@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.
Files changed (62) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +107 -0
  3. package/config.schema.json +90 -0
  4. package/dist/devices/camera.js +368 -0
  5. package/dist/devices/camera.js.map +1 -0
  6. package/dist/devices/carbonMonoxideSensor.js +44 -0
  7. package/dist/devices/carbonMonoxideSensor.js.map +1 -0
  8. package/dist/devices/contactSensor.js +65 -0
  9. package/dist/devices/contactSensor.js.map +1 -0
  10. package/dist/devices/device.js +147 -0
  11. package/dist/devices/device.js.map +1 -0
  12. package/dist/devices/dimmerSwitch.js +12 -0
  13. package/dist/devices/dimmerSwitch.js.map +1 -0
  14. package/dist/devices/garageDoor.js +58 -0
  15. package/dist/devices/garageDoor.js.map +1 -0
  16. package/dist/devices/index.js +55 -0
  17. package/dist/devices/index.js.map +1 -0
  18. package/dist/devices/lightGroup.js +15 -0
  19. package/dist/devices/lightGroup.js.map +1 -0
  20. package/dist/devices/lightSwitch.js +42 -0
  21. package/dist/devices/lightSwitch.js.map +1 -0
  22. package/dist/devices/lock.js +49 -0
  23. package/dist/devices/lock.js.map +1 -0
  24. package/dist/devices/motionSensor.js +73 -0
  25. package/dist/devices/motionSensor.js.map +1 -0
  26. package/dist/devices/multiLevelSwitchBase.js +55 -0
  27. package/dist/devices/multiLevelSwitchBase.js.map +1 -0
  28. package/dist/devices/panel.js +79 -0
  29. package/dist/devices/panel.js.map +1 -0
  30. package/dist/devices/smokeSensor.js +47 -0
  31. package/dist/devices/smokeSensor.js.map +1 -0
  32. package/dist/devices/thermostat.js +216 -0
  33. package/dist/devices/thermostat.js.map +1 -0
  34. package/dist/homebridge-ui/public/index.html +138 -0
  35. package/dist/homebridge-ui/server.js +120 -0
  36. package/dist/homebridge-ui/server.js.map +1 -0
  37. package/dist/index.js +9 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/platform.js +393 -0
  40. package/dist/platform.js.map +1 -0
  41. package/dist/settings.js +12 -0
  42. package/dist/settings.js.map +1 -0
  43. package/dist/types.js +2 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/utils/debounce.js +49 -0
  46. package/dist/utils/debounce.js.map +1 -0
  47. package/dist/utils/ports.js +39 -0
  48. package/dist/utils/ports.js.map +1 -0
  49. package/dist/utils/redact.js +19 -0
  50. package/dist/utils/redact.js.map +1 -0
  51. package/dist/utils/sanitizeName.js +22 -0
  52. package/dist/utils/sanitizeName.js.map +1 -0
  53. package/dist/vivint/api.js +246 -0
  54. package/dist/vivint/api.js.map +1 -0
  55. package/dist/vivint/datapatch.js +52 -0
  56. package/dist/vivint/datapatch.js.map +1 -0
  57. package/dist/vivint/dictionary.js +66 -0
  58. package/dist/vivint/dictionary.js.map +1 -0
  59. package/dist/vivint/eventStream.js +77 -0
  60. package/dist/vivint/eventStream.js.map +1 -0
  61. package/dist/vivint/vivint_dictionary.json +8720 -0
  62. package/package.json +62 -0
@@ -0,0 +1,79 @@
1
+ import { sanitizeDeviceName } from '../utils/sanitizeName.js';
2
+ import { VivintDict } from '../vivint/dictionary.js';
3
+ import { VivintDevice } from './device.js';
4
+ export class Panel extends VivintDevice {
5
+ static className = 'Panel';
6
+ static hasBattery = true;
7
+ service;
8
+ vivintToHomekit;
9
+ homekitToVivint;
10
+ constructor(platform, accessory, data) {
11
+ super(platform, accessory, data);
12
+ this.service = this.ensureService(this.Service.SecuritySystem, sanitizeDeviceName(this.name, this.id));
13
+ const CurrentState = this.Characteristic.SecuritySystemCurrentState;
14
+ const TargetState = this.Characteristic.SecuritySystemTargetState;
15
+ this.vivintToHomekit = {
16
+ [VivintDict.SecurityState.DISARMED]: CurrentState.DISARMED,
17
+ [VivintDict.SecurityState.ARMING_AWAY_IN_EXIT_DELAY]: CurrentState.AWAY_ARM,
18
+ [VivintDict.SecurityState.ARMING_STAY_IN_EXIT_DELAY]: CurrentState.STAY_ARM,
19
+ [VivintDict.SecurityState.ARMED_STAY]: CurrentState.STAY_ARM,
20
+ [VivintDict.SecurityState.ARMED_AWAY]: CurrentState.AWAY_ARM,
21
+ [VivintDict.SecurityState.ARMED_STAY_IN_ENTRY_DELAY]: CurrentState.STAY_ARM,
22
+ [VivintDict.SecurityState.ARMED_AWAY_IN_ENTRY_DELAY]: CurrentState.AWAY_ARM,
23
+ [VivintDict.SecurityState.ALARM]: CurrentState.ALARM_TRIGGERED,
24
+ [VivintDict.SecurityState.ALARM_FIRE]: CurrentState.ALARM_TRIGGERED,
25
+ [VivintDict.SecurityState.DISABLED]: CurrentState.DISARMED,
26
+ [VivintDict.SecurityState.WALK_TEST]: CurrentState.DISARMED,
27
+ };
28
+ this.homekitToVivint = {
29
+ [TargetState.DISARM]: VivintDict.SecurityState.DISARMED,
30
+ [TargetState.STAY_ARM]: VivintDict.SecurityState.ARMED_STAY,
31
+ [TargetState.AWAY_ARM]: VivintDict.SecurityState.ARMED_AWAY,
32
+ };
33
+ this.service.getCharacteristic(CurrentState)
34
+ .setProps({
35
+ validValues: [CurrentState.STAY_ARM, CurrentState.AWAY_ARM, CurrentState.DISARMED, CurrentState.ALARM_TRIGGERED],
36
+ })
37
+ .onGet(() => this.getPanelState());
38
+ this.service.getCharacteristic(TargetState)
39
+ .setProps({
40
+ validValues: [TargetState.STAY_ARM, TargetState.AWAY_ARM, TargetState.DISARM],
41
+ })
42
+ .onSet(value => this.setTargetState(value));
43
+ }
44
+ getPanelState() {
45
+ const mapped = this.vivintToHomekit[this.data.Status];
46
+ return mapped ?? this.Characteristic.SecuritySystemCurrentState.DISARMED;
47
+ }
48
+ async setTargetState(targetState) {
49
+ const TargetState = this.Characteristic.SecuritySystemTargetState;
50
+ const vivintState = this.homekitToVivint[targetState];
51
+ await this.runSetAction('set the alarm panel state', async () => {
52
+ // Vivint does not support switching directly between Stay and Away,
53
+ // so disarm first when changing between armed modes.
54
+ if (targetState !== TargetState.DISARM
55
+ && this.getPanelState() !== this.Characteristic.SecuritySystemCurrentState.DISARMED) {
56
+ await this.vivintApi.setPanelState(this.homekitToVivint[TargetState.DISARM]);
57
+ }
58
+ await this.vivintApi.setPanelState(vivintState);
59
+ });
60
+ }
61
+ notify() {
62
+ super.notify();
63
+ if (this.data.Status === undefined) {
64
+ return;
65
+ }
66
+ const state = this.getPanelState();
67
+ this.service.updateCharacteristic(this.Characteristic.SecuritySystemCurrentState, state);
68
+ if (state !== this.Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED) {
69
+ this.service.updateCharacteristic(this.Characteristic.SecuritySystemTargetState, state);
70
+ }
71
+ }
72
+ static appliesTo(data) {
73
+ return data.Type === VivintDict.PanelDeviceType.Panel;
74
+ }
75
+ static inferCategory(data, categories) {
76
+ return categories.SECURITY_SYSTEM;
77
+ }
78
+ }
79
+ //# sourceMappingURL=panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel.js","sourceRoot":"","sources":["../../src/devices/panel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
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
+ 'FIREFIGHTER_AUDIO_DETECTOR',
6
+ 'HW_SMOKE_5808W3',
7
+ 'EXISTING_SMOKE',
8
+ 'SMKE1_SMOKE_CANADA',
9
+ 'SMKE1_SMOKE',
10
+ 'VS_SMKT_SMOKE_DETECTOR',
11
+ 'SMKT2_GE_SMOKE_HEAT',
12
+ 'SMKT3_2GIG',
13
+ 'SMKT6_2GIG',
14
+ ].map(name => VivintDict.EquipmentCode[name]);
15
+ export class SmokeSensor extends VivintDevice {
16
+ static className = 'SmokeSensor';
17
+ static hasBattery = true;
18
+ service;
19
+ constructor(platform, accessory, data) {
20
+ super(platform, accessory, data);
21
+ this.service = this.ensureService(this.Service.SmokeSensor, sanitizeDeviceName(this.name, this.id));
22
+ this.batteryService?.updateCharacteristic(this.Characteristic.ChargingState, this.Characteristic.ChargingState.NOT_CHARGEABLE);
23
+ this.service.getCharacteristic(this.Characteristic.SmokeDetected)
24
+ .onGet(() => this.getSensorState());
25
+ this.service.getCharacteristic(this.Characteristic.StatusTampered)
26
+ .onGet(() => this.getTamperedState());
27
+ this.notify();
28
+ }
29
+ getSensorState() {
30
+ return this.data.Status
31
+ ? this.Characteristic.SmokeDetected.SMOKE_DETECTED
32
+ : this.Characteristic.SmokeDetected.SMOKE_NOT_DETECTED;
33
+ }
34
+ notify() {
35
+ super.notify();
36
+ this.service.updateCharacteristic(this.Characteristic.SmokeDetected, this.getSensorState());
37
+ this.service.updateCharacteristic(this.Characteristic.StatusTampered, this.getTamperedState());
38
+ }
39
+ static appliesTo(data) {
40
+ return data.Type === VivintDict.PanelDeviceType.WirelessSensor
41
+ && EQUIPMENT_CODES.includes(data.EquipmentCode);
42
+ }
43
+ static inferCategory(data, categories) {
44
+ return categories.SENSOR;
45
+ }
46
+ }
47
+ //# sourceMappingURL=smokeSensor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smokeSensor.js","sourceRoot":"","sources":["../../src/devices/smokeSensor.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,eAAe,GAAG;IACtB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,oBAAoB;IACpB,aAAa;IACb,wBAAwB;IACxB,qBAAqB;IACrB,YAAY;IACZ,YAAY;CACb,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AAE9C,MAAM,OAAO,WAAY,SAAQ,YAAY;IAC3C,MAAM,CAAmB,SAAS,GAAG,aAAa,CAAC;IACnD,MAAM,CAAmB,UAAU,GAAG,IAAI,CAAC;IAE1B,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,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACpG,IAAI,CAAC,cAAc,EAAE,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;QAE/H,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC;aAC9D,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;aAC/D,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAExC,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YACrB,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,cAAc;YAClD,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,kBAAkB,CAAC;IAC3D,CAAC;IAEQ,MAAM;QACb,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAC5F,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,CAAU,SAAS,CAAC,IAAgB;QACxC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,eAAe,CAAC,cAAc;eACzD,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAuB,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,CAAU,aAAa,CAAC,IAAgB,EAAE,UAAyB;QACvE,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC"}
@@ -0,0 +1,216 @@
1
+ import { debounceLeading } from '../utils/debounce.js';
2
+ import { sanitizeDeviceName } from '../utils/sanitizeName.js';
3
+ import { VivintDict } from '../vivint/dictionary.js';
4
+ import { VivintDevice } from './device.js';
5
+ const SET_POINT_DEBOUNCE_MS = 2000;
6
+ export class Thermostat extends VivintDevice {
7
+ static className = 'Thermostat';
8
+ service;
9
+ fanService;
10
+ setHeatSetPointDebounced;
11
+ setCoolSetPointDebounced;
12
+ constructor(platform, accessory, data) {
13
+ super(platform, accessory, data);
14
+ const sanitizedName = sanitizeDeviceName(this.name, this.id);
15
+ this.service = this.ensureService(this.Service.Thermostat, sanitizedName);
16
+ this.fanService = this.ensureService(this.Service.Fan, `${sanitizedName} fan`);
17
+ this.setHeatSetPointDebounced = debounceLeading((temperature) => this.vivintApi.setThermostatHeatSetPoint(this.id, temperature), SET_POINT_DEBOUNCE_MS);
18
+ this.setCoolSetPointDebounced = debounceLeading((temperature) => this.vivintApi.setThermostatCoolSetPoint(this.id, temperature), SET_POINT_DEBOUNCE_MS);
19
+ /*
20
+ * Only allow small increments for Celsius temperatures. HomeKit is already
21
+ * limited to 1-degree increments in Fahrenheit, and a coarser step for
22
+ * Fahrenheit causes HomeKit to round incorrectly when converting °F <-> °C.
23
+ */
24
+ let minSetTemp, maxSetTemp, minGetTemp, maxGetTemp;
25
+ const tempStep = 0.1;
26
+ if (this.isCelsius()) {
27
+ minSetTemp = 10;
28
+ maxSetTemp = 32;
29
+ minGetTemp = -20;
30
+ maxGetTemp = 60;
31
+ }
32
+ else {
33
+ minSetTemp = this.fahrenheitToCelsius(50);
34
+ maxSetTemp = this.fahrenheitToCelsius(90);
35
+ minGetTemp = this.fahrenheitToCelsius(0);
36
+ maxGetTemp = this.fahrenheitToCelsius(160);
37
+ }
38
+ this.service.getCharacteristic(this.Characteristic.CurrentHeatingCoolingState)
39
+ .onGet(() => this.getOperatingState());
40
+ this.service.getCharacteristic(this.Characteristic.TargetHeatingCoolingState)
41
+ .onGet(() => this.getOperatingMode())
42
+ .onSet(value => this.setTargetHeatingCoolingState(value));
43
+ this.service.getCharacteristic(this.Characteristic.CurrentTemperature)
44
+ .setProps({ minStep: tempStep, minValue: minGetTemp, maxValue: maxGetTemp })
45
+ .onGet(() => this.getTemperatureValue());
46
+ this.service.getCharacteristic(this.Characteristic.TargetTemperature)
47
+ .setProps({ minStep: tempStep, minValue: minSetTemp, maxValue: maxSetTemp })
48
+ .onGet(() => this.getTargetTemperatureValue())
49
+ .onSet(value => this.setTargetTemperature(value));
50
+ this.service.getCharacteristic(this.Characteristic.CurrentRelativeHumidity)
51
+ .onGet(() => this.getHumidityValue());
52
+ this.service.getCharacteristic(this.Characteristic.CoolingThresholdTemperature)
53
+ .setProps({ minStep: tempStep, minValue: minSetTemp, maxValue: maxSetTemp })
54
+ .onGet(() => this.getCoolingThresholdTemperatureValue())
55
+ .onSet(value => this.setCoolingThresholdTemperature(value));
56
+ this.service.getCharacteristic(this.Characteristic.HeatingThresholdTemperature)
57
+ .setProps({ minStep: tempStep, minValue: minSetTemp, maxValue: maxSetTemp })
58
+ .onGet(() => this.getHeatingThresholdTemperatureValue())
59
+ .onSet(value => this.setHeatingThresholdTemperature(value));
60
+ this.service.getCharacteristic(this.Characteristic.TemperatureDisplayUnits)
61
+ .onGet(() => this.getTemperatureDisplayUnits());
62
+ this.fanService.getCharacteristic(this.Characteristic.On)
63
+ .onGet(() => this.getFanState())
64
+ .onSet(value => this.setFanOn(value));
65
+ }
66
+ getOperatingState() {
67
+ switch (this.data.OperatingState) {
68
+ case VivintDict.OperatingStates.HEATING:
69
+ return this.Characteristic.CurrentHeatingCoolingState.HEAT;
70
+ case VivintDict.OperatingStates.COOLING:
71
+ return this.Characteristic.CurrentHeatingCoolingState.COOL;
72
+ case VivintDict.OperatingStates.IDLE:
73
+ default:
74
+ return this.Characteristic.CurrentHeatingCoolingState.OFF;
75
+ }
76
+ }
77
+ getOperatingMode() {
78
+ switch (this.data.OperatingMode) {
79
+ case VivintDict.OperatingModes.HEAT:
80
+ return this.Characteristic.TargetHeatingCoolingState.HEAT;
81
+ case VivintDict.OperatingModes.COOL:
82
+ return this.Characteristic.TargetHeatingCoolingState.COOL;
83
+ case VivintDict.OperatingModes.AUTO:
84
+ case VivintDict.OperatingModes.ECO:
85
+ return this.Characteristic.TargetHeatingCoolingState.AUTO;
86
+ case VivintDict.OperatingModes.OFF:
87
+ default:
88
+ return this.Characteristic.TargetHeatingCoolingState.OFF;
89
+ }
90
+ }
91
+ async setTargetHeatingCoolingState(state) {
92
+ let setValue = VivintDict.OperatingModes.OFF;
93
+ switch (state) {
94
+ case this.Characteristic.TargetHeatingCoolingState.HEAT:
95
+ setValue = VivintDict.OperatingModes.HEAT;
96
+ break;
97
+ case this.Characteristic.TargetHeatingCoolingState.COOL:
98
+ setValue = VivintDict.OperatingModes.COOL;
99
+ break;
100
+ case this.Characteristic.TargetHeatingCoolingState.AUTO:
101
+ setValue = VivintDict.OperatingModes.AUTO;
102
+ break;
103
+ }
104
+ await this.runSetAction('set the thermostat mode', () => this.vivintApi.setThermostatState(this.id, setValue));
105
+ }
106
+ getTemperatureValue() {
107
+ return this.unroundTemperature(this.data.Value ?? 0);
108
+ }
109
+ getTargetTemperatureValue() {
110
+ switch (this.getOperatingMode()) {
111
+ case this.Characteristic.TargetHeatingCoolingState.HEAT:
112
+ return this.getHeatSetPoint();
113
+ case this.Characteristic.TargetHeatingCoolingState.COOL:
114
+ return this.getCoolSetPoint();
115
+ default:
116
+ return this.getTemperatureValue();
117
+ }
118
+ }
119
+ async setTargetTemperature(temperature) {
120
+ switch (this.getOperatingMode()) {
121
+ case this.Characteristic.TargetHeatingCoolingState.HEAT:
122
+ await this.runSetAction(`set the target temperature to ${temperature}`, () => this.setHeatSetPointDebounced(temperature));
123
+ break;
124
+ case this.Characteristic.TargetHeatingCoolingState.COOL:
125
+ await this.runSetAction(`set the target temperature to ${temperature}`, () => this.setCoolSetPointDebounced(temperature));
126
+ break;
127
+ default:
128
+ // Target temperature cannot be set while off or in auto mode.
129
+ break;
130
+ }
131
+ }
132
+ getCoolingThresholdTemperatureValue() {
133
+ switch (this.getOperatingMode()) {
134
+ case this.Characteristic.TargetHeatingCoolingState.OFF:
135
+ return this.getTemperatureValue();
136
+ case this.Characteristic.TargetHeatingCoolingState.HEAT:
137
+ return this.getHeatSetPoint();
138
+ default:
139
+ return this.getCoolSetPoint();
140
+ }
141
+ }
142
+ getCoolSetPoint() {
143
+ return this.unroundTemperature(this.data.CoolSetPoint ?? 0);
144
+ }
145
+ async setCoolingThresholdTemperature(value) {
146
+ await this.runSetAction(`set the cooling threshold to ${value}`, () => this.setCoolSetPointDebounced(value));
147
+ }
148
+ getHeatingThresholdTemperatureValue() {
149
+ switch (this.getOperatingMode()) {
150
+ case this.Characteristic.TargetHeatingCoolingState.OFF:
151
+ return this.getTemperatureValue();
152
+ case this.Characteristic.TargetHeatingCoolingState.COOL:
153
+ return this.getCoolSetPoint();
154
+ default:
155
+ return this.getHeatSetPoint();
156
+ }
157
+ }
158
+ getHeatSetPoint() {
159
+ return this.unroundTemperature(this.data.HeatSetPoint ?? 0);
160
+ }
161
+ async setHeatingThresholdTemperature(value) {
162
+ await this.runSetAction(`set the heating threshold to ${value}`, () => this.setHeatSetPointDebounced(value));
163
+ }
164
+ getHumidityValue() {
165
+ return typeof this.data.Humidity === 'number' ? this.data.Humidity : 0;
166
+ }
167
+ getFanState() {
168
+ return this.data.FanState === 1;
169
+ }
170
+ async setFanOn(fanOn) {
171
+ const fanState = fanOn ? 100 : 0;
172
+ await this.runSetAction(`turn the fan ${fanOn ? 'on' : 'off'}`, () => this.vivintApi.setThermostatFanState(this.id, fanState));
173
+ }
174
+ getTemperatureDisplayUnits() {
175
+ return this.isCelsius()
176
+ ? this.Characteristic.TemperatureDisplayUnits.CELSIUS
177
+ : this.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
178
+ }
179
+ isCelsius() {
180
+ return Boolean(this.data.TemperatureCelsius);
181
+ }
182
+ /**
183
+ * Vivint reports temperatures in Celsius. For Fahrenheit thermostats, round
184
+ * to the nearest whole °F and convert back so HomeKit shows clean values.
185
+ */
186
+ unroundTemperature(temperature) {
187
+ if (this.isCelsius()) {
188
+ return 0.5 * Math.round(2 * temperature);
189
+ }
190
+ return this.fahrenheitToCelsius(Math.round(this.celsiusToFahrenheit(temperature)));
191
+ }
192
+ fahrenheitToCelsius(temperature) {
193
+ return (temperature - 32) / 1.8;
194
+ }
195
+ celsiusToFahrenheit(temperature) {
196
+ return temperature * 1.8 + 32;
197
+ }
198
+ notify() {
199
+ this.service.updateCharacteristic(this.Characteristic.CurrentHeatingCoolingState, this.getOperatingState());
200
+ this.service.updateCharacteristic(this.Characteristic.TargetHeatingCoolingState, this.getOperatingMode());
201
+ this.service.updateCharacteristic(this.Characteristic.CurrentTemperature, this.getTemperatureValue());
202
+ this.service.updateCharacteristic(this.Characteristic.TargetTemperature, this.getTargetTemperatureValue());
203
+ this.service.updateCharacteristic(this.Characteristic.CurrentRelativeHumidity, this.getHumidityValue());
204
+ this.service.updateCharacteristic(this.Characteristic.CoolingThresholdTemperature, this.getCoolingThresholdTemperatureValue());
205
+ this.service.updateCharacteristic(this.Characteristic.HeatingThresholdTemperature, this.getHeatingThresholdTemperatureValue());
206
+ this.service.updateCharacteristic(this.Characteristic.TemperatureDisplayUnits, this.getTemperatureDisplayUnits());
207
+ this.fanService.updateCharacteristic(this.Characteristic.On, this.getFanState());
208
+ }
209
+ static appliesTo(data) {
210
+ return data.Type === VivintDict.PanelDeviceType.Thermostat;
211
+ }
212
+ static inferCategory(data, categories) {
213
+ return categories.THERMOSTAT;
214
+ }
215
+ }
216
+ //# sourceMappingURL=thermostat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thermostat.js","sourceRoot":"","sources":["../../src/devices/thermostat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ <div class="card">
2
+ <div class="card-body">
3
+ <h5 class="card-title">Vivint Account</h5>
4
+
5
+ <div id="tokenStatus" class="alert alert-secondary" role="alert" style="display: none;"></div>
6
+
7
+ <!-- Step 1: email + password -->
8
+ <form id="loginForm" style="display: none;">
9
+ <p class="card-text">
10
+ Sign in with your Vivint account to link it to Homebridge.
11
+ If your account uses multi-factor authentication, you will be asked for the verification code next.
12
+ Your email and password are sent directly to Vivint and are not stored.
13
+ </p>
14
+ <div class="form-group">
15
+ <label for="email">Vivint Email</label>
16
+ <input type="email" class="form-control" id="email" autocomplete="username" required>
17
+ </div>
18
+ <div class="form-group">
19
+ <label for="password">Vivint Password</label>
20
+ <input type="password" class="form-control" id="password" autocomplete="current-password" required>
21
+ </div>
22
+ <button type="submit" class="btn btn-primary" id="loginButton">Sign In</button>
23
+ </form>
24
+
25
+ <!-- Step 2: MFA code -->
26
+ <form id="mfaForm" style="display: none;">
27
+ <p class="card-text">
28
+ Enter the verification code from your text message, email, or authenticator app.
29
+ </p>
30
+ <div class="form-group">
31
+ <label for="mfaCode">Verification Code</label>
32
+ <input type="text" class="form-control" id="mfaCode" inputmode="numeric" autocomplete="one-time-code" required>
33
+ </div>
34
+ <button type="submit" class="btn btn-primary" id="mfaButton">Verify</button>
35
+ <button type="button" class="btn btn-secondary" id="mfaCancelButton">Start Over</button>
36
+ </form>
37
+
38
+ <!-- Shown when a token is already configured -->
39
+ <div id="signedInActions" style="display: none;">
40
+ <button type="button" class="btn btn-secondary" id="reauthButton">Sign In Again / Replace Token</button>
41
+ </div>
42
+ </div>
43
+ </div>
44
+
45
+ <script>
46
+ (async () => {
47
+ const $ = (id) => document.getElementById(id);
48
+ const show = (el, visible) => { el.style.display = visible ? '' : 'none'; };
49
+
50
+ let pluginConfig = await homebridge.getPluginConfig();
51
+ if (!pluginConfig.length) {
52
+ pluginConfig = [{ platform: 'Vivint', name: 'Vivint' }];
53
+ await homebridge.updatePluginConfig(pluginConfig);
54
+ }
55
+
56
+ // Render the standard settings (refresh interval, ignored devices, camera
57
+ // options, ...) from config.schema.json below this custom pane.
58
+ homebridge.showSchemaForm();
59
+
60
+ const refreshView = () => {
61
+ const hasToken = Boolean(pluginConfig[0].refreshToken);
62
+ const status = $('tokenStatus');
63
+ show(status, true);
64
+ if (hasToken) {
65
+ status.className = 'alert alert-success';
66
+ status.textContent = 'A Vivint refresh token is configured. You are all set unless the plugin reports authentication errors.';
67
+ } else {
68
+ status.className = 'alert alert-warning';
69
+ status.textContent = 'No Vivint refresh token is configured yet. Sign in below to generate one.';
70
+ }
71
+ show($('loginForm'), !hasToken);
72
+ show($('signedInActions'), hasToken);
73
+ show($('mfaForm'), false);
74
+ };
75
+
76
+ const saveToken = async (refreshToken) => {
77
+ pluginConfig[0].refreshToken = refreshToken;
78
+ await homebridge.updatePluginConfig(pluginConfig);
79
+ await homebridge.savePluginConfig();
80
+ homebridge.toast.success('Vivint account linked. Restart Homebridge (or the child bridge) to apply.', 'Success');
81
+ refreshView();
82
+ };
83
+
84
+ $('loginForm').addEventListener('submit', async (event) => {
85
+ event.preventDefault();
86
+ const button = $('loginButton');
87
+ button.disabled = true;
88
+ homebridge.showSpinner();
89
+ try {
90
+ const response = await homebridge.request('/login', {
91
+ username: $('email').value,
92
+ password: $('password').value,
93
+ });
94
+ if (response.requiresMfa) {
95
+ show($('loginForm'), false);
96
+ show($('mfaForm'), true);
97
+ $('mfaCode').focus();
98
+ homebridge.toast.info('Vivint sent you a verification code.', 'Verification Required');
99
+ } else {
100
+ await saveToken(response.refreshToken);
101
+ }
102
+ } catch (error) {
103
+ homebridge.toast.error(error.message || 'Sign-in failed.', 'Error');
104
+ } finally {
105
+ homebridge.hideSpinner();
106
+ button.disabled = false;
107
+ }
108
+ });
109
+
110
+ $('mfaForm').addEventListener('submit', async (event) => {
111
+ event.preventDefault();
112
+ const button = $('mfaButton');
113
+ button.disabled = true;
114
+ homebridge.showSpinner();
115
+ try {
116
+ const response = await homebridge.request('/verify-code', { code: $('mfaCode').value });
117
+ await saveToken(response.refreshToken);
118
+ } catch (error) {
119
+ homebridge.toast.error(error.message || 'Verification failed.', 'Error');
120
+ } finally {
121
+ homebridge.hideSpinner();
122
+ button.disabled = false;
123
+ }
124
+ });
125
+
126
+ $('mfaCancelButton').addEventListener('click', () => {
127
+ $('mfaCode').value = '';
128
+ refreshView();
129
+ });
130
+
131
+ $('reauthButton').addEventListener('click', () => {
132
+ show($('signedInActions'), false);
133
+ show($('loginForm'), true);
134
+ });
135
+
136
+ refreshView();
137
+ })();
138
+ </script>
@@ -0,0 +1,120 @@
1
+ import { HomebridgePluginUiServer, RequestError } from '@homebridge/plugin-ui-utils';
2
+ /**
3
+ * Backend for the plugin's custom settings UI. Walks the user through
4
+ * Vivint's sign-in flow (including multi-factor authentication) and hands the
5
+ * resulting long-lived session token back to the UI so it can be saved to the
6
+ * plugin config.
7
+ *
8
+ * This file is intentionally self-contained: it runs as a separate process
9
+ * spawned by the Homebridge UI and does not load the plugin itself.
10
+ */
11
+ const VIVINT_LOGIN_URL = 'https://www.vivintsky.com/api/login';
12
+ const VIVINT_AUTHUSER_URL = 'https://www.vivintsky.com/api/authuser';
13
+ const VIVINT_MFA_URL = 'https://www.vivintsky.com/platform-user-api/v0/platformusers/2fa/validate';
14
+ const REQUEST_TIMEOUT_MS = 20_000;
15
+ function extractSessionCookie(response) {
16
+ const setCookies = response.headers.getSetCookie?.() ?? [];
17
+ return setCookies.find(cookie => cookie.startsWith('s='))?.split(';')[0];
18
+ }
19
+ async function vivintFetch(url, init) {
20
+ try {
21
+ return await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
22
+ }
23
+ catch (error) {
24
+ const reason = error instanceof Error ? error.message : String(error);
25
+ throw new RequestError(`Could not reach Vivint (${reason}). Check your internet connection and try again.`, {});
26
+ }
27
+ }
28
+ class VivintUiServer extends HomebridgePluginUiServer {
29
+ /**
30
+ * The session cookie for the in-progress sign-in. Held server-side between
31
+ * the login and MFA verification steps; never logged.
32
+ */
33
+ pendingToken = '';
34
+ constructor() {
35
+ super();
36
+ this.onRequest('/login', this.login.bind(this));
37
+ this.onRequest('/verify-code', this.verifyCode.bind(this));
38
+ this.ready();
39
+ }
40
+ /**
41
+ * Step 1: sign in with email and password. Triggers Vivint to send an MFA
42
+ * code when the account has MFA enabled (which is Vivint's default).
43
+ */
44
+ async login(payload) {
45
+ const username = (payload.username ?? '').trim();
46
+ const password = payload.password ?? '';
47
+ if (!username || !password) {
48
+ throw new RequestError('Please enter both your Vivint email address and password.', {});
49
+ }
50
+ const loginResponse = await vivintFetch(VIVINT_LOGIN_URL, {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json' },
53
+ // persist_session extends the token lifetime from 20 minutes to 1 month
54
+ body: JSON.stringify({ username, password, persist_session: true }),
55
+ });
56
+ if (loginResponse.status === 401 || loginResponse.status === 400) {
57
+ throw new RequestError('Vivint rejected the email address or password. Please check them and try again.', {});
58
+ }
59
+ if (loginResponse.status === 429 || loginResponse.status === 403) {
60
+ throw new RequestError('Vivint is rate limiting sign-in attempts. Please wait a few minutes before trying again.', {});
61
+ }
62
+ if (!loginResponse.ok) {
63
+ throw new RequestError(`Vivint sign-in failed unexpectedly (HTTP ${loginResponse.status}). Please try again later.`, {});
64
+ }
65
+ const sessionCookie = extractSessionCookie(loginResponse);
66
+ if (!sessionCookie) {
67
+ throw new RequestError('Vivint did not return a session token. Please try again later.', {});
68
+ }
69
+ this.pendingToken = sessionCookie;
70
+ // Calling the authuser endpoint triggers Vivint to send the MFA code.
71
+ // A 401 here means MFA verification is required; 200 means it is not.
72
+ const authResponse = await vivintFetch(VIVINT_AUTHUSER_URL, {
73
+ method: 'GET',
74
+ headers: { Cookie: this.pendingToken },
75
+ });
76
+ await authResponse.text().catch(() => '');
77
+ const rotatedCookie = extractSessionCookie(authResponse);
78
+ if (rotatedCookie) {
79
+ this.pendingToken = rotatedCookie;
80
+ }
81
+ if (authResponse.status === 401) {
82
+ return { requiresMfa: true };
83
+ }
84
+ if (!authResponse.ok) {
85
+ throw new RequestError(`Vivint sign-in failed unexpectedly (HTTP ${authResponse.status}). Please try again later.`, {});
86
+ }
87
+ return { requiresMfa: false, refreshToken: this.pendingToken };
88
+ }
89
+ /**
90
+ * Step 2: verify the MFA code the user received (or from their
91
+ * authenticator app) and return the final refresh token.
92
+ */
93
+ async verifyCode(payload) {
94
+ const code = (payload.code ?? '').trim();
95
+ if (!code) {
96
+ throw new RequestError('Please enter the verification code.', {});
97
+ }
98
+ if (!this.pendingToken) {
99
+ throw new RequestError('The sign-in session has expired. Please sign in again.', {});
100
+ }
101
+ const response = await vivintFetch(VIVINT_MFA_URL, {
102
+ method: 'POST',
103
+ headers: { 'Content-Type': 'application/json', Cookie: this.pendingToken },
104
+ body: JSON.stringify({ code, persist_session: true }),
105
+ });
106
+ await response.text().catch(() => '');
107
+ if (!response.ok) {
108
+ throw new RequestError('Vivint rejected the verification code. Please check the code and try again.', {});
109
+ }
110
+ const rotatedCookie = extractSessionCookie(response);
111
+ if (rotatedCookie) {
112
+ this.pendingToken = rotatedCookie;
113
+ }
114
+ const token = this.pendingToken;
115
+ this.pendingToken = '';
116
+ return { refreshToken: token };
117
+ }
118
+ }
119
+ (() => new VivintUiServer())();
120
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../homebridge-ui/server.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { VivintPlatform } from './platform.js';
2
+ import { PLATFORM_NAME } from './settings.js';
3
+ /**
4
+ * Registers the Vivint platform with Homebridge.
5
+ */
6
+ export default (api) => {
7
+ api.registerPlatform(PLATFORM_NAME, VivintPlatform);
8
+ };
9
+ //# sourceMappingURL=index.js.map