Skip to content

Commit

Permalink
Added window covering to schema and updated config validation
Browse files Browse the repository at this point in the history
  • Loading branch information
justjam2013 committed Nov 20, 2024
1 parent fc75f83 commit 5444bae
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 36 deletions.
65 changes: 39 additions & 26 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,30 @@
{ "title": "Garage Door", "enum": ["garagedoor"] },
{ "title": "Lock", "enum": ["lock"] },
{ "title": "Sensor", "enum": ["sensor"] },
{ "title": "Switch", "enum": ["switch"] }
{ "title": "Switch", "enum": ["switch"] },
{ "title": "Window Covering - Blinds, Shades)", "enum": ["windowcovering"] }
],
"default": "switch"
},
"switchDefaultState": {
"title": "Switch Default State *",
"description": "Switch default state",
"doorbellVolume": {
"title": "Doorbell Volume *",
"description": "Doorbell volume *",
"type": "integer",
"minimum": 0,
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'doorbell';"
}
},
"garageDoorDefaultState": {
"title": "Garage Door Default State *",
"description": "Garage Door default state",
"type": "string",
"oneOf": [
{ "title": "Off", "enum": ["off"] },
{ "title": "On", "enum": ["on"] }
{ "title": "Closed", "enum": ["closed"] },
{ "title": "Open", "enum": ["open"] }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'switch';"
"functionBody": "return model.devices[arrayIndices].accessoryType === 'garagedoor';"
}
},
"lockDefaultState": {
Expand All @@ -74,18 +84,6 @@
"functionBody": "return model.devices[arrayIndices].accessoryType === 'lock';"
}
},
"garageDoorDefaultState": {
"title": "Garage Door Default State *",
"description": "Garage Door default state",
"type": "string",
"oneOf": [
{ "title": "Closed", "enum": ["closed"] },
{ "title": "Open", "enum": ["open"] }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'garagedoor';"
}
},
"lockHardwareFinish": {
"title": "Lock Hardware Finish *",
"description": "Color of the virtual HomeKey card in the Wallet app",
Expand All @@ -100,13 +98,28 @@
"functionBody": "return model.devices[arrayIndices].accessoryType === 'lock';"
}
},
"doorbellVolume": {
"title": "Doorbell Volume *",
"description": "Doorbell volume *",
"type": "integer",
"minimum": 0,
"switchDefaultState": {
"title": "Switch Default State *",
"description": "Switch default state",
"type": "string",
"oneOf": [
{ "title": "Off", "enum": ["off"] },
{ "title": "On", "enum": ["on"] }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'doorbell';"
"functionBody": "return model.devices[arrayIndices].accessoryType === 'switch';"
}
},
"windowCoveringDefaultState": {
"title": "Window Covering Default State *",
"description": "Window Covering default state",
"type": "string",
"oneOf": [
{ "title": "Closed", "enum": ["closed"] },
{ "title": "Open", "enum": ["open"] }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'windowcovering';"
}
},
"sensorType": {
Expand Down Expand Up @@ -143,7 +156,7 @@
"description": "Accessory state survives Homebridge restart",
"type": "boolean",
"condition": {
"functionBody": "return ['switch', 'lock', 'garagedoor'].includes(model.devices[arrayIndices].accessoryType) && [undefined, false].includes(model.devices[arrayIndices].accessoryHasResetTimer);"
"functionBody": "return ['switch', 'lock', 'garagedoor', 'windowcovering'].includes(model.devices[arrayIndices].accessoryType) && [undefined, false].includes(model.devices[arrayIndices].accessoryHasResetTimer);"
}
},
"accessoryHasResetTimer": {
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.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "homebridge-virtual-accessories",
"displayName": "Virtual Accessories for Homebridge",
"type": "module",
"version": "1.0.4",
"version": "1.1.0-beta.1",
"description": "Virtual accessories for Homebridge.",
"author": "justjam2013",
"license": "Apache-2.0",
Expand Down
8 changes: 4 additions & 4 deletions src/accessories/virtualAccessoryWindowCovering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export class WindowCovering extends Accessory {
static readonly CLOSED: number = 0; // 0%
static readonly OPEN: number = 100; // 100%

static readonly DECREASING: number = 0; // Characteristic.PositionState.DECREASING;
static readonly INCREASING: number = 1; // Characteristic.PositionState.INCREASING;
static readonly STOPPED: number = 2; // Characteristic.PositionState.STOPPED;
static readonly DECREASING: number = 0; // Characteristic.PositionState.DECREASING; -> CLOSING
static readonly INCREASING: number = 1; // Characteristic.PositionState.INCREASING; -> OPENING
static readonly STOPPED: number = 2; // Characteristic.PositionState.STOPPED; -> OPEN or CLOSED

/**
* These are just used to create a working example
Expand Down Expand Up @@ -161,7 +161,7 @@ export class WindowCovering extends Accessory {
*/
async handlePositionStateGet() {
// implement your own code to check if the device is on
const windowCoveringPosition = this.platform.Characteristic.PositionState.DECREASING;
const windowCoveringPosition = this.platform.Characteristic.PositionState.STOPPED;

this.platform.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Window Covering Position: ${this.getPositionName(windowCoveringPosition)}`);

Expand Down
4 changes: 4 additions & 0 deletions src/accessoryFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Switch } from './accessories/virtualAccessorySwitch.js';
import { Lock } from './accessories/virtualAccessoryLock.js';
import { Doorbell } from './accessories/virtualAccessoryDoorbell.js';
import { GarageDoor } from './accessories/virtualAccessoryGarageDoor.js';
import { WindowCovering } from './accessories/virtualAccessoryWindowCovering.js';

import { VirtualSensor } from './sensors/virtualSensor.js';
import { VirtualContactSensor } from './sensors/virtualSensorContact.js';
Expand Down Expand Up @@ -55,6 +56,9 @@ export abstract class AccessoryFactory {
case 'garagedoor':
virtualAccessory = new GarageDoor(platform, accessory);
break;
case 'windowcovering':
virtualAccessory = new WindowCovering(platform, accessory);
break;
case 'sensor':
virtualAccessory = AccessoryFactory.createVirtualSensor(platform, accessory, accessoryConfiguration.sensorType);
break;
Expand Down
19 changes: 16 additions & 3 deletions src/configuration/configurationAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ export class AccessoryConfiguration {
// Doorbell
doorbellVolume!: number;

// Window Covering
windowCoveringDefaultState!: string;

// Sensor
sensorType!: string;
sensorTrigger!: string;

// Window Covering
windowCoveringDefaultState!: string;

// Reset timer
@Type(TimerConfiguration)
resetTimer!: TimerConfiguration;
Expand Down Expand Up @@ -96,6 +96,8 @@ export class AccessoryConfiguration {
return this.isValidSensor();
case 'switch':
return this.isValidSwitch();
case 'windowcovering':
return this.isValidWindowCovering();
default:
return false;
}
Expand Down Expand Up @@ -208,6 +210,17 @@ export class AccessoryConfiguration {
);
};

private isValidWindowCovering(): boolean {
const isValidWindowCoveringDefaultState: boolean = (this.windowCoveringDefaultState !== undefined);

// Store fields failing validation
if (!isValidWindowCoveringDefaultState) this.errorFields.push('windowCoveringDefaultState');

return (
isValidWindowCoveringDefaultState
);
}

/**
* Adornment validation
*/
Expand Down

0 comments on commit 5444bae

Please sign in to comment.