@jgrimard/homebridge-vivint 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +107 -0
- package/config.schema.json +90 -0
- package/dist/devices/camera.js +368 -0
- package/dist/devices/camera.js.map +1 -0
- package/dist/devices/carbonMonoxideSensor.js +44 -0
- package/dist/devices/carbonMonoxideSensor.js.map +1 -0
- package/dist/devices/contactSensor.js +65 -0
- package/dist/devices/contactSensor.js.map +1 -0
- package/dist/devices/device.js +147 -0
- package/dist/devices/device.js.map +1 -0
- package/dist/devices/dimmerSwitch.js +12 -0
- package/dist/devices/dimmerSwitch.js.map +1 -0
- package/dist/devices/garageDoor.js +58 -0
- package/dist/devices/garageDoor.js.map +1 -0
- package/dist/devices/index.js +55 -0
- package/dist/devices/index.js.map +1 -0
- package/dist/devices/lightGroup.js +15 -0
- package/dist/devices/lightGroup.js.map +1 -0
- package/dist/devices/lightSwitch.js +42 -0
- package/dist/devices/lightSwitch.js.map +1 -0
- package/dist/devices/lock.js +49 -0
- package/dist/devices/lock.js.map +1 -0
- package/dist/devices/motionSensor.js +73 -0
- package/dist/devices/motionSensor.js.map +1 -0
- package/dist/devices/multiLevelSwitchBase.js +55 -0
- package/dist/devices/multiLevelSwitchBase.js.map +1 -0
- package/dist/devices/panel.js +79 -0
- package/dist/devices/panel.js.map +1 -0
- package/dist/devices/smokeSensor.js +47 -0
- package/dist/devices/smokeSensor.js.map +1 -0
- package/dist/devices/thermostat.js +216 -0
- package/dist/devices/thermostat.js.map +1 -0
- package/dist/homebridge-ui/public/index.html +138 -0
- package/dist/homebridge-ui/server.js +120 -0
- package/dist/homebridge-ui/server.js.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.js +393 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.js +12 -0
- package/dist/settings.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/debounce.js +49 -0
- package/dist/utils/debounce.js.map +1 -0
- package/dist/utils/ports.js +39 -0
- package/dist/utils/ports.js.map +1 -0
- package/dist/utils/redact.js +19 -0
- package/dist/utils/redact.js.map +1 -0
- package/dist/utils/sanitizeName.js +22 -0
- package/dist/utils/sanitizeName.js.map +1 -0
- package/dist/vivint/api.js +246 -0
- package/dist/vivint/api.js.map +1 -0
- package/dist/vivint/datapatch.js +52 -0
- package/dist/vivint/datapatch.js.map +1 -0
- package/dist/vivint/dictionary.js +66 -0
- package/dist/vivint/dictionary.js.map +1 -0
- package/dist/vivint/eventStream.js +77 -0
- package/dist/vivint/eventStream.js.map +1 -0
- package/dist/vivint/vivint_dictionary.json +8720 -0
- package/package.json +62 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { sanitizeDeviceName } from '../utils/sanitizeName.js';
|
|
2
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
3
|
+
import { VivintDevice } from './device.js';
|
|
4
|
+
const EQUIPMENT_CODES = [
|
|
5
|
+
'DW21R_RECESSED_DOOR',
|
|
6
|
+
'DW10_THIN_DOOR_WINDOW',
|
|
7
|
+
'DW11_THIN_DOOR_WINDOW',
|
|
8
|
+
'DW20_RECESSED_DOOR',
|
|
9
|
+
'EXISTING_DOOR_WINDOW_CONTACT',
|
|
10
|
+
'TAKE_TAKEOVER',
|
|
11
|
+
'GB1_GLASS_BREAK',
|
|
12
|
+
'GB2_GLASS_BREAK',
|
|
13
|
+
'EXISTING_GLASS_BREAK',
|
|
14
|
+
'HW_GLASS_BREAK_5853',
|
|
15
|
+
'TILT_SENSOR_2GIG_345',
|
|
16
|
+
'EXISTING_HEAT',
|
|
17
|
+
'EXISTING_FLOOD_TEMP',
|
|
18
|
+
'SWS1_SMART_WATER_SENSOR',
|
|
19
|
+
'DW12_THIN_DOOR_WINDOW',
|
|
20
|
+
'GB3_GLASS_BREAK',
|
|
21
|
+
'PIR3_MOTION',
|
|
22
|
+
'APOLLO_COMBO_SMOKE',
|
|
23
|
+
'APOLLO_COMBO_CO',
|
|
24
|
+
'GARAGE01_RESOLUTION_TILT',
|
|
25
|
+
].map(name => VivintDict.EquipmentCode[name]);
|
|
26
|
+
export class ContactSensor extends VivintDevice {
|
|
27
|
+
static className = 'ContactSensor';
|
|
28
|
+
static hasBattery = true;
|
|
29
|
+
service;
|
|
30
|
+
constructor(platform, accessory, data) {
|
|
31
|
+
super(platform, accessory, data);
|
|
32
|
+
this.service = this.ensureService(this.Service.ContactSensor, sanitizeDeviceName(this.name, this.id));
|
|
33
|
+
this.batteryService?.updateCharacteristic(this.Characteristic.ChargingState, this.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
34
|
+
this.service.getCharacteristic(this.Characteristic.ContactSensorState)
|
|
35
|
+
.onGet(() => this.getSensorState());
|
|
36
|
+
this.service.getCharacteristic(this.Characteristic.StatusTampered)
|
|
37
|
+
.onGet(() => this.getTamperedState());
|
|
38
|
+
this.notify();
|
|
39
|
+
}
|
|
40
|
+
getSensorState() {
|
|
41
|
+
return this.data.Status
|
|
42
|
+
? this.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
|
|
43
|
+
: this.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
44
|
+
}
|
|
45
|
+
notify() {
|
|
46
|
+
super.notify();
|
|
47
|
+
this.service.updateCharacteristic(this.Characteristic.ContactSensorState, this.getSensorState());
|
|
48
|
+
this.service.updateCharacteristic(this.Characteristic.StatusTampered, this.getTamperedState());
|
|
49
|
+
}
|
|
50
|
+
static appliesTo(data) {
|
|
51
|
+
return data.Type === VivintDict.PanelDeviceType.WirelessSensor
|
|
52
|
+
&& EQUIPMENT_CODES.includes(data.EquipmentCode);
|
|
53
|
+
}
|
|
54
|
+
static inferCategory(data, categories) {
|
|
55
|
+
const name = data.Name ?? '';
|
|
56
|
+
if (name.match(/\bwindow\b/i)) {
|
|
57
|
+
return categories.WINDOW;
|
|
58
|
+
}
|
|
59
|
+
else if (name.match(/\bdoor(way)?\b/i)) {
|
|
60
|
+
return categories.DOOR;
|
|
61
|
+
}
|
|
62
|
+
return categories.SENSOR;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=contactSensor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contactSensor.js","sourceRoot":"","sources":["../../src/devices/contactSensor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { dataPatch } from '../vivint/datapatch.js';
|
|
2
|
+
/**
|
|
3
|
+
* Base class for all Vivint device handlers. A handler wraps one Homebridge
|
|
4
|
+
* accessory, keeps the latest device data from the Vivint API, and pushes
|
|
5
|
+
* state changes into HomeKit.
|
|
6
|
+
*/
|
|
7
|
+
export class VivintDevice {
|
|
8
|
+
platform;
|
|
9
|
+
accessory;
|
|
10
|
+
/**
|
|
11
|
+
* Stable class name stored in accessory.context.deviceClassName. Must not
|
|
12
|
+
* change between releases, or cached accessories would be recreated.
|
|
13
|
+
*/
|
|
14
|
+
static className = 'VivintDevice';
|
|
15
|
+
/** Whether this device type exposes a Battery service. */
|
|
16
|
+
static hasBattery = false;
|
|
17
|
+
id;
|
|
18
|
+
name;
|
|
19
|
+
data;
|
|
20
|
+
batteryService;
|
|
21
|
+
constructor(platform, accessory, data) {
|
|
22
|
+
this.platform = platform;
|
|
23
|
+
this.accessory = accessory;
|
|
24
|
+
this.id = accessory.context.id;
|
|
25
|
+
this.name = accessory.context.name;
|
|
26
|
+
this.data = data ?? { Id: this.id };
|
|
27
|
+
const ctor = this.constructor;
|
|
28
|
+
if (ctor.hasBattery) {
|
|
29
|
+
this.batteryService = this.ensureService(this.platform.Service.Battery, `${this.name} Battery`);
|
|
30
|
+
this.batteryService.getCharacteristic(this.platform.Characteristic.StatusLowBattery)
|
|
31
|
+
.onGet(() => this.getLowBatteryState());
|
|
32
|
+
this.batteryService.getCharacteristic(this.platform.Characteristic.BatteryLevel)
|
|
33
|
+
.onGet(() => this.getBatteryLevelValue());
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the existing service of the given type, adding it first if the
|
|
38
|
+
* cached accessory does not have it yet.
|
|
39
|
+
*/
|
|
40
|
+
ensureService(type, name) {
|
|
41
|
+
const existing = this.accessory.getService(type);
|
|
42
|
+
if (existing) {
|
|
43
|
+
return existing;
|
|
44
|
+
}
|
|
45
|
+
// Concrete service classes take (displayName?, subtype?) — the abstract
|
|
46
|
+
// base type does not reflect that, hence the cast.
|
|
47
|
+
const ServiceCtor = type;
|
|
48
|
+
return this.accessory.addService(new ServiceCtor(name));
|
|
49
|
+
}
|
|
50
|
+
get Characteristic() {
|
|
51
|
+
return this.platform.Characteristic;
|
|
52
|
+
}
|
|
53
|
+
get Service() {
|
|
54
|
+
return this.platform.Service;
|
|
55
|
+
}
|
|
56
|
+
get log() {
|
|
57
|
+
return this.platform.log;
|
|
58
|
+
}
|
|
59
|
+
get vivintApi() {
|
|
60
|
+
return this.platform.vivintApi;
|
|
61
|
+
}
|
|
62
|
+
get config() {
|
|
63
|
+
return this.platform.config;
|
|
64
|
+
}
|
|
65
|
+
getBatteryLevelValue() {
|
|
66
|
+
return typeof this.data.BatteryLevel === 'number' ? this.data.BatteryLevel : 100;
|
|
67
|
+
}
|
|
68
|
+
getLowBatteryState() {
|
|
69
|
+
const threshold = this.config.lowBatteryLevel;
|
|
70
|
+
const low = threshold
|
|
71
|
+
? this.getBatteryLevelValue() <= threshold
|
|
72
|
+
: Boolean(this.data.LowBattery);
|
|
73
|
+
return low
|
|
74
|
+
? this.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
75
|
+
: this.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
76
|
+
}
|
|
77
|
+
getTamperedState() {
|
|
78
|
+
return this.data.Tamper
|
|
79
|
+
? this.Characteristic.StatusTampered.TAMPERED
|
|
80
|
+
: this.Characteristic.StatusTampered.NOT_TAMPERED;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Replaces the cached data with a full snapshot from the API.
|
|
84
|
+
*/
|
|
85
|
+
handleSnapshot(data) {
|
|
86
|
+
if (data.Id !== this.id) {
|
|
87
|
+
this.log.warn(`Ignoring snapshot for device ${data.Id} delivered to device ${this.id}`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.data = data;
|
|
91
|
+
this.notifySafely();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Applies an incremental realtime patch to the cached data.
|
|
95
|
+
*/
|
|
96
|
+
handlePatch(patch) {
|
|
97
|
+
if (patch.Id !== this.id) {
|
|
98
|
+
this.log.warn(`Ignoring patch for device ${patch.Id} delivered to device ${this.id}`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
dataPatch(this.data, patch);
|
|
102
|
+
this.notifySafely();
|
|
103
|
+
}
|
|
104
|
+
notifySafely() {
|
|
105
|
+
try {
|
|
106
|
+
this.notify();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// One misbehaving device must never break updates for the others.
|
|
110
|
+
this.log.error(`Error while updating HomeKit state for '${this.name}':`, error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Pushes the current cached state into HomeKit.
|
|
115
|
+
*/
|
|
116
|
+
notify() {
|
|
117
|
+
if (this.batteryService) {
|
|
118
|
+
this.batteryService.updateCharacteristic(this.Characteristic.StatusLowBattery, this.getLowBatteryState());
|
|
119
|
+
this.batteryService.updateCharacteristic(this.Characteristic.BatteryLevel, this.getBatteryLevelValue());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Wraps a HomeKit "set" action with uniform error handling: failures are
|
|
124
|
+
* logged with a helpful message and surfaced to HomeKit as a communication
|
|
125
|
+
* failure rather than crashing the plugin.
|
|
126
|
+
*/
|
|
127
|
+
async runSetAction(description, action) {
|
|
128
|
+
try {
|
|
129
|
+
await action();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
this.log.error(`Failed to ${description} for '${this.name}':`, error instanceof Error ? error.message : error);
|
|
133
|
+
throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Whether this handler manages the given Vivint device. */
|
|
137
|
+
static appliesTo(data) {
|
|
138
|
+
void data;
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
/** The HomeKit accessory category to use when first publishing the accessory. */
|
|
142
|
+
static inferCategory(data, categories) {
|
|
143
|
+
void data;
|
|
144
|
+
return categories.OTHER;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/devices/device.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
2
|
+
import { MultiLevelSwitchBase } from './multiLevelSwitchBase.js';
|
|
3
|
+
export class DimmerSwitch extends MultiLevelSwitchBase {
|
|
4
|
+
static className = 'DimmerSwitch';
|
|
5
|
+
static appliesTo(data) {
|
|
6
|
+
return data.Type === VivintDict.PanelDeviceType.MultiLevelSwitch;
|
|
7
|
+
}
|
|
8
|
+
static inferCategory(data, categories) {
|
|
9
|
+
return categories.SWITCH;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=dimmerSwitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimmerSwitch.js","sourceRoot":"","sources":["../../src/devices/dimmerSwitch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,OAAO,YAAa,SAAQ,oBAAoB;IACpD,MAAM,CAAmB,SAAS,GAAG,cAAc,CAAC;IAEpD,MAAM,CAAU,SAAS,CAAC,IAAgB;QACxC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,eAAe,CAAC,gBAAgB,CAAC;IACnE,CAAC;IAED,MAAM,CAAU,aAAa,CAAC,IAAgB,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { sanitizeDeviceName } from '../utils/sanitizeName.js';
|
|
2
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
3
|
+
import { VivintDevice } from './device.js';
|
|
4
|
+
export class GarageDoor extends VivintDevice {
|
|
5
|
+
static className = 'GarageDoor';
|
|
6
|
+
service;
|
|
7
|
+
constructor(platform, accessory, data) {
|
|
8
|
+
super(platform, accessory, data);
|
|
9
|
+
this.service = this.ensureService(this.Service.GarageDoorOpener, sanitizeDeviceName(this.name, this.id));
|
|
10
|
+
this.service.getCharacteristic(this.Characteristic.CurrentDoorState)
|
|
11
|
+
.onGet(() => this.getGarageDoorCurrentState());
|
|
12
|
+
this.service.getCharacteristic(this.Characteristic.TargetDoorState)
|
|
13
|
+
.onGet(() => this.getGarageDoorTargetState())
|
|
14
|
+
.onSet(value => this.setTargetState(value));
|
|
15
|
+
this.notify();
|
|
16
|
+
}
|
|
17
|
+
async setTargetState(targetState) {
|
|
18
|
+
const closing = targetState === this.Characteristic.TargetDoorState.CLOSED;
|
|
19
|
+
const targetVivintState = closing ? VivintDict.GarageDoorStates.Closing : VivintDict.GarageDoorStates.Opening;
|
|
20
|
+
await this.runSetAction(`${closing ? 'close' : 'open'} the garage door`, () => this.vivintApi.setGarageDoorState(this.id, targetVivintState));
|
|
21
|
+
}
|
|
22
|
+
getGarageDoorCurrentState() {
|
|
23
|
+
switch (this.data.Status) {
|
|
24
|
+
case VivintDict.GarageDoorStates.Unknown: // treat unknown as closed to avoid double notifications
|
|
25
|
+
case VivintDict.GarageDoorStates.Closed:
|
|
26
|
+
return this.Characteristic.CurrentDoorState.CLOSED;
|
|
27
|
+
case VivintDict.GarageDoorStates.Closing:
|
|
28
|
+
return this.Characteristic.CurrentDoorState.CLOSING;
|
|
29
|
+
case VivintDict.GarageDoorStates.Opening:
|
|
30
|
+
return this.Characteristic.CurrentDoorState.OPENING;
|
|
31
|
+
case VivintDict.GarageDoorStates.Opened:
|
|
32
|
+
return this.Characteristic.CurrentDoorState.OPEN;
|
|
33
|
+
default:
|
|
34
|
+
return this.Characteristic.CurrentDoorState.STOPPED;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
getGarageDoorTargetState() {
|
|
38
|
+
switch (this.data.Status) {
|
|
39
|
+
case VivintDict.GarageDoorStates.Opening:
|
|
40
|
+
case VivintDict.GarageDoorStates.Opened:
|
|
41
|
+
return this.Characteristic.TargetDoorState.OPEN;
|
|
42
|
+
default:
|
|
43
|
+
return this.Characteristic.TargetDoorState.CLOSED;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
notify() {
|
|
47
|
+
super.notify();
|
|
48
|
+
this.service.updateCharacteristic(this.Characteristic.CurrentDoorState, this.getGarageDoorCurrentState());
|
|
49
|
+
this.service.updateCharacteristic(this.Characteristic.TargetDoorState, this.getGarageDoorTargetState());
|
|
50
|
+
}
|
|
51
|
+
static appliesTo(data) {
|
|
52
|
+
return data.Type === VivintDict.PanelDeviceType.GarageDoor;
|
|
53
|
+
}
|
|
54
|
+
static inferCategory(data, categories) {
|
|
55
|
+
return categories.GARAGE_DOOR_OPENER;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=garageDoor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"garageDoor.js","sourceRoot":"","sources":["../../src/devices/garageDoor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,OAAO,UAAW,SAAQ,YAAY;IAC1C,MAAM,CAAmB,SAAS,GAAG,YAAY,CAAC;IAEjC,OAAO,CAAU;IAElC,YAAY,QAAwB,EAAE,SAAoD,EAAE,IAA4B;QACtH,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC;aACjE,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;aAChE,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC;aAC5C,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAgC;QAC3D,MAAM,OAAO,GAAG,WAAW,KAAK,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,MAAM,CAAC;QAC3E,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC9G,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,kBAAkB,EAAE,GAAG,EAAE,CAC5E,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,yBAAyB;QACvB,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3B,KAAK,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,wDAAwD;YAClG,KAAK,UAAU,CAAC,gBAAgB,CAAC,MAAM;gBACrC,OAAO,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,MAAM,CAAC;YACrD,KAAK,UAAU,CAAC,gBAAgB,CAAC,OAAO;gBACtC,OAAO,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACtD,KAAK,UAAU,CAAC,gBAAgB,CAAC,OAAO;gBACtC,OAAO,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACtD,KAAK,UAAU,CAAC,gBAAgB,CAAC,MAAM;gBACrC,OAAO,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACnD;gBACE,OAAO,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC;QACtD,CAAC;IACH,CAAC;IAED,wBAAwB;QACtB,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3B,KAAK,UAAU,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACzC,KAAK,UAAU,CAAC,gBAAgB,CAAC,MAAM;gBACrC,OAAO,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC;YAClD;gBACE,OAAO,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,MAAM,CAAC;QACpD,CAAC;IACH,CAAC;IAEQ,MAAM;QACb,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,EAAE,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC1G,CAAC;IAED,MAAM,CAAU,SAAS,CAAC,IAAgB;QACxC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC;IAC7D,CAAC;IAED,MAAM,CAAU,aAAa,CAAC,IAAgB,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,kBAAkB,CAAC;IACvC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Camera } from './camera.js';
|
|
2
|
+
import { CarbonMonoxideSensor } from './carbonMonoxideSensor.js';
|
|
3
|
+
import { ContactSensor } from './contactSensor.js';
|
|
4
|
+
import { VivintDevice } from './device.js';
|
|
5
|
+
import { DimmerSwitch } from './dimmerSwitch.js';
|
|
6
|
+
import { GarageDoor } from './garageDoor.js';
|
|
7
|
+
import { LightGroup } from './lightGroup.js';
|
|
8
|
+
import { LightSwitch } from './lightSwitch.js';
|
|
9
|
+
import { Lock } from './lock.js';
|
|
10
|
+
import { MotionSensor } from './motionSensor.js';
|
|
11
|
+
import { Panel } from './panel.js';
|
|
12
|
+
import { SmokeSensor } from './smokeSensor.js';
|
|
13
|
+
import { Thermostat } from './thermostat.js';
|
|
14
|
+
export { VivintDevice };
|
|
15
|
+
/**
|
|
16
|
+
* All supported device handlers, in matching priority order.
|
|
17
|
+
*/
|
|
18
|
+
export const DEVICE_HANDLERS = [
|
|
19
|
+
ContactSensor,
|
|
20
|
+
SmokeSensor,
|
|
21
|
+
CarbonMonoxideSensor,
|
|
22
|
+
MotionSensor,
|
|
23
|
+
Lock,
|
|
24
|
+
Thermostat,
|
|
25
|
+
GarageDoor,
|
|
26
|
+
Panel,
|
|
27
|
+
Camera,
|
|
28
|
+
LightSwitch,
|
|
29
|
+
DimmerSwitch,
|
|
30
|
+
LightGroup,
|
|
31
|
+
];
|
|
32
|
+
export function findHandlerForData(data) {
|
|
33
|
+
return DEVICE_HANDLERS.find(handler => handler.appliesTo(data));
|
|
34
|
+
}
|
|
35
|
+
export function findHandlerByClassName(className) {
|
|
36
|
+
return DEVICE_HANDLERS.find(handler => handler.className === className);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Device types that exist in the Vivint snapshot but have no HomeKit purpose.
|
|
40
|
+
* They are silently skipped instead of being reported as unsupported.
|
|
41
|
+
*/
|
|
42
|
+
export const IRRELEVANT_DEVICE_TYPES = [
|
|
43
|
+
'sensor_group',
|
|
44
|
+
'network_hosts_service',
|
|
45
|
+
'panel_diagnostics_service',
|
|
46
|
+
'iot_service',
|
|
47
|
+
'scheduler_service',
|
|
48
|
+
'yofi_device',
|
|
49
|
+
'keyfob_device',
|
|
50
|
+
'control4_device',
|
|
51
|
+
'lgit_poe_wifi_bridge_device',
|
|
52
|
+
'mqtt_audio_sync_service',
|
|
53
|
+
'holiday_theme_service',
|
|
54
|
+
];
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/devices/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,CAAC;AAaxB;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAyB;IACnD,aAAa;IACb,WAAW;IACX,oBAAoB;IACpB,YAAY;IACZ,IAAI;IACJ,UAAU;IACV,UAAU;IACV,KAAK;IACL,MAAM;IACN,WAAW;IACX,YAAY;IACZ,UAAU;CACX,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,IAAgB;IACjD,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,cAAc;IACd,uBAAuB;IACvB,2BAA2B;IAC3B,aAAa;IACb,mBAAmB;IACnB,aAAa;IACb,eAAe;IACf,iBAAiB;IACjB,6BAA6B;IAC7B,yBAAyB;IACzB,uBAAuB;CACxB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
2
|
+
import { MultiLevelSwitchBase } from './multiLevelSwitchBase.js';
|
|
3
|
+
export class LightGroup extends MultiLevelSwitchBase {
|
|
4
|
+
static className = 'LightGroup';
|
|
5
|
+
static appliesTo(data) {
|
|
6
|
+
return data.Type === VivintDict.PanelDeviceType.GroupDevices
|
|
7
|
+
&& Array.isArray(data.panel_capability_types)
|
|
8
|
+
&& data.panel_capability_types.includes(VivintDict.PanelCapabilityType.Dimmable)
|
|
9
|
+
&& data.panel_capability_types.includes(VivintDict.PanelCapabilityType.GroupDevices);
|
|
10
|
+
}
|
|
11
|
+
static inferCategory(data, categories) {
|
|
12
|
+
return categories.SWITCH;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=lightGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightGroup.js","sourceRoot":"","sources":["../../src/devices/lightGroup.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,OAAO,UAAW,SAAQ,oBAAoB;IAClD,MAAM,CAAmB,SAAS,GAAG,YAAY,CAAC;IAElD,MAAM,CAAU,SAAS,CAAC,IAAgB;QACxC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,eAAe,CAAC,YAAY;eACvD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC;eAC1C,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,QAAQ,CAAC;eAC7E,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,CAAU,aAAa,CAAC,IAAgB,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { sanitizeDeviceName } from '../utils/sanitizeName.js';
|
|
2
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
3
|
+
import { VivintDevice } from './device.js';
|
|
4
|
+
/**
|
|
5
|
+
* Binary Z-Wave switch. Exposed as a lightbulb, fan or plain switch depending
|
|
6
|
+
* on the device name.
|
|
7
|
+
*/
|
|
8
|
+
export class LightSwitch extends VivintDevice {
|
|
9
|
+
static className = 'LightSwitch';
|
|
10
|
+
service;
|
|
11
|
+
constructor(platform, accessory, data) {
|
|
12
|
+
super(platform, accessory, data);
|
|
13
|
+
const sanitizedName = sanitizeDeviceName(this.name, this.id);
|
|
14
|
+
if (this.name.match(/\blight\b/i)) {
|
|
15
|
+
this.service = this.ensureService(this.Service.Lightbulb, sanitizedName);
|
|
16
|
+
}
|
|
17
|
+
else if (this.name.match(/\bfan\b/i)) {
|
|
18
|
+
this.service = this.ensureService(this.Service.Fan, sanitizedName);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
this.service = this.ensureService(this.Service.Switch, sanitizedName);
|
|
22
|
+
}
|
|
23
|
+
this.service.getCharacteristic(this.Characteristic.On)
|
|
24
|
+
.onGet(() => Boolean(this.data.Status))
|
|
25
|
+
.onSet(value => this.setSwitchState(value));
|
|
26
|
+
}
|
|
27
|
+
async setSwitchState(targetState) {
|
|
28
|
+
const on = Boolean(targetState);
|
|
29
|
+
await this.runSetAction(`turn the switch ${on ? 'on' : 'off'}`, () => this.vivintApi.putDevice('switches', this.id, { s: on, _id: this.id }));
|
|
30
|
+
}
|
|
31
|
+
notify() {
|
|
32
|
+
super.notify();
|
|
33
|
+
this.service.updateCharacteristic(this.Characteristic.On, this.data.Value !== 0);
|
|
34
|
+
}
|
|
35
|
+
static appliesTo(data) {
|
|
36
|
+
return data.Type === VivintDict.PanelDeviceType.BinarySwitch;
|
|
37
|
+
}
|
|
38
|
+
static inferCategory(data, categories) {
|
|
39
|
+
return categories.SWITCH;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=lightSwitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightSwitch.js","sourceRoot":"","sources":["../../src/devices/lightSwitch.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAC3C,MAAM,CAAmB,SAAS,GAAG,aAAa,CAAC;IAElC,OAAO,CAAU;IAElC,YAAY,QAAwB,EAAE,SAAoD,EAAE,IAA4B;QACtH,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAEjC,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;aACnD,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACtC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAgC;QAC3D,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CACnE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5E,CAAC;IAEQ,MAAM;QACb,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,CAAU,SAAS,CAAC,IAAgB;QACxC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,eAAe,CAAC,YAAY,CAAC;IAC/D,CAAC;IAED,MAAM,CAAU,aAAa,CAAC,IAAgB,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { sanitizeDeviceName } from '../utils/sanitizeName.js';
|
|
2
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
3
|
+
import { VivintDevice } from './device.js';
|
|
4
|
+
export class Lock extends VivintDevice {
|
|
5
|
+
static className = 'Lock';
|
|
6
|
+
static hasBattery = true;
|
|
7
|
+
service;
|
|
8
|
+
constructor(platform, accessory, data) {
|
|
9
|
+
super(platform, accessory, data);
|
|
10
|
+
this.service = this.ensureService(this.Service.LockMechanism, sanitizeDeviceName(this.name, this.id));
|
|
11
|
+
this.batteryService?.updateCharacteristic(this.Characteristic.ChargingState, this.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
12
|
+
this.service.getCharacteristic(this.Characteristic.LockCurrentState)
|
|
13
|
+
.onGet(() => this.getLockState());
|
|
14
|
+
this.service.getCharacteristic(this.Characteristic.LockTargetState)
|
|
15
|
+
.onSet(value => this.setTargetState(value));
|
|
16
|
+
this.notify();
|
|
17
|
+
}
|
|
18
|
+
async setTargetState(targetState) {
|
|
19
|
+
const locked = targetState === this.Characteristic.LockTargetState.SECURED;
|
|
20
|
+
await this.runSetAction(`set lock state to ${locked ? 'locked' : 'unlocked'}`, () => this.vivintApi.setLockState(this.id, locked));
|
|
21
|
+
}
|
|
22
|
+
getLockState() {
|
|
23
|
+
switch (this.data.Status) {
|
|
24
|
+
case false:
|
|
25
|
+
return this.Characteristic.LockCurrentState.UNSECURED;
|
|
26
|
+
case true:
|
|
27
|
+
return this.Characteristic.LockCurrentState.SECURED;
|
|
28
|
+
case this.Characteristic.LockCurrentState.JAMMED:
|
|
29
|
+
return this.Characteristic.LockCurrentState.JAMMED;
|
|
30
|
+
default:
|
|
31
|
+
return this.Characteristic.LockCurrentState.UNKNOWN;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
notify() {
|
|
35
|
+
super.notify();
|
|
36
|
+
const state = this.getLockState();
|
|
37
|
+
this.service.updateCharacteristic(this.Characteristic.LockCurrentState, state);
|
|
38
|
+
this.service.updateCharacteristic(this.Characteristic.LockTargetState, state === this.Characteristic.LockCurrentState.SECURED
|
|
39
|
+
? this.Characteristic.LockTargetState.SECURED
|
|
40
|
+
: this.Characteristic.LockTargetState.UNSECURED);
|
|
41
|
+
}
|
|
42
|
+
static appliesTo(data) {
|
|
43
|
+
return data.Type === VivintDict.PanelDeviceType.DoorLock;
|
|
44
|
+
}
|
|
45
|
+
static inferCategory(data, categories) {
|
|
46
|
+
return categories.DOOR_LOCK;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/devices/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { sanitizeDeviceName } from '../utils/sanitizeName.js';
|
|
2
|
+
import { VivintDict } from '../vivint/dictionary.js';
|
|
3
|
+
import { VivintDevice } from './device.js';
|
|
4
|
+
const EQUIPMENT_CODES = [
|
|
5
|
+
'PIR1_MOTION',
|
|
6
|
+
'PIR2_MOTION',
|
|
7
|
+
'EXISTING_MOTION_DETECTOR',
|
|
8
|
+
].map(name => VivintDict.EquipmentCode[name]);
|
|
9
|
+
export class MotionSensor extends VivintDevice {
|
|
10
|
+
static className = 'MotionSensor';
|
|
11
|
+
static hasBattery = true;
|
|
12
|
+
service;
|
|
13
|
+
occupancyService;
|
|
14
|
+
occupancyTimeoutMs;
|
|
15
|
+
lastSensedMotion;
|
|
16
|
+
occupancyTimer;
|
|
17
|
+
constructor(platform, accessory, data) {
|
|
18
|
+
super(platform, accessory, data);
|
|
19
|
+
const sanitizedName = sanitizeDeviceName(this.name, this.id);
|
|
20
|
+
this.occupancyTimeoutMs = (this.config.motionDetectedOccupancySensorMins ?? 0) * 60 * 1000;
|
|
21
|
+
this.service = this.ensureService(this.Service.MotionSensor, sanitizedName);
|
|
22
|
+
this.batteryService?.updateCharacteristic(this.Characteristic.ChargingState, this.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
23
|
+
this.service.getCharacteristic(this.Characteristic.MotionDetected)
|
|
24
|
+
.onGet(() => this.getMotionDetectedState());
|
|
25
|
+
this.service.getCharacteristic(this.Characteristic.StatusTampered)
|
|
26
|
+
.onGet(() => this.getTamperedState());
|
|
27
|
+
if (this.occupancyTimeoutMs > 0) {
|
|
28
|
+
this.occupancyService = this.ensureService(this.Service.OccupancySensor, `${sanitizedName} Occupancy`);
|
|
29
|
+
this.occupancyService.getCharacteristic(this.Characteristic.OccupancyDetected)
|
|
30
|
+
.onGet(() => this.getOccupancyState());
|
|
31
|
+
this.occupancyTimer = setInterval(() => this.notifyOccupancy(), 60 * 1000);
|
|
32
|
+
this.occupancyTimer.unref();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// The occupancy sensor was disabled in the config; drop a stale service
|
|
36
|
+
// left over on the cached accessory.
|
|
37
|
+
const stale = accessory.getService(this.Service.OccupancySensor);
|
|
38
|
+
if (stale) {
|
|
39
|
+
accessory.removeService(stale);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
this.notify();
|
|
43
|
+
}
|
|
44
|
+
getOccupancyState() {
|
|
45
|
+
if (this.lastSensedMotion !== undefined && Date.now() - this.lastSensedMotion < this.occupancyTimeoutMs) {
|
|
46
|
+
return this.Characteristic.OccupancyDetected.OCCUPANCY_DETECTED;
|
|
47
|
+
}
|
|
48
|
+
return this.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED;
|
|
49
|
+
}
|
|
50
|
+
getMotionDetectedState() {
|
|
51
|
+
return Boolean(this.data.Status);
|
|
52
|
+
}
|
|
53
|
+
notifyOccupancy() {
|
|
54
|
+
this.occupancyService?.updateCharacteristic(this.Characteristic.OccupancyDetected, this.getOccupancyState());
|
|
55
|
+
}
|
|
56
|
+
notify() {
|
|
57
|
+
super.notify();
|
|
58
|
+
if (this.getMotionDetectedState()) {
|
|
59
|
+
this.lastSensedMotion = Date.now();
|
|
60
|
+
}
|
|
61
|
+
this.service.updateCharacteristic(this.Characteristic.MotionDetected, this.getMotionDetectedState());
|
|
62
|
+
this.service.updateCharacteristic(this.Characteristic.StatusTampered, this.getTamperedState());
|
|
63
|
+
this.notifyOccupancy();
|
|
64
|
+
}
|
|
65
|
+
static appliesTo(data) {
|
|
66
|
+
return data.Type === VivintDict.PanelDeviceType.WirelessSensor
|
|
67
|
+
&& EQUIPMENT_CODES.includes(data.EquipmentCode);
|
|
68
|
+
}
|
|
69
|
+
static inferCategory(data, categories) {
|
|
70
|
+
return categories.SENSOR;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=motionSensor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motionSensor.js","sourceRoot":"","sources":["../../src/devices/motionSensor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { debounceLeading } from '../utils/debounce.js';
|
|
2
|
+
import { sanitizeDeviceName } from '../utils/sanitizeName.js';
|
|
3
|
+
import { VivintDevice } from './device.js';
|
|
4
|
+
const BRIGHTNESS_DEBOUNCE_MS = 500;
|
|
5
|
+
/**
|
|
6
|
+
* Shared behavior for dimmable devices (dimmer switches and Philips Hue light
|
|
7
|
+
* groups). Exposed as a fan with rotation speed when the device name contains
|
|
8
|
+
* "fan", otherwise as a dimmable lightbulb.
|
|
9
|
+
*/
|
|
10
|
+
export class MultiLevelSwitchBase extends VivintDevice {
|
|
11
|
+
service;
|
|
12
|
+
isFan;
|
|
13
|
+
lastOnState;
|
|
14
|
+
lastLevel;
|
|
15
|
+
setLevelDebounced;
|
|
16
|
+
constructor(platform, accessory, data) {
|
|
17
|
+
super(platform, accessory, data);
|
|
18
|
+
const sanitizedName = sanitizeDeviceName(this.name, this.id);
|
|
19
|
+
this.isFan = Boolean(this.name.match(/\bfan\b/i));
|
|
20
|
+
this.service = this.isFan
|
|
21
|
+
? this.ensureService(this.Service.Fan, sanitizedName)
|
|
22
|
+
: this.ensureService(this.Service.Lightbulb, sanitizedName);
|
|
23
|
+
this.service.getCharacteristic(this.Characteristic.On)
|
|
24
|
+
.onGet(() => Boolean(this.data.Status))
|
|
25
|
+
.onSet(value => this.setSwitchState(value));
|
|
26
|
+
// Dragging the brightness/speed slider produces a burst of set requests;
|
|
27
|
+
// debounce them so only the first and final values reach the Vivint API.
|
|
28
|
+
this.setLevelDebounced = debounceLeading((level) => this.vivintApi.putDevice('switches', this.id, { val: level, _id: this.id }), BRIGHTNESS_DEBOUNCE_MS);
|
|
29
|
+
const levelCharacteristic = this.isFan ? this.Characteristic.RotationSpeed : this.Characteristic.Brightness;
|
|
30
|
+
this.service.getCharacteristic(levelCharacteristic)
|
|
31
|
+
.onGet(() => this.data.Value ?? 0)
|
|
32
|
+
.onSet(value => this.setLevel(value));
|
|
33
|
+
}
|
|
34
|
+
async setSwitchState(targetState) {
|
|
35
|
+
const on = Boolean(targetState);
|
|
36
|
+
await this.runSetAction(`turn ${on ? 'on' : 'off'}`, () => this.vivintApi.putDevice('switches', this.id, { s: on, _id: this.id }));
|
|
37
|
+
}
|
|
38
|
+
async setLevel(value) {
|
|
39
|
+
await this.runSetAction(`set the level to ${value}`, () => this.setLevelDebounced(value));
|
|
40
|
+
}
|
|
41
|
+
notify() {
|
|
42
|
+
super.notify();
|
|
43
|
+
// Vivint typically sends each change twice; only push actual changes.
|
|
44
|
+
if (this.data.Value !== this.lastLevel) {
|
|
45
|
+
this.lastLevel = this.data.Value;
|
|
46
|
+
const levelCharacteristic = this.isFan ? this.Characteristic.RotationSpeed : this.Characteristic.Brightness;
|
|
47
|
+
this.service.updateCharacteristic(levelCharacteristic, this.data.Value ?? 0);
|
|
48
|
+
}
|
|
49
|
+
if (this.data.Status !== this.lastOnState) {
|
|
50
|
+
this.lastOnState = this.data.Status;
|
|
51
|
+
this.service.updateCharacteristic(this.Characteristic.On, Boolean(this.data.Status));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=multiLevelSwitchBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multiLevelSwitchBase.js","sourceRoot":"","sources":["../../src/devices/multiLevelSwitchBase.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC;;;;GAIG;AACH,MAAM,OAAgB,oBAAqB,SAAQ,YAAY;IAC1C,OAAO,CAAU;IACnB,KAAK,CAAU;IACxB,WAAW,CAAW;IACtB,SAAS,CAAU;IACV,iBAAiB,CAAmC;IAErE,YAAY,QAAwB,EAAE,SAAoD,EAAE,IAA4B;QACtH,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAEjC,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK;YACvB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC;YACrD,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAE9D,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;aACnD,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACtC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAE9C,yEAAyE;QACzE,yEAAyE;QACzE,IAAI,CAAC,iBAAiB,GAAG,eAAe,CACtC,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAC9F,sBAAsB,CACvB,CAAC;QAEF,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAC5G,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,mBAAmB,CAAC;aAChD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;aACjC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAgC;QAC3D,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CACxD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5E,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,KAA0B;QAC/C,MAAM,IAAI,CAAC,YAAY,CAAC,oBAAoB,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAe,CAAC,CAAC,CAAC;IACtG,CAAC;IAEQ,MAAM;QACb,KAAK,CAAC,MAAM,EAAE,CAAC;QAEf,sEAAsE;QACtE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;YAC5G,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QAC/E,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;CACF"}
|