Merge pull request #13 from chester4444/master
Added GarageDoor and HumiditySensor
This commit is contained in:
commit
ae63f6cdee
58
README.md
58
README.md
@ -17,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 |
|
||||||
@ -153,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.
|
||||||
|
|
||||||
@ -315,7 +371,7 @@ This accessory can monitor and change the on/off state of something. It is very
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 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 |
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -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"
|
||||||
|
|||||||
135
src/Accessories/GarageDoor.ts
Normal file
135
src/Accessories/GarageDoor.ts
Normal 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
src/Accessories/HumiditySensor.ts
Normal file
59
src/Accessories/HumiditySensor.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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 {
|
||||||
|
|||||||
@ -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 !');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user