Skip to content

Commit

Permalink
Added new service WindowCovering and corresponding characteristics
Browse files Browse the repository at this point in the history
Improved validity checks for state-characteristics on data passed to homekit by characteristics
  • Loading branch information
En3rGy committed Jun 21, 2024
1 parent 829b773 commit 11dee44
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 26 deletions.
54 changes: 39 additions & 15 deletions config.schema.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"pluginAlias": "hsd",
"pluginType": "platform",
"footerDisplay": "v0.8",
"footerDisplay": "v0.9",
"singular": false,
"schema": {
"required": [
Expand Down Expand Up @@ -66,6 +66,12 @@
"required": true,
"default": "Lightbulb",
"oneOf": [
{
"title": "Garage Door Opener",
"enum": [
"GarageDoorOpener"
]
},
{
"title": "Lightbulb",
"enum": [
Expand All @@ -85,17 +91,23 @@
]
},
{
"title": "Garage Door Opener",
"title": "Temperature Sensor",
"enum": [
"GarageDoorOpener"
"TemperatureSensor"
]
},
{
"title": "Window",
"enum": [
"Window"
]
}
},
{
"title": "Window Covering",
"enum": [
"WindowCovering"
]
}
]
},
"characteristics": {
Expand All @@ -109,7 +121,7 @@
"title": "Characteristics",
"type": "string",
"default": "On",
"description": "<h4>Endpoints</h4><p><ul><li>Brightness: 1=set, 2=get</li><li>On: 1=set, 2=get</li><li>CurrentDoorState: 1=get</li><li>TargetDoorState: 1=set, 2=get</li><li>ObstructionDetected: 1=get</li></ul></p>",
"description": "<h4>Endpoints</h4><p><ul><li>Brightness: 1=set, 2=get</li><li>On: 1=set, 2=get</li><li>CurrentDoorState: 1=get</li><li>CurrentPosition: 1=get</li><li>CurrentTemperature: 1=get</li><li>HoldPosition: 1=set</li><li>ObstructionDetected: 1=get</li><li>On: 1=set, 2=get</li><li>PositionState: 1=set</li><li>TargetDoorState: 1=set, 2=get</li><li>TargetPosition: 1=set, 2=get</li></ul></p>",
"oneOf": [
{
"title": "Brightness",
Expand All @@ -118,21 +130,27 @@
]
},
{
"title": "On",
"title": "Current Door State",
"enum": [
"On"
"CurrentDoorState"
]
},
{
"title": "Current Door State",
"title": "Current Position",
"enum": [
"CurrentDoorState"
"CurrentPosition"
]
},
{
"title": "Current Temperature",
"enum": [
"CurrentTemperature"
]
},
{
"title": "Target Door State",
"title": "Hold Position",
"enum": [
"TargetDoorState"
"HoldPosition"
]
},
{
Expand All @@ -141,22 +159,28 @@
"ObstructionDetection"
]
},
{
"title": "On",
"enum": [
"On"
]
},
{
"title": "Position State",
"enum": [
"PositionState"
]
},
{
"title": "Target Position",
"title": "Target Door State",
"enum": [
"TargetPosition"
"TargetDoorState"
]
},
{
"title": "Current Temperature",
"title": "Target Position",
"enum": [
"CurrentTemperature"
"TargetPosition"
]
}
]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "homebridge-hsd",
"displayName": "Homebridge Gira Homeserver URL-Endpoint",
"version": "1.1.10",
"version": "1.1.11",
"description": "Plugin to access KNX bus via Gira Homeserver",
"license": "MIT",
"keywords": [
Expand Down
36 changes: 36 additions & 0 deletions src/service/WindowCovering.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { HomeServerConnector } from '../hs';
import { API } from 'homebridge';

import { HsdPlatformAccessory } from '../hsdPlatformAccessory';
import { addCurrentPositionCharacteristic } from './characteristic/CurrentPosition';
import { addPositionStateCharacteristic } from './characteristic/PositionState';
import { addTargetPositionCharacteristic } from './characteristic/TargetPosition';
import { addObstructionDetectedCharacteristic } from './characteristic/ObstructionDetected';
import { addHoldPositionCharacteristic } from './characteristic/HoldPosition';
import { HsdServiceConfig } from '../config';
import { AbstractHsdService } from './AbstractHsdService';
// import { addListener } from 'process';

export class WindowCovering extends AbstractHsdService {

public constructor (api: API, hsd: HomeServerConnector, accessory: HsdPlatformAccessory, config: HsdServiceConfig) {
super(api, hsd, accessory, config);

const service = this.getService(this.api.hap.Service.Window);
//service.setCharacteristic(this.api.hap.Service.name, config.serviceName);

for (const characteristic of config.characteristics) {
if (characteristic.characteristicName === 'CurrentPosition') {
addCurrentPositionCharacteristic(api, service, hsd, characteristic.endpoints[0]);
} else if (characteristic.characteristicName === 'PositionState') {
addPositionStateCharacteristic(api, service, hsd, characteristic.endpoints[0]);
} else if (characteristic.characteristicName === 'TargetPosition') {
addTargetPositionCharacteristic(api, service, hsd, characteristic.endpoints[0], characteristic.endpoints[1]);
} else if (characteristic.characteristicName === 'ObstructionDetected') {
addObstructionDetectedCharacteristic(api, service, hsd, characteristic.endpoints[0]);
} else if (characteristic.characteristicName === 'HoldPosition') {
addHoldPositionCharacteristic(api, service, hsd, characteristic.endpoints[0]);
}
}
}
}
20 changes: 16 additions & 4 deletions src/service/characteristic/CurrentDoorState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,24 @@ export const addCurrentDoorStateCharacteristic = (api: API,
}, getEndpoint);

currentDoorStat.onGet(async () => {
const ret = hsd.getCo(getEndpoint);
if (typeof(ret) === 'object') {
const ret = Number(hsd.getCo(getEndpoint));

let state = -1;
if (ret === api.hap.Characteristic.CurrentDoorState.OPEN) {
state = api.hap.Characteristic.CurrentDoorState.OPEN;
} else if (ret === api.hap.Characteristic.CurrentDoorState.CLOSED) {
state = api.hap.Characteristic.CurrentDoorState.CLOSED;
} else if (ret === api.hap.Characteristic.CurrentDoorState.OPENING) {
state = api.hap.Characteristic.CurrentDoorState.OPEN;
} else if (ret === api.hap.Characteristic.CurrentDoorState.CLOSING) {
state = api.hap.Characteristic.CurrentDoorState.CLOSING;
} else if (ret === api.hap.Characteristic.CurrentDoorState.STOPPED) {
state = api.hap.Characteristic.CurrentDoorState.STOPPED;
} else {
return Promise.reject(0);
//return Promise.reject(new Error('CurrentDoorState.ts | CurrentDoorStat.onGet | Invalid return object!'));
}
return Number(ret);

return state;
});
};

2 changes: 1 addition & 1 deletion src/service/characteristic/CurrentPosition.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { API, Service } from 'homebridge';
import { HomeServerConnector } from '../../hs';

export const addCurrentPosition = (api: API,
export const addCurrentPositionCharacteristic = (api: API,
service: Service,
hsd: HomeServerConnector,
getEndpoint: string): void => {
Expand Down
20 changes: 20 additions & 0 deletions src/service/characteristic/HoldPosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { API, Service } from 'homebridge';
import { HomeServerConnector } from '../../hs';

export const addHoldPositionCharacteristic = (api: API,
service: Service,
hsd: HomeServerConnector,
setEndpoint: string): void => {

const holdPosition = service.getCharacteristic(api.hap.Characteristic.HoldPosition);

// Add subscription
hsd.addListener(reading => {
holdPosition.updateValue(Boolean(reading));
}, setEndpoint);

holdPosition.onSet(async hold => {
hsd.setCo(setEndpoint, Boolean(hold));
});
};

9 changes: 9 additions & 0 deletions src/service/characteristic/LockCurrentState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@ export const addOnCharacteristic = (api: API,
}, getEndpoint);

lockCurrentState.onGet(async () => {

/* todo:
UNSECURED Characteristic.LockCurrentState.UNSECURED 0
SECURED Characteristic.LockCurrentState.SECURED 1
JAMMED Characteristic.LockCurrentState.JAMMED 2
UNKNOWN Characteristic.LockCurrentState.UNKNOWN 3
*/

return Number(hsd.getCo(getEndpoint));
});

lockCurrentState.onSet(async turnOn => {

hsd.setCo(setEndpoint, Number(turnOn));
});
};
Expand Down
7 changes: 7 additions & 0 deletions src/service/characteristic/LockTarget State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export const addOnCharacteristic = (api: API,
}, getEndpoint);

lockTargetState.onGet(async () => {

/* todo:
User
UNSECURED Characteristic.LockTargetState.UNSECURED 0
SECURED Characteristic.LockTargetState.SECURED 1
*/

return Number(hsd.getCo(getEndpoint));
});

Expand Down
13 changes: 12 additions & 1 deletion src/service/characteristic/PositionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@ export const addPositionStateCharacteristic = (api: API,
}, getEndpoint);

positionState.onGet(async () => {
return Number(hsd.getCo(getEndpoint));
const ret = Number(hsd.getCo(getEndpoint));
let state = -1;
if (ret === api.hap.Characteristic.PositionState.STOPPED) {
state = api.hap.Characteristic.PositionState.STOPPED;
} else if (ret === api.hap.Characteristic.PositionState.DECREASING) {
state = api.hap.Characteristic.PositionState.DECREASING;
} else if (ret === api.hap.Characteristic.PositionState.INCREASING) {
state = api.hap.Characteristic.PositionState.INCREASING;
} else {
return Promise.reject(0);
}
return state;
});
};

13 changes: 9 additions & 4 deletions src/service/characteristic/TargetDoorState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ export const addTargetDoorStateCharacteristic = (api: API,
}, getEndpoint);

targetDoorState.onGet(async () => {
const ret = hsd.getCo(getEndpoint);
if (typeof(ret) === 'object') {
const ret = Number(hsd.getCo(getEndpoint));
let state = api.hap.Characteristic.TargetDoorState.OPEN;

if (ret === api.hap.Characteristic.TargetDoorState.OPEN) {
state = api.hap.Characteristic.TargetDoorState.OPEN;
} else if (ret === api.hap.Characteristic.TargetDoorState.CLOSED) {
state = api.hap.Characteristic.TargetDoorState.CLOSED;
} else {
return Promise.reject(0);
// return Promise.reject(new Error('TargetDoorState.ts | targetDoorState.onGet | Invalid return object!'));
}
return Number(ret);
return state;
});

targetDoorState.onSet(async state => {
Expand Down

0 comments on commit 11dee44

Please sign in to comment.