Doorbell refinement, working on README
This commit is contained in:
parent
a8c5b1b9e6
commit
b95352b05b
288
README.md
288
README.md
@ -1,48 +1,41 @@
|
||||
# homebridge-smarthomeng
|
||||
Homebridge plugin for SmartHomeNG. This is work in progress and not all devices are supported yet.
|
||||
|
||||
**Version v2 is a complete rewrite from scratch and a breaking update.**
|
||||
You need to adapt your `config.json` !
|
||||
|
||||
## Currently supported
|
||||
This plugin currently supports the following services (and characteristics):
|
||||
|
||||
* LightBulb (on/off, brightness, hue, saturation)
|
||||
* Fan (on/off)
|
||||
* Temperature sensor (current temperature)
|
||||
* Thermostat (current- / target temperature)
|
||||
* Window (current- / target position)
|
||||
* Window Covering (current- / target position)
|
||||
* Motion sensor (motion detected)
|
||||
* Occupancy sensor (motion detected)
|
||||
* LightBulb (on/off, brightness, hue, saturation, r, g, b, w)
|
||||
* Fan (active)
|
||||
* TemperatureSensor (current temperature)
|
||||
* Thermostat (current- / target temperature, currentheatingcoolingstate)
|
||||
* MotionSensor (motion detected)
|
||||
* OccupancySensor (presence detected)
|
||||
* ContactSensor (contact state)
|
||||
* Switch (on/off)
|
||||
* Outlet (on/off)
|
||||
* WindowCovering (CurrentPosition, TargetPosition).
|
||||
|
||||
Other accessories are being worked on and will be added as soon as ready.
|
||||
|
||||
## Requirements
|
||||
* [SmartHomeNG](https://github.com/smarthomeNG/smarthome)
|
||||
* [homebridge](https://www.npmjs.com/package/homebridge)
|
||||
|
||||
## Installation
|
||||
### Install nodejs >= 0.12.
|
||||
You have to find out the right way for your OS.
|
||||
|
||||
|
||||
Debian Jessie:
|
||||
|
||||
curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
Alpine Linux: (--no-cache example is for building a docker image)
|
||||
|
||||
apk --no-cache add nodejs
|
||||
### Install nodejs >=14.18.1
|
||||
See [NodeJS](https://nodejs.org/en/) website for details depending on your OS.
|
||||
|
||||
### Install libavahi-compat-libdnssd-dev lib
|
||||
Debian Jessie:
|
||||
For me i needed these libraries to be installed for my homebridge to work. See their [Homepage](https://homebridge.io) for installation instructions.
|
||||
Below is what i did on my Debian Bullseye installation:
|
||||
|
||||
sudo apt-get install libavahi-compat-libdnssd-dev
|
||||
|
||||
Alpine Linux: (--no-cache example is for building a docker image)
|
||||
sudo apt install libavahi-compat-libdnssd-dev
|
||||
|
||||
apk --no-cache add dbus nodejs avahi avahi-compat-libdns_sd avahi-dev
|
||||
|
||||
### Install homebridge from NPM repository
|
||||
### Install homebridge >=1.3.5 from NPM repository
|
||||
|
||||
npm install -g homebridge --unsafe-perm
|
||||
|
||||
@ -53,104 +46,183 @@ Alpine Linux: (--no-cache example is for building a docker image)
|
||||
|
||||
|
||||
## Configuration
|
||||
You have to create a config.json in .homebridge directory. You'll find that directory in your home folder. This is an example config file which just uses this plugin and some example SmartHomeNG items.
|
||||
If you already have a working homebridge installation just add the platform section into your existing config. If you are a new homebridge user you have to create a `config.json` file in the `.homebridge` directory. You'll find that directory in your home folder.
|
||||
|
||||
### Common characteristics
|
||||
The following characteristics are valid for all accessories.
|
||||
|
||||
Mandatory:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "OccupancySensor",
|
||||
"name": "Presence kitchen",
|
||||
}
|
||||
```
|
||||
|
||||
Optional:
|
||||
```json
|
||||
{
|
||||
"manufacturer": "Preussen",
|
||||
"model": "Motion 360 KNX",
|
||||
}
|
||||
```
|
||||
### Doorbell
|
||||
TODO
|
||||
|
||||
### Fan
|
||||
TODO
|
||||
|
||||
### LightBulb
|
||||
TODO
|
||||
|
||||
### Occupancy sensor
|
||||
TODO
|
||||
|
||||
### Motion sensor
|
||||
TODO
|
||||
|
||||
### Contact sensor
|
||||
TODO
|
||||
|
||||
### Switch
|
||||
TODO
|
||||
|
||||
### Outlet
|
||||
TODO
|
||||
|
||||
### Temperature sensor
|
||||
TODO
|
||||
|
||||
### Thermostat
|
||||
TODO
|
||||
|
||||
### WindowCovering
|
||||
In addition to the common characteristics the following are available.
|
||||
|
||||
Mandatory:
|
||||
```json
|
||||
{
|
||||
"CurrentPosition": "EG.Buero.Rolladen.Position",
|
||||
"TargetPosition": "EG.Buero.Rolladen.ZielPosition",
|
||||
}
|
||||
```
|
||||
The current moving state and direction is automatically derived from the difference between the current and target position.
|
||||
|
||||
Optional:
|
||||
```json
|
||||
{
|
||||
"CurrentPositionMin": 0,
|
||||
"CurrentPositionMax": 255,
|
||||
"CurrentPositionInverted": true,
|
||||
"TargetPositionMin": 0,
|
||||
"TargetPositionMax": 255,
|
||||
"TargetPositionInverted": true
|
||||
}
|
||||
```
|
||||
HomeKit works with values between 0 and 100 where 0 is completely closed and 100 is open.
|
||||
My KNX installation, as example, needs values between 0 and 255 where 255 is completely closed and 0 is open.
|
||||
The above optional parameters allow you to specify the neede range for your device. If needed the values can be inverted at the same time. The plugin then transposes the values in both directions.
|
||||
|
||||
### Example configuration file
|
||||
This is an example config file which just uses this plugin and some example SmartHomeNG items.
|
||||
|
||||
```json
|
||||
{
|
||||
"bridge": {
|
||||
"name": "HBDEV",
|
||||
"name": "SmartHomeNG",
|
||||
"username": "CC:22:3D:E3:DE:37",
|
||||
"port": 51826,
|
||||
"pin": "031-45-154"
|
||||
"port": 51138,
|
||||
"pin": "655-59-9284"
|
||||
},
|
||||
|
||||
"platforms": [
|
||||
{
|
||||
"platform": "SmartHomeNG",
|
||||
|
||||
"name": "SmartHomeNG",
|
||||
"host": "srvsmarthome.ha.swa.lu",
|
||||
"host": "smarthome.iot.wagener.family",
|
||||
"accessories": [
|
||||
{
|
||||
"name": "Temperatur Stube",
|
||||
"type": "TemperatureSensor",
|
||||
"currenttemperature": "EG.Stube.Temperatur"
|
||||
},
|
||||
{
|
||||
"name": "Heizung Bad",
|
||||
"type": "Thermostat",
|
||||
"currenttemperature": "OG.Bad.Temperatur",
|
||||
"targettemperature": "OG.Bad.Temperatur.Sollwert",
|
||||
"targettemperatureminimum": 18,
|
||||
"targettemperaturemaximum": 25
|
||||
},
|
||||
{
|
||||
"name": "Ventilator Bad",
|
||||
"type": "Fan",
|
||||
"onoff": "OG.Bad.Ventilator"
|
||||
},
|
||||
{
|
||||
"name": "Lüftung",
|
||||
"type": "Fan",
|
||||
"onoff": "EG.Lüftung"
|
||||
"rotationSpeed": "EG.LüftungSpeed"
|
||||
},
|
||||
{
|
||||
"name": "Schalter",
|
||||
"type": "Switch",
|
||||
"onoff": "EG.Esszimmer.Schalter"
|
||||
},
|
||||
{
|
||||
"name": "Schaltsteckdose",
|
||||
"type": "Outlet",
|
||||
"onoff": "EG.Esszimmer.Steckdose"
|
||||
"name": "Steckdose Esszimmer",
|
||||
"On": "EG.Esszimmer.Steckdose"
|
||||
},
|
||||
{
|
||||
"name": "Bürolicht",
|
||||
"type": "Lightbulb",
|
||||
"onoff": "EG.Buero.Licht"
|
||||
},
|
||||
{
|
||||
"name": "Stubenlicht",
|
||||
"type": "Lightbulb",
|
||||
"onoff": "EG.Stube.Licht"
|
||||
},
|
||||
{
|
||||
"name": "Schlafzimmerlicht",
|
||||
"type": "Lightbulb",
|
||||
"onoff": "OG.SZSS.Licht",
|
||||
"brightness": "OG.SZSS.Licht.dimmen"
|
||||
},
|
||||
{
|
||||
"name": "Rolladen Büro",
|
||||
"type": "WindowCovering",
|
||||
"updown": "EG.Buero.Rolladen.AufAb",
|
||||
"currentposition": "EG.Buero.Rolladen.Position",
|
||||
"targetposition": "EG.Buero.Rolladen.Position",
|
||||
"inverted": true
|
||||
},
|
||||
{
|
||||
"name": "Bewegungsmelder Küche",
|
||||
"type": "MotionSensor",
|
||||
"motionstate": "EG.Kueche.Praesenz"
|
||||
},
|
||||
{
|
||||
"name": "Terassentür Küche",
|
||||
"type": "ContactSensor",
|
||||
"contactsensorstate": "EG.Kueche.Tuer",
|
||||
"inverted": true
|
||||
},
|
||||
{
|
||||
"name": "Fenster Esszimmer",
|
||||
"type": "ContactSensor",
|
||||
"contactsensorstate": "EG.Esszimmer.Fenster",
|
||||
"inverted": true
|
||||
},
|
||||
{
|
||||
"name": "Präsenzsmelder Esszimmer",
|
||||
"type": "OccupancySensor",
|
||||
"motiondetected": "EG.Esszimmer.Praesenz"
|
||||
"name": "Präsenz Büro",
|
||||
"manufacturer": "Preussen",
|
||||
"model": "Motion 360 KNX",
|
||||
"OccupancyDetected": "EG.Buero.Praesenz"
|
||||
},
|
||||
{
|
||||
"type": "MotionSensor",
|
||||
"name": "Bewegung Flur",
|
||||
"manufacturer": "Preussen",
|
||||
"model": "Motion 360 KNX",
|
||||
"MotionDetected": "EG.Flur.Praesenz"
|
||||
},
|
||||
{
|
||||
"type": "ContactSensor",
|
||||
"name": "Fenster Büro",
|
||||
"ContactState": "EG.Buero.Fenster"
|
||||
},
|
||||
{
|
||||
"type": "Doorbell",
|
||||
"name": "Haustür",
|
||||
"SinglePress": "Technik.Asterisk.Klingel"
|
||||
},
|
||||
{
|
||||
"type": "Lightbulb",
|
||||
"name": "Licht Büro",
|
||||
"On": "EG.Buero.Deckenspots",
|
||||
"Brightness": "EG.Buero.Deckenspots.dimmen",
|
||||
"BrightnessMin": 0,
|
||||
"BrightnessMax": 255
|
||||
}
|
||||
{
|
||||
"type": "Lightbulb",
|
||||
"name": "RGB Leiste Stube",
|
||||
"On": "EG.Stube.Ledleiste",
|
||||
"Brightness": "EG.Stube.Ledleiste.dimmen",
|
||||
"BrightnessMin": 0,
|
||||
"BrightnessMax": 255,
|
||||
"R": "EG.Stube.Ledleiste.R.dimmen",
|
||||
"RMin": 0,
|
||||
"RMax": 255,
|
||||
"G": "EG.Stube.Ledleiste.G.dimmen",
|
||||
"GMin": 0,
|
||||
"GMax": 255,
|
||||
"B": "EG.Stube.Ledleiste.B.dimmen",
|
||||
"BMin": 0,
|
||||
"BMax": 255,
|
||||
"W": "EG.Stube.Ledleiste.W.dimmen",
|
||||
"WMin": 0,
|
||||
"WMax": 255
|
||||
},
|
||||
{
|
||||
"type": "Fan",
|
||||
"name": "Ventilator Bad",
|
||||
"Active": "OG.Bad.Ventilator"
|
||||
},
|
||||
{
|
||||
"type": "Thermostat",
|
||||
"name": "Temperatur Büro",
|
||||
"CurrentTemperature": "EG.Buero.Temperatur",
|
||||
"TargetTemperature": "EG.Buero.Temperatur.Sollwert",
|
||||
"CurrentHeatingCoolingState": "EG.Buero.Temperatur.Modus"
|
||||
},
|
||||
{
|
||||
"type": "WindowCovering",
|
||||
"name": "Shutters office",
|
||||
"CurrentPosition": "EG.Buero.Rolladen.Position",
|
||||
"CurrentPositionMin": 0,
|
||||
"CurrentPositionMax": 255,
|
||||
"CurrentPositionInverted": true,
|
||||
"TargetPosition": "EG.Buero.Rolladen.ZielPosition",
|
||||
"TargetPositionMin": 0,
|
||||
"TargetPositionMax": 255,
|
||||
"TargetPositionInverted": true
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -158,3 +230,5 @@ You have to create a config.json in .homebridge directory. You'll find that dire
|
||||
"description": "This is my development config file."
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
11
package-lock.json
generated
11
package-lock.json
generated
@ -9,7 +9,6 @@
|
||||
"version": "2.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"ws": "^8.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -2336,11 +2335,6 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
@ -5407,11 +5401,6 @@
|
||||
"type-check": "~0.4.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"homebridge-plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"ws": "^8.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
66
src/Accessories/Doorbell.ts
Normal file
66
src/Accessories/Doorbell.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import {
|
||||
AccessoryPlugin,
|
||||
CharacteristicValue,
|
||||
Service,
|
||||
Nullable,
|
||||
} from 'homebridge';
|
||||
|
||||
import { SmartHomeNGPlatform } from '../platform';
|
||||
|
||||
export class Doorbell implements AccessoryPlugin {
|
||||
private readonly deviceService: Service;
|
||||
private readonly informationService: Service;
|
||||
|
||||
public name: string;
|
||||
//private event = this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS;
|
||||
|
||||
constructor(private readonly platform: SmartHomeNGPlatform, private readonly accessory) {
|
||||
this.name = accessory.name;
|
||||
this.deviceService = new this.platform.Service.Doorbell(accessory.name);
|
||||
|
||||
// create handlers for required characteristics
|
||||
this.deviceService.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent)
|
||||
.onGet(this.handleProgrammableSwitchEventGet.bind(this));
|
||||
|
||||
this.informationService =
|
||||
new this.platform.Service.AccessoryInformation()
|
||||
.setCharacteristic(this.platform.Characteristic.Manufacturer, accessory.manufacturer)
|
||||
.setCharacteristic(this.platform.Characteristic.Model, accessory.model)
|
||||
.setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.singlepress);
|
||||
|
||||
this.platform.shng.addMonitor(accessory.singlepress, this.shngSinglePressCallback.bind(this));
|
||||
this.platform.log.info('Doorbell', accessory.name, 'created!');
|
||||
}
|
||||
|
||||
identify(): void {
|
||||
this.platform.log.info('Identify!');
|
||||
}
|
||||
|
||||
getServices(): Service[] {
|
||||
return [this.informationService, this.deviceService];
|
||||
}
|
||||
|
||||
handleProgrammableSwitchEventGet(): Nullable<CharacteristicValue> {
|
||||
this.platform.log.error(
|
||||
'handleProgrammableSwitchEventGet:',
|
||||
this.accessory.name, '=',
|
||||
0,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
shngSinglePressCallback(value: unknown): void {
|
||||
this.platform.log.debug('shngSinglePressCallback:', this.accessory.name, '=', value, '(' + typeof value + ')');
|
||||
if (typeof value === 'boolean') {
|
||||
if (value) {
|
||||
this.deviceService.updateCharacteristic(
|
||||
this.platform.Characteristic.ProgrammableSwitchEvent,
|
||||
this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.platform.log.warn('Unknown type', typeof value, 'received for', this.accessory.name + ':', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
src/Accessories/VideoDoorbell.ts
Normal file
66
src/Accessories/VideoDoorbell.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import {
|
||||
AccessoryPlugin,
|
||||
CharacteristicValue,
|
||||
Service,
|
||||
Nullable,
|
||||
} from 'homebridge';
|
||||
|
||||
import { SmartHomeNGPlatform } from '../platform';
|
||||
|
||||
export class Doorbell implements AccessoryPlugin {
|
||||
private readonly deviceService: Service;
|
||||
private readonly informationService: Service;
|
||||
|
||||
public name: string;
|
||||
//private event = this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS;
|
||||
|
||||
constructor(private readonly platform: SmartHomeNGPlatform, private readonly accessory) {
|
||||
this.name = accessory.name;
|
||||
this.deviceService = new this.platform.Service.Doorbell(accessory.name);
|
||||
|
||||
// create handlers for required characteristics
|
||||
this.deviceService.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent)
|
||||
.onGet(this.handleProgrammableSwitchEventGet.bind(this));
|
||||
|
||||
this.informationService =
|
||||
new this.platform.Service.AccessoryInformation()
|
||||
.setCharacteristic(this.platform.Characteristic.Manufacturer, accessory.manufacturer)
|
||||
.setCharacteristic(this.platform.Characteristic.Model, accessory.model)
|
||||
.setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.singlepress);
|
||||
|
||||
this.platform.shng.addMonitor(accessory.contactstate, this.shngCallback.bind(this));
|
||||
this.platform.log.info('ContactSensor', accessory.name, 'created!');
|
||||
}
|
||||
|
||||
identify(): void {
|
||||
this.platform.log.info('Identify!');
|
||||
}
|
||||
|
||||
getServices(): Service[] {
|
||||
return [this.informationService, this.deviceService];
|
||||
}
|
||||
|
||||
handleProgrammableSwitchEventGet(): Nullable<CharacteristicValue> {
|
||||
this.platform.log.debug(
|
||||
'handleProgrammableSwitchEventGet:',
|
||||
this.accessory.name, '=',
|
||||
0,
|
||||
);
|
||||
return this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS;
|
||||
}
|
||||
|
||||
shngCallback(value: unknown): void {
|
||||
this.platform.log.debug('shngCallback:', this.accessory.name, '=', value, '(' + typeof value + ')');
|
||||
if (typeof value === 'boolean') {
|
||||
if (value) {
|
||||
this.deviceService.updateCharacteristic(
|
||||
this.platform.Characteristic.ProgrammableSwitchEvent,
|
||||
this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.platform.log.warn('Unknown type', typeof value, 'received for', this.accessory.name + ':', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import { TemperatureSensor } from './Accessories/TemperatureSensor';
|
||||
import { Thermostat } from './Accessories/Thermostat';
|
||||
import { WindowCovering } from './Accessories/WindowCovering';
|
||||
import { ContactSensor } from './Accessories/ContactSensor';
|
||||
import { Doorbell } from './Accessories/DoorBell';
|
||||
|
||||
function uncapitalizeKeys(obj): Record<string, unknown> {
|
||||
function isObject(o: unknown): boolean {
|
||||
@ -95,6 +96,11 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
|
||||
devices.push(new ContactSensor(this, accessory));
|
||||
break;
|
||||
|
||||
// Doorbell
|
||||
case 'doorbell':
|
||||
devices.push(new Doorbell(this, accessory));
|
||||
break;
|
||||
|
||||
// Switch
|
||||
case 'switch':
|
||||
devices.push(new Switch(this, accessory));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user