mirror of
https://github.com/dtwardow/homebridge-multi-tap-switch.git
synced 2026-11-02 05:18:30 +00:00
First test
This commit is contained in:
1 parent
d5961e4464
commit
0637aeb2f3
7 files changed
+128
-89
No files matched your search
@@ -1,53 +1,81 @@
|
||||
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
||||
|
||||
import { ExampleHomebridgePlatform } from './platform';
|
||||
import { MultiTapSwitchPlatform } from './platform';
|
||||
import {TIMEOUT} from 'dns';
|
||||
|
||||
/**
|
||||
* Platform Accessory
|
||||
* An instance of this class is created for each accessory your platform registers
|
||||
* Each accessory may expose multiple services of different service types.
|
||||
*/
|
||||
export class ExamplePlatformAccessory {
|
||||
private service: Service;
|
||||
export class DeviceAccessory {
|
||||
private serviceIn: Service;
|
||||
private serviceOut: Service;
|
||||
|
||||
/**
|
||||
* These are just used to create a working example
|
||||
* You should implement your own code to track the state of your accessory
|
||||
*/
|
||||
private exampleStates = {
|
||||
On: false,
|
||||
Brightness: 100,
|
||||
private readonly singleButtonEvents = {
|
||||
minValue: this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
|
||||
maxValue: this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
|
||||
validValues: [
|
||||
this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
|
||||
],
|
||||
};
|
||||
|
||||
private currentState = {
|
||||
"On": Boolean,
|
||||
"NumScenes": Number,
|
||||
"KeepSeconds": Number,
|
||||
"Timeout": TIMEOUT
|
||||
};
|
||||
|
||||
private readonly triggerButtons: Service[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly platform: ExampleHomebridgePlatform,
|
||||
private readonly platform: MultiTapSwitchPlatform,
|
||||
private readonly accessory: PlatformAccessory,
|
||||
private readonly numOfButtons: number,
|
||||
) {
|
||||
|
||||
// set accessory information
|
||||
this.accessory.getService(this.platform.Service.AccessoryInformation)!
|
||||
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Default-Manufacturer')
|
||||
.setCharacteristic(this.platform.Characteristic.Model, 'Default-Model')
|
||||
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'Default-Serial');
|
||||
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'TippyTapper Solutions')
|
||||
.setCharacteristic(this.platform.Characteristic.Model, 'SceneButton-000')
|
||||
.setCharacteristic(this.platform.Characteristic.SerialNumber, 'DE:AD:BE:EF:00:00');
|
||||
|
||||
// get the LightBulb service if it exists, otherwise create a new LightBulb service
|
||||
// you can create multiple services for each accessory
|
||||
this.service = this.accessory.getService(this.platform.Service.Lightbulb) || this.accessory.addService(this.platform.Service.Lightbulb);
|
||||
|
||||
this.serviceIn = this.accessory.getService(this.platform.Service.Switch)
|
||||
|| this.accessory.addService(this.platform.Service.Switch);
|
||||
|
||||
this.serviceOut = this.accessory.getService(this.platform.Service.ServiceLabel)
|
||||
|| this.accessory.addService(this.platform.Service.ServiceLabel);
|
||||
|
||||
this.serviceOut.setCharacteristic(this.platform.Characteristic.ServiceLabelNamespace, '')
|
||||
this.serviceOut.setCharacteristic(this.platform.Characteristic.ServiceLabelIndex, 1);
|
||||
|
||||
// Create configured number of scene buttons
|
||||
for (let i = 1; i <= numOfButtons; i++) {
|
||||
const newButton = this.accessory.addService(this.platform.Service.StatelessProgrammableSwitch);
|
||||
this.serviceOut.addLinkedService(newButton);
|
||||
this.triggerButtons.push(newButton);
|
||||
|
||||
newButton.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent)
|
||||
.setProps(this.singleButtonEvents);
|
||||
newButton.setCharacteristic(this.platform.Characteristic.ServiceLabelIndex, i);
|
||||
}
|
||||
|
||||
// set the service name, this is what is displayed as the default name on the Home app
|
||||
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
|
||||
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.exampleDisplayName);
|
||||
this.serviceOut.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.exampleDisplayName);
|
||||
|
||||
// each service must implement at-minimum the "required characteristics" for the given service type
|
||||
// see https://developers.homebridge.io/#/service/Lightbulb
|
||||
|
||||
// register handlers for the On/Off Characteristic
|
||||
this.service.getCharacteristic(this.platform.Characteristic.On)
|
||||
this.serviceOut.getCharacteristic(this.platform.Characteristic.On)
|
||||
.onSet(this.setOn.bind(this)) // SET - bind to the `setOn` method below
|
||||
.onGet(this.getOn.bind(this)); // GET - bind to the `getOn` method below
|
||||
|
||||
// register handlers for the Brightness Characteristic
|
||||
this.service.getCharacteristic(this.platform.Characteristic.Brightness)
|
||||
this.serviceOut.getCharacteristic(this.platform.Characteristic.Brightness)
|
||||
.onSet(this.setBrightness.bind(this)); // SET - bind to the 'setBrightness` method below
|
||||
|
||||
/**
|
||||
@@ -62,11 +90,11 @@ export class ExamplePlatformAccessory {
|
||||
*/
|
||||
|
||||
// Example: add two "motion sensor" services to the accessory
|
||||
const motionSensorOneService = this.accessory.getService('Motion Sensor One Name') ||
|
||||
this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor One Name', 'YourUniqueIdentifier-1');
|
||||
const inputService = this.accessory.getService(this.accessory.displayName + ' Trigger') ||
|
||||
this.accessory.addService(this.platform.Service.MotionSensor, this.accessory.displayName + ' Trigger', 'YourUniqueIdentifier-1');
|
||||
|
||||
const motionSensorTwoService = this.accessory.getService('Motion Sensor Two Name') ||
|
||||
this.accessory.addService(this.platform.Service.MotionSensor, 'Motion Sensor Two Name', 'YourUniqueIdentifier-2');
|
||||
const outputService = this.accessory.getService(this.accessory.displayName + ' SceneSwitch') ||
|
||||
this.accessory.addService(this.platform.Service.MotionSensor, this.accessory.displayName + ' SceneSwitch', 'YourUniqueIdentifier-2');
|
||||
|
||||
/**
|
||||
* Updating characteristics values asynchronously.
|
||||
@@ -83,12 +111,13 @@ export class ExamplePlatformAccessory {
|
||||
motionDetected = !motionDetected;
|
||||
|
||||
// push the new value to HomeKit
|
||||
motionSensorOneService.updateCharacteristic(this.platform.Characteristic.MotionDetected, motionDetected);
|
||||
motionSensorTwoService.updateCharacteristic(this.platform.Characteristic.MotionDetected, !motionDetected);
|
||||
inputService.updateCharacteristic(this.platform.Characteristic.MotionDetected, motionDetected);
|
||||
outputService.updateCharacteristic(this.platform.Characteristic.MotionDetected, !motionDetected);
|
||||
|
||||
this.platform.log.debug('Triggering motionSensorOneService:', motionDetected);
|
||||
this.platform.log.debug('Triggering motionSensorTwoService:', !motionDetected);
|
||||
}, 10000);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,8 +126,12 @@ export class ExamplePlatformAccessory {
|
||||
*/
|
||||
async setOn(value: CharacteristicValue) {
|
||||
// implement your own code to turn your device on/off
|
||||
this.exampleStates.On = value as boolean;
|
||||
this.currentState.On = value as boolean;
|
||||
|
||||
this.currentState.Timeout = setTimeout(() => {
|
||||
this.currentState.On = false;
|
||||
this.setOn(false);
|
||||
}, 1000 * 10);
|
||||
this.platform.log.debug('Set Characteristic On ->', value);
|
||||
}
|
||||
|
||||
@@ -117,7 +150,7 @@ export class ExamplePlatformAccessory {
|
||||
*/
|
||||
async getOn(): Promise<CharacteristicValue> {
|
||||
// implement your own code to check if the device is on
|
||||
const isOn = this.exampleStates.On;
|
||||
const isOn = this.currentState.On;
|
||||
|
||||
this.platform.log.debug('Get Characteristic On ->', isOn);
|
||||
|
||||
@@ -133,9 +166,9 @@ export class ExamplePlatformAccessory {
|
||||
*/
|
||||
async setBrightness(value: CharacteristicValue) {
|
||||
// implement your own code to set the brightness
|
||||
this.exampleStates.Brightness = value as number;
|
||||
//this.currentState.KeepSeconds = value as number;
|
||||
|
||||
this.platform.log.debug('Set Characteristic Brightness -> ', value);
|
||||
this.platform.log.debug('Set Characteristic KeepSeconds -> ', value);
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { API } from 'homebridge';
|
||||
|
||||
import { PLATFORM_NAME } from './settings';
|
||||
import { ExampleHomebridgePlatform } from './platform';
|
||||
import { MultiTapSwitchPlatform } from './platform';
|
||||
|
||||
/**
|
||||
* This method registers the platform with Homebridge
|
||||
*/
|
||||
export = (api: API) => {
|
||||
api.registerPlatform(PLATFORM_NAME, ExampleHomebridgePlatform);
|
||||
api.registerPlatform(PLATFORM_NAME, MultiTapSwitchPlatform);
|
||||
};
|
||||
+43
-49
@@ -1,14 +1,14 @@
|
||||
import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service, Characteristic } from 'homebridge';
|
||||
|
||||
import { PLATFORM_NAME, PLUGIN_NAME } from './settings';
|
||||
import { ExamplePlatformAccessory } from './platformAccessory';
|
||||
import { DeviceAccessory } from './accessory';
|
||||
|
||||
/**
|
||||
* HomebridgePlatform
|
||||
* This class is the main constructor for your plugin, this is where you should
|
||||
* parse the user config and discover/register accessories with Homebridge.
|
||||
*/
|
||||
export class ExampleHomebridgePlatform implements DynamicPlatformPlugin {
|
||||
export class MultiTapSwitchPlatform implements DynamicPlatformPlugin {
|
||||
public readonly Service: typeof Service = this.api.hap.Service;
|
||||
public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic;
|
||||
|
||||
@@ -44,6 +44,10 @@ export class ExampleHomebridgePlatform implements DynamicPlatformPlugin {
|
||||
this.accessories.push(accessory);
|
||||
}
|
||||
|
||||
defineUuid(name: string | undefined, serial: string): string {
|
||||
return this.api.hap.uuid.generate(name + '_' + serial);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an example method showing how to register discovered accessories.
|
||||
* Accessories must only be registered once, previously created accessories
|
||||
@@ -54,63 +58,53 @@ export class ExampleHomebridgePlatform implements DynamicPlatformPlugin {
|
||||
// EXAMPLE ONLY
|
||||
// A real plugin you would discover accessories from the local network, cloud services
|
||||
// or a user-defined array in the platform config.
|
||||
const exampleDevices = [
|
||||
{
|
||||
exampleUniqueId: 'ABCD',
|
||||
exampleDisplayName: 'Bedroom',
|
||||
},
|
||||
{
|
||||
exampleUniqueId: 'EFGH',
|
||||
exampleDisplayName: 'Kitchen',
|
||||
},
|
||||
];
|
||||
|
||||
// loop over the discovered devices and register each one if it has not already been registered
|
||||
for (const device of exampleDevices) {
|
||||
// generate a unique id for the accessory this should be generated from
|
||||
// something globally unique, but constant, for example, the device serial
|
||||
// number or MAC address
|
||||
//const uuid = this.api.hap.uuid.generate(device.exampleUniqueId);
|
||||
const uuid = this.defineUuid(this.config.name, "0");
|
||||
|
||||
// generate a unique id for the accessory this should be generated from
|
||||
// something globally unique, but constant, for example, the device serial
|
||||
// number or MAC address
|
||||
const uuid = this.api.hap.uuid.generate(device.exampleUniqueId);
|
||||
// see if an accessory with the same uuid has already been registered and restored from
|
||||
// the cached devices we stored in the `configureAccessory` method above
|
||||
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
|
||||
|
||||
// see if an accessory with the same uuid has already been registered and restored from
|
||||
// the cached devices we stored in the `configureAccessory` method above
|
||||
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
|
||||
if (existingAccessory) {
|
||||
// the accessory already exists
|
||||
this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
|
||||
|
||||
if (existingAccessory) {
|
||||
// the accessory already exists
|
||||
this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
|
||||
// if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
|
||||
// existingAccessory.context.device = device;
|
||||
// this.api.updatePlatformAccessories([existingAccessory]);
|
||||
|
||||
// if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
|
||||
// existingAccessory.context.device = device;
|
||||
// this.api.updatePlatformAccessories([existingAccessory]);
|
||||
// create the accessory handler for the restored accessory
|
||||
// this is imported from `accessoryInput.ts`
|
||||
new DeviceAccessory(this, existingAccessory, this.config.numScenes);
|
||||
|
||||
// create the accessory handler for the restored accessory
|
||||
// this is imported from `platformAccessory.ts`
|
||||
new ExamplePlatformAccessory(this, existingAccessory);
|
||||
// it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.:
|
||||
// remove platform accessories when no longer present
|
||||
// this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]);
|
||||
// this.log.info('Removing existing accessory from cache:', existingAccessory.displayName);
|
||||
} else {
|
||||
// the accessory does not yet exist, so we need to create it
|
||||
this.log.info('Adding INPUT:', this.config.name);
|
||||
|
||||
// it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.:
|
||||
// remove platform accessories when no longer present
|
||||
// this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]);
|
||||
// this.log.info('Removing existing accessory from cache:', existingAccessory.displayName);
|
||||
} else {
|
||||
// the accessory does not yet exist, so we need to create it
|
||||
this.log.info('Adding new accessory:', device.exampleDisplayName);
|
||||
// create a new accessory
|
||||
const accessory = new this.api.platformAccessory(<string>this.config.name, uuid);
|
||||
|
||||
// create a new accessory
|
||||
const accessory = new this.api.platformAccessory(device.exampleDisplayName, uuid);
|
||||
// store a copy of the device object in the `accessory.context`
|
||||
// the `context` property can be used to store any data about the accessory you may need
|
||||
accessory.context.device = {
|
||||
"numScenes": this.config.numScenes,
|
||||
"keepSeconds": this.config.keepSeconds
|
||||
};
|
||||
|
||||
// store a copy of the device object in the `accessory.context`
|
||||
// the `context` property can be used to store any data about the accessory you may need
|
||||
accessory.context.device = device;
|
||||
// create the accessory handler for the newly create accessory
|
||||
// this is imported from `accessoryInput.ts`
|
||||
new DeviceAccessory(this, accessory, this.config.numScenes);
|
||||
|
||||
// create the accessory handler for the newly create accessory
|
||||
// this is imported from `platformAccessory.ts`
|
||||
new ExamplePlatformAccessory(this, accessory);
|
||||
|
||||
// link the accessory to your platform
|
||||
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
||||
}
|
||||
// link the accessory to your platform
|
||||
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* This is the name of the platform that users will use to register the plugin in the Homebridge config.json
|
||||
*/
|
||||
export const PLATFORM_NAME = 'ExampleHomebridgePlugin';
|
||||
export const PLATFORM_NAME = 'MultiTapSwitch';
|
||||
|
||||
/**
|
||||
* This must match the name of your plugin as defined the package.json
|
||||
*/
|
||||
export const PLUGIN_NAME = 'homebridge-plugin-name';
|
||||
export const PLUGIN_NAME = 'homebridge-multitap-switch';
|
||||
Reference in new issue
Block a user