13 Commits
Author SHA1 Message Date
Serge Wagener ae63f6cdee Merge pull request #13 from chester4444/master
Added GarageDoor and HumiditySensor
2022-03-08 16:27:23 +01:00
Serge Wagener bbc42dfb7e Added config section link 2022-03-08 16:24:52 +01:00
Chester c6f596e9e5 Merge branch 'master' of https://github.com/chester4444/homebridge-smarthomeng 2022-03-08 15:15:19 +01:00
Chester 3561e0c3d6 added humidity sensor 2022-03-08 15:13:53 +01:00
Chester 447e0a68ef added GarageDoor and HumiditySensor 2022-03-08 14:18:35 +01:00
Chester 6f373379ae Adding humidity sensor 2022-03-07 21:12:55 +01:00
Chester 6b46c9cdb8 Added garage door description 2022-03-07 17:11:36 +01:00
Chester 77df0609ca garage door added 2022-03-07 16:44:43 +01:00
Chester abe95f516f added garagedoor 2022-03-07 16:30:32 +01:00
Serge Wagener a3e7b85f17 Added badges to README 2022-02-20 10:45:25 +01:00
Serge Wagener ba2505853c Preparing for v2.0.4 release 2022-02-19 13:58:11 +01:00
Serge Wagener e0611aed2c Sort accessories in README alphabetically 2022-02-19 13:39:05 +01:00
Serge Wagener 9a1709591f Fixed package.json 2022-02-19 13:36:38 +01:00
7 changed files with 336 additions and 65 deletions

No files matched your search

+121 -56
View File
@@ -1,7 +1,13 @@
# homebridge-smarthomeng # homebridge-smarthomeng
[![npm](https://badgen.net/npm/v/homebridge-smarthomeng)](https://www.npmjs.com/package/homebridge-smarthomeng)
[![npm](https://badgen.net/badge/homebridge/>=1.3.5/green)](https://www.npmjs.com/package/homebridge-smarthomeng)
[![npm](https://badgen.net/npm/node/homebridge-smarthomeng)](https://www.npmjs.com/package/homebridge-smarthomeng)
[![npm](https://badgen.net/npm/dt/homebridge-smarthomeng)](https://www.npmjs.com/package/homebridge-smarthomeng)
[![npm](https://badgen.net/npm/dm/homebridge-smarthomeng)](https://www.npmjs.com/package/homebridge-smarthomeng)
**Version v2 is a complete rewrite from scratch and a breaking update.** **Version v2 is a complete rewrite from scratch and a breaking update.**
You need to adapt your `config.json` ! You need to adapt your [`config.json`](#example-configuration-file) !
## Currently supported accessories ## Currently supported accessories
This plugin currently supports the following services (and characteristics): This plugin currently supports the following services (and characteristics):
@@ -11,6 +17,8 @@ This plugin currently supports the following services (and characteristics):
| [ContactSensor](#contact-sensor) | Simple contact sensor, for example for windows | | [ContactSensor](#contact-sensor) | Simple contact sensor, for example for windows |
| [Doorbell](#doorbell) | Doorbell, sends message to devices on ring | | [Doorbell](#doorbell) | Doorbell, sends message to devices on ring |
| [Fan](#fan) | Simple on/off fan, may be extended in future | | [Fan](#fan) | Simple on/off fan, may be extended in future |
| [GarageDoor](#garage-door) | Garage door opener |
| [HumiditySensor](#humidity-sensor) | Humidity sensor |
| [Lightbulb](#lightbulb) | Everything, from simple light to dimmable, RGB and RGBW | | [Lightbulb](#lightbulb) | Everything, from simple light to dimmable, RGB and RGBW |
| [MotionSensor](#motion-sensor) | Detects and reports motion | | [MotionSensor](#motion-sensor) | Detects and reports motion |
| [OccupancySensor](#occupancy-sensor) | Detects presence in a room | | [OccupancySensor](#occupancy-sensor) | Detects presence in a room |
@@ -92,6 +100,25 @@ The following characteristics are valid for all accessories:
"model": "Motion 360 KNX", "model": "Motion 360 KNX",
} }
``` ```
### Contact sensor
This sensor shows the open / closed state of a contact (door, window, generic ...).
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:-------------|:----------------|:----------|:---------------------------------|
| ContactState | \<item> | Yes | SHNG item to monitor for contact |
#### Example:
```json
{
"type": "ContactSensor",
"name": "Window kitchen",
"ContactState": "EG.Kueche.Fenster"
}
```
### Doorbell ### Doorbell
A doorbell is an accessory that simply sends a message to all devices enrolled in the home that someone rang the doorbell. A doorbell is an accessory that simply sends a message to all devices enrolled in the home that someone rang the doorbell.
HomeKit displays a message that "This accessory is not currently supported by the Home app.". HomeKit displays a message that "This accessory is not currently supported by the Home app.".
@@ -128,6 +155,60 @@ For now this accessory only supports turning the fan on and off. Further improve
} }
``` ```
### Garage Door
This accessory is used for opening/closing garage doors or any other automatic gate.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Default | Description |
|:---------------------------|:----------------|:----------|:--------|:------------------------------------------------------------------|
| CurrentDoorState | \<item> | Yes | | SHNG item to monitor the current door state |
| TargetDoorState | \<item> | Yes | | SHNG item to monitor and set the target position |
| ObstructionDetected | \<item> | No | | SHNG item to monitor if the door is blocked |
#### Additional comments
Valid values for 'CurrentDoorState':
* OPEN = 0
* CLOSED = 1
* OPENING = 2
* CLOSING = 3
* STOPPED = 4
Valid values for 'TargetDoorState':
* OPEN = 0
* CLOSED = 1
'ObstructionDetected' may be set 'true' if there is any physical problem opening/closing the door.
#### Example
```json
{
"type": "GarageDoor",
"name": "GarageRechts",
"currentdoorstate": "garage.rechts.cds",
"targetdoorstate": "garage.rechts.tds",
"obstructiondetected": "garage.rechts.od"
}
```
### Humidity sensor
This accessory shows the current relative humidity in %.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:-------------------|:----------------|:----------|:-----------------------------------------------|
| CurrentHumidity | \<item> | Yes | SHNG item to monitor relative humidity in % |
#### Example:
```json
{
"type": "HumiditySensor",
"name": "Luftfeuchtigkeit Glashaus",
"CurrentHumidity": "Glashaus.Luftfeuchtigkeit"
}
```
### LightBulb ### LightBulb
Lightbulb can be as simple as a generic on/off light, but can also be as complex as a full RGBW led strip. Lightbulb can be as simple as a generic on/off light, but can also be as complex as a full RGBW led strip.
@@ -180,6 +261,25 @@ The above optional min and max parameters allow you to specify the neede range f
} }
``` ```
### Motion sensor
This sensor is tripped if it detects motion in a room.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:---------------|:----------------|:----------|:--------------------------------|
| MotionDetected | \<item> | Yes | SHNG item to monitor for motion |
#### Example:
```json
{
"type": "MotionSensor",
"name": "Movement hallway",
"MotionDetected": "EG.Flur.Bewegung"
}
```
### Occupancy sensor ### Occupancy sensor
This sensor is tripped if it detects presence in a room. This sensor is tripped if it detects presence in a room.
@@ -200,59 +300,6 @@ This sensor is tripped if it detects presence in a room.
} }
``` ```
### Motion sensor
This sensor is tripped if it detects motion in a room.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:---------------|:----------------|:----------|:--------------------------------|
| MotionDetected | \<item> | Yes | SHNG item to monitor for motion |
#### Example:
```json
{
"type": "MotionSensor",
"name": "Movement hallway",
"MotionDetected": "EG.Flur.Bewegung"
}
```
### Contact sensor
This sensor shows the open / closed state of a contact (door, window, generic ...).
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:-------------|:----------------|:----------|:---------------------------------|
| ContactState | \<item> | Yes | SHNG item to monitor for contact |
#### Example:
```json
{
"type": "ContactSensor",
"name": "Window kitchen",
"ContactState": "EG.Kueche.Fenster"
}
```
### Switch
This accessory can monitor and change the on/off state of something. It is very similar to an outlet.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:----------|:----------------|:----------|:----------------------------------------|
| On | \<item> | Yes | SHNG item to switch something on or off |
#### Example:
```json
{
"type": "Switch",
"name": "Music living-room",
"On": "EG.Stube.Radio"
}
```
### Outlet ### Outlet
This accessory can monitor and change the on/off state of a wall outlet. The outlet can be generic, a light, a fan, ... This accessory can monitor and change the on/off state of a wall outlet. The outlet can be generic, a light, a fan, ...
@@ -305,8 +352,26 @@ Valid values for 'TargetState':
} }
``` ```
### Switch
This accessory can monitor and change the on/off state of something. It is very similar to an outlet.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
|:----------|:----------------|:----------|:----------------------------------------|
| On | \<item> | Yes | SHNG item to switch something on or off |
#### Example:
```json
{
"type": "Switch",
"name": "Music living-room",
"On": "EG.Stube.Radio"
}
```
### Temperature sensor ### Temperature sensor
This sensor show the actual temperature. This sensor shows the actual temperature.
#### Characteristics in addition to [common characteristics](#common-accessories-characteristics) #### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description | | Parameter | Possible values | Mandatory | Description |
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "homebridge-smarthomeng", "name": "homebridge-smarthomeng",
"version": "2.0.0", "version": "2.0.4",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "homebridge-smarthomeng", "name": "homebridge-smarthomeng",
"version": "2.0.0", "version": "2.0.4",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"ws": "^8.4.2" "ws": "^8.4.2"
+4 -4
View File
@@ -2,15 +2,15 @@
"private": false, "private": false,
"displayName": "SmartHomeNG", "displayName": "SmartHomeNG",
"name": "homebridge-smarthomeng", "name": "homebridge-smarthomeng",
"version": "2.0.2", "version": "2.0.4",
"description": "A short description about what your plugin does.", "description": "SmartHomeNG plugin for Homebridge",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/Foxi352/homebridge-smarthomeng2.git" "url": "git://github.com/Foxi352/homebridge-smarthomeng.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/Foxi352/homebridge-smarthomeng2/issues" "url": "https://github.com/Foxi352/homebridge-smarthomeng/issues"
}, },
"engines": { "engines": {
"node": ">=14.18.1", "node": ">=14.18.1",
+135
View File
@@ -0,0 +1,135 @@
import {
AccessoryPlugin,
CharacteristicValue,
Service,
Nullable,
} from 'homebridge';
import { SmartHomeNGPlatform } from '../platform';
export class GarageDoor implements AccessoryPlugin {
private readonly deviceService: Service;
private readonly informationService: Service;
public name: string;
private targetDoorState = this.platform.Characteristic.CurrentDoorState.CLOSED;
private currentDoorState = this.platform.Characteristic.CurrentDoorState.STOPPED;
private obstructionDetected = false;
constructor(private readonly platform: SmartHomeNGPlatform, private readonly accessory) {
this.name = accessory.name;
this.deviceService = new this.platform.Service.GarageDoorOpener(accessory.name);
// create handlers for required characteristics
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.currentdoorstate); // FIXME
if (accessory.currentdoorstate) {
this.platform.shng.addMonitor(accessory.currentdoorstate, this.shngCurrentDoorStateCallback.bind(this));
this.deviceService.getCharacteristic(this.platform.Characteristic.CurrentDoorState)
.onGet(this.getCurrentDoorState.bind(this))
.onSet(this.setCurrentDoorState.bind(this));
} else {
this.platform.log.error('GarageDoor: missing \"currentdoorstate\" in config.json!');
}
if (accessory.targetdoorstate) {
this.platform.shng.addMonitor(accessory.targetdoorstate, this.shngTargetDoorStateCallback.bind(this));
this.deviceService.getCharacteristic(this.platform.Characteristic.TargetDoorState)
.onGet(this.getTargetDoorState.bind(this))
.onSet(this.setTargetDoorState.bind(this));
} else {
this.platform.log.error('GarageDoor: missing \"targetdoorstate\" in config.json!');
}
if (accessory.obstructiondetected) {
this.platform.shng.addMonitor(accessory.obstructiondetected, this.shngObstructionDetectedCallback.bind(this));
this.deviceService.getCharacteristic(this.platform.Characteristic.ObstructionDetected)
.onGet(this.getObstructionDetected.bind(this))
.onSet(this.setObstructionDetected.bind(this));
}
this.platform.log.info("GarageDoor '%s' created!", accessory.name);
}
identify(): void {
this.platform.log.info('Identify!');
}
getServices(): Service[] {
return [this.informationService, this.deviceService];
}
getCurrentDoorState(): Nullable<CharacteristicValue> {
//getCurrentDoorState(value: CharacteristicValue) {
// this.currentDoorState = value as number;
this.platform.log.info('getCurrentDoorState:', this.accessory.name, 'is currently', this.currentDoorState);
return this.currentDoorState;
}
setCurrentDoorState(value: CharacteristicValue) {
this.currentDoorState = value as number;
this.platform.log.info('setCurrentDoorState:', this.accessory.name, 'was set to', this.currentDoorState);
this.platform.shng.setItem(this.accessory.currentdoorstate, this.currentDoorState);
}
getTargetDoorState(): Nullable<CharacteristicValue> {
//getTargetDoorState(value: CharacteristicValue) {
// this.targetDoorState = value as number;
this.platform.log.info('getTargetDoorState:', this.accessory.name, 'is currently', this.targetDoorState);
return this.targetDoorState;
}
setTargetDoorState(value: CharacteristicValue) {
this.targetDoorState = value as number;
this.platform.log.info('setTargetDoorState:', this.accessory.name, 'was set to', this.targetDoorState);
this.platform.shng.setItem(this.accessory.targetdoorstate, this.targetDoorState);
}
getObstructionDetected(): Nullable<CharacteristicValue> {
this.platform.log.info('getObstructionDetected:', this.accessory.name, 'is currently', this.obstructionDetected);
return this.obstructionDetected;
}
setObstructionDetected(value: CharacteristicValue) {
this.obstructionDetected = value as boolean;
this.platform.log.info('setObstructionDetected:', this.accessory.name, 'was set to', this.obstructionDetected);
this.platform.shng.setItem(this.accessory.obstructiondetected, this.obstructionDetected);
}
shngCurrentDoorStateCallback(value: unknown): void {
this.platform.log.debug('shngCurrentDoorStateCallback:', this.accessory.name, '=', value, '(' + typeof value + ')');
if (typeof value === 'number') {
this.currentDoorState = value;
this.deviceService.updateCharacteristic(this.platform.Characteristic.CurrentDoorState, this.currentDoorState);
} else {
this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value);
}
}
shngTargetDoorStateCallback(value: unknown): void {
this.platform.log.debug('shngTargetDoorStateCallback:', this.accessory.name, '=', value, '(' + typeof value + ')');
if (typeof value === 'number') {
this.targetDoorState = value;
this.deviceService.updateCharacteristic(this.platform.Characteristic.TargetDoorState, this.targetDoorState);
} else {
this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value);
}
}
shngObstructionDetectedCallback(value: unknown): void {
this.platform.log.debug('shngObstructionDetectedCallback:', this.accessory.name, '=', value, '(' + typeof value + ')');
if (typeof value === 'boolean') {
this.obstructionDetected = value;
this.deviceService.updateCharacteristic(this.platform.Characteristic.ObstructionDetected, this.obstructionDetected);
} else {
this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value);
}
}
}
+59
View File
@@ -0,0 +1,59 @@
import {
AccessoryPlugin,
CharacteristicValue,
Service,
Nullable,
} from 'homebridge';
import { SmartHomeNGPlatform } from '../platform';
export class HumiditySensor implements AccessoryPlugin {
private readonly deviceService: Service;
private readonly informationService: Service;
public name: string;
private currentHumidity = 0;
constructor(private readonly platform: SmartHomeNGPlatform, private readonly accessory) {
this.name = accessory.name;
this.deviceService = new this.platform.Service.HumiditySensor(accessory.name);
// create handlers for required characteristics
this.deviceService.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
.onGet(this.getCurrentHumidity.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.currenthumidity);
this.platform.shng.addMonitor(accessory.currenthumidity, this.shngCallback.bind(this));
this.platform.log.info('HumiditySensor', accessory.name, 'created!');
}
identify(): void {
this.platform.log.info('Identify!');
}
getServices(): Service[] {
return [this.informationService, this.deviceService];
}
getCurrentHumidity(): Nullable<CharacteristicValue> {
this.platform.log.debug('getCurrentHumidity:', this.accessory.name, '=', this.currentHumidity);
return this.currentHumidity;
}
shngCallback(value: unknown): void {
this.platform.log.debug('shngCallback:', this.accessory.name, '=', value, '(' + typeof value + ')');
if (typeof value === 'number') {
this.currentHumidity = value;
} else {
this.platform.log.warn('Unknown type', typeof value, 'received for', this.accessory.name + ':', value);
}
this.deviceService.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.currentHumidity);
}
}
+1 -1
View File
@@ -29,7 +29,7 @@ export class Doorbell implements AccessoryPlugin {
.setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.singlepress); .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.singlepress);
this.platform.shng.addMonitor(accessory.contactstate, this.shngCallback.bind(this)); this.platform.shng.addMonitor(accessory.contactstate, this.shngCallback.bind(this));
this.platform.log.info('ContactSensor', accessory.name, 'created!'); this.platform.log.info('Doorbell', accessory.name, 'created!');
} }
identify(): void { identify(): void {
+14 -2
View File
@@ -21,6 +21,8 @@ import { Doorbell } from './Accessories/Doorbell';
import { SecuritySystem } from './Accessories/SecuritySystem'; import { SecuritySystem } from './Accessories/SecuritySystem';
import { OccupancySensor } from './Accessories/OccupancySensor'; import { OccupancySensor } from './Accessories/OccupancySensor';
import { MotionSensor } from './Accessories/MotionSensor'; import { MotionSensor } from './Accessories/MotionSensor';
import { GarageDoor } from './Accessories/GarageDoor';
import { HumiditySensor } from './Accessories/HumiditySensor';
function uncapitalizeKeys(obj): Record<string, unknown> { function uncapitalizeKeys(obj): Record<string, unknown> {
function isObject(o: unknown): boolean { function isObject(o: unknown): boolean {
@@ -106,7 +108,7 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
devices.push(new Doorbell(this, accessory)); devices.push(new Doorbell(this, accessory));
break; break;
// Doorbell // Security system
case 'securitysystem': case 'securitysystem':
devices.push(new SecuritySystem(this, accessory)); devices.push(new SecuritySystem(this, accessory));
break; break;
@@ -131,7 +133,7 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
devices.push(new Fan(this, accessory)); devices.push(new Fan(this, accessory));
break; break;
// TemperatureSensor // Temperature sensor
case 'temperaturesensor': case 'temperaturesensor':
devices.push(new TemperatureSensor(this, accessory)); devices.push(new TemperatureSensor(this, accessory));
break; break;
@@ -146,6 +148,16 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
devices.push(new WindowCovering(this, accessory)); devices.push(new WindowCovering(this, accessory));
break; break;
// Garage door
case 'garagedoor':
devices.push(new GarageDoor(this, accessory));
break;
// Humidity sensor
case 'humiditysensor':
devices.push(new HumiditySensor(this, accessory));
break;
// Show error for (yet ?) unsupported device // Show error for (yet ?) unsupported device
default: default:
this.log.warn('Accessory type', accessory.type, 'for', accessory.name, 'not recognized !'); this.log.warn('Accessory type', accessory.type, 'for', accessory.name, 'not recognized !');