Skip to content

Commit

Permalink
Merge pull request #13 from chester4444/master
Browse files Browse the repository at this point in the history
Added GarageDoor and HumiditySensor
  • Loading branch information
Serge Wagener authored Mar 8, 2022
2 parents bbc42df + c6f596e commit ae63f6c
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 6 deletions.
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This plugin currently supports the following services (and characteristics):
| [ContactSensor](#contact-sensor) | Simple contact sensor, for example for windows |
| [Doorbell](#doorbell) | Doorbell, sends message to devices on ring |
| [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 |
| [MotionSensor](#motion-sensor) | Detects and reports motion |
| [OccupancySensor](#occupancy-sensor) | Detects presence in a room |
Expand Down Expand Up @@ -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 can be as simple as a generic on/off light, but can also be as complex as a full RGBW led strip.

Expand Down Expand Up @@ -315,7 +371,7 @@ This accessory can monitor and change the on/off state of something. It is very
```

### Temperature sensor
This sensor show the actual temperature.
This sensor shows the actual temperature.

#### Characteristics in addition to [common characteristics](#common-accessories-characteristics)
| Parameter | Possible values | Mandatory | Description |
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

135 changes: 135 additions & 0 deletions src/Accessories/GarageDoor.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 59 additions & 0 deletions src/Accessories/HumiditySensor.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}


2 changes: 1 addition & 1 deletion src/Accessories/VideoDoorbell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class Doorbell implements AccessoryPlugin {
.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!');
this.platform.log.info('Doorbell', accessory.name, 'created!');
}

identify(): void {
Expand Down
16 changes: 14 additions & 2 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { Doorbell } from './Accessories/Doorbell';
import { SecuritySystem } from './Accessories/SecuritySystem';
import { OccupancySensor } from './Accessories/OccupancySensor';
import { MotionSensor } from './Accessories/MotionSensor';
import { GarageDoor } from './Accessories/GarageDoor';
import { HumiditySensor } from './Accessories/HumiditySensor';

function uncapitalizeKeys(obj): Record<string, unknown> {
function isObject(o: unknown): boolean {
Expand Down Expand Up @@ -106,7 +108,7 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
devices.push(new Doorbell(this, accessory));
break;

// Doorbell
// Security system
case 'securitysystem':
devices.push(new SecuritySystem(this, accessory));
break;
Expand All @@ -131,7 +133,7 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
devices.push(new Fan(this, accessory));
break;

// TemperatureSensor
// Temperature sensor
case 'temperaturesensor':
devices.push(new TemperatureSensor(this, accessory));
break;
Expand All @@ -146,6 +148,16 @@ export class SmartHomeNGPlatform implements StaticPlatformPlugin {
devices.push(new WindowCovering(this, accessory));
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
default:
this.log.warn('Accessory type', accessory.type, 'for', accessory.name, 'not recognized !');
Expand Down

0 comments on commit ae63f6c

Please sign in to comment.