@marcel2215/homebridge-supla-plugin 2.1.28 → 2.1.30

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 (120) hide show
  1. package/README.md +67 -1
  2. package/config.schema.json +92 -75
  3. package/dist/Accesories/ActionTriggerAccessory.d.ts +0 -1
  4. package/dist/Accesories/ActionTriggerAccessory.d.ts.map +1 -1
  5. package/dist/Accesories/ActionTriggerAccessory.js +15 -9
  6. package/dist/Accesories/ActionTriggerAccessory.js.map +1 -1
  7. package/dist/Accesories/AirQualityAccessory.d.ts +3 -1
  8. package/dist/Accesories/AirQualityAccessory.d.ts.map +1 -1
  9. package/dist/Accesories/AirQualityAccessory.js +47 -5
  10. package/dist/Accesories/AirQualityAccessory.js.map +1 -1
  11. package/dist/Accesories/ContactSensorAccessory.d.ts +3 -1
  12. package/dist/Accesories/ContactSensorAccessory.d.ts.map +1 -1
  13. package/dist/Accesories/ContactSensorAccessory.js +32 -4
  14. package/dist/Accesories/ContactSensorAccessory.js.map +1 -1
  15. package/dist/Accesories/DimmerAccessory.d.ts +4 -2
  16. package/dist/Accesories/DimmerAccessory.d.ts.map +1 -1
  17. package/dist/Accesories/DimmerAccessory.js +51 -14
  18. package/dist/Accesories/DimmerAccessory.js.map +1 -1
  19. package/dist/Accesories/DimmerRgbLightAccessory.d.ts +10 -2
  20. package/dist/Accesories/DimmerRgbLightAccessory.d.ts.map +1 -1
  21. package/dist/Accesories/DimmerRgbLightAccessory.js +149 -26
  22. package/dist/Accesories/DimmerRgbLightAccessory.js.map +1 -1
  23. package/dist/Accesories/DoorAccessory.d.ts +14 -1
  24. package/dist/Accesories/DoorAccessory.d.ts.map +1 -1
  25. package/dist/Accesories/DoorAccessory.js +146 -20
  26. package/dist/Accesories/DoorAccessory.js.map +1 -1
  27. package/dist/Accesories/ElectricityMeterAccessory.d.ts +13 -1
  28. package/dist/Accesories/ElectricityMeterAccessory.d.ts.map +1 -1
  29. package/dist/Accesories/ElectricityMeterAccessory.js +127 -12
  30. package/dist/Accesories/ElectricityMeterAccessory.js.map +1 -1
  31. package/dist/Accesories/FacadeBlindAccessory.d.ts +6 -0
  32. package/dist/Accesories/FacadeBlindAccessory.d.ts.map +1 -1
  33. package/dist/Accesories/FacadeBlindAccessory.js +205 -64
  34. package/dist/Accesories/FacadeBlindAccessory.js.map +1 -1
  35. package/dist/Accesories/FrontGateFsm.d.ts +74 -68
  36. package/dist/Accesories/FrontGateFsm.d.ts.map +1 -1
  37. package/dist/Accesories/FrontGateFsm.js +563 -403
  38. package/dist/Accesories/FrontGateFsm.js.map +1 -1
  39. package/dist/Accesories/GarageDoorOpenerAccesory.d.ts +12 -3
  40. package/dist/Accesories/GarageDoorOpenerAccesory.d.ts.map +1 -1
  41. package/dist/Accesories/GarageDoorOpenerAccesory.js +168 -21
  42. package/dist/Accesories/GarageDoorOpenerAccesory.js.map +1 -1
  43. package/dist/Accesories/GateAccessory.d.ts +12 -2
  44. package/dist/Accesories/GateAccessory.d.ts.map +1 -1
  45. package/dist/Accesories/GateAccessory.js +245 -90
  46. package/dist/Accesories/GateAccessory.js.map +1 -1
  47. package/dist/Accesories/GateLockAccessory.d.ts +17 -1
  48. package/dist/Accesories/GateLockAccessory.d.ts.map +1 -1
  49. package/dist/Accesories/GateLockAccessory.js +375 -50
  50. package/dist/Accesories/GateLockAccessory.js.map +1 -1
  51. package/dist/Accesories/LeakSensorAccessory.d.ts +3 -1
  52. package/dist/Accesories/LeakSensorAccessory.d.ts.map +1 -1
  53. package/dist/Accesories/LeakSensorAccessory.js +32 -4
  54. package/dist/Accesories/LeakSensorAccessory.js.map +1 -1
  55. package/dist/Accesories/LightBulbAccesory.d.ts +3 -2
  56. package/dist/Accesories/LightBulbAccesory.d.ts.map +1 -1
  57. package/dist/Accesories/LightBulbAccesory.js +41 -12
  58. package/dist/Accesories/LightBulbAccesory.js.map +1 -1
  59. package/dist/Accesories/PressureAccessory.d.ts +3 -1
  60. package/dist/Accesories/PressureAccessory.d.ts.map +1 -1
  61. package/dist/Accesories/PressureAccessory.js +28 -5
  62. package/dist/Accesories/PressureAccessory.js.map +1 -1
  63. package/dist/Accesories/RGBLightBulbAccesory.d.ts +9 -0
  64. package/dist/Accesories/RGBLightBulbAccesory.d.ts.map +1 -1
  65. package/dist/Accesories/RGBLightBulbAccesory.js +137 -17
  66. package/dist/Accesories/RGBLightBulbAccesory.js.map +1 -1
  67. package/dist/Accesories/RollerShutterAccessory.d.ts +6 -0
  68. package/dist/Accesories/RollerShutterAccessory.d.ts.map +1 -1
  69. package/dist/Accesories/RollerShutterAccessory.js +221 -75
  70. package/dist/Accesories/RollerShutterAccessory.js.map +1 -1
  71. package/dist/Accesories/SwitchAccessory.d.ts +3 -2
  72. package/dist/Accesories/SwitchAccessory.d.ts.map +1 -1
  73. package/dist/Accesories/SwitchAccessory.js +41 -12
  74. package/dist/Accesories/SwitchAccessory.js.map +1 -1
  75. package/dist/Accesories/TemperatureAccessory.d.ts +3 -1
  76. package/dist/Accesories/TemperatureAccessory.d.ts.map +1 -1
  77. package/dist/Accesories/TemperatureAccessory.js +28 -5
  78. package/dist/Accesories/TemperatureAccessory.js.map +1 -1
  79. package/dist/Accesories/TemperatureHumidityAccessory.d.ts +5 -1
  80. package/dist/Accesories/TemperatureHumidityAccessory.d.ts.map +1 -1
  81. package/dist/Accesories/TemperatureHumidityAccessory.js +40 -9
  82. package/dist/Accesories/TemperatureHumidityAccessory.js.map +1 -1
  83. package/dist/Accesories/ThermostatAccessory.d.ts +18 -1
  84. package/dist/Accesories/ThermostatAccessory.d.ts.map +1 -1
  85. package/dist/Accesories/ThermostatAccessory.js +193 -34
  86. package/dist/Accesories/ThermostatAccessory.js.map +1 -1
  87. package/dist/Accesories/ValveAccessory.d.ts +5 -2
  88. package/dist/Accesories/ValveAccessory.d.ts.map +1 -1
  89. package/dist/Accesories/ValveAccessory.js +47 -8
  90. package/dist/Accesories/ValveAccessory.js.map +1 -1
  91. package/dist/Accesories/WicketAccesory.d.ts +18 -3
  92. package/dist/Accesories/WicketAccesory.d.ts.map +1 -1
  93. package/dist/Accesories/WicketAccesory.js +154 -14
  94. package/dist/Accesories/WicketAccesory.js.map +1 -1
  95. package/dist/Heplers/ColorConverters.d.ts +2 -2
  96. package/dist/Heplers/ColorConverters.d.ts.map +1 -1
  97. package/dist/Heplers/ColorConverters.js +7 -3
  98. package/dist/Heplers/ColorConverters.js.map +1 -1
  99. package/dist/Heplers/DisplayName.d.ts +15 -0
  100. package/dist/Heplers/DisplayName.d.ts.map +1 -0
  101. package/dist/Heplers/DisplayName.js +174 -0
  102. package/dist/Heplers/DisplayName.js.map +1 -0
  103. package/dist/Heplers/SuplaChannelContext.d.ts +3 -1
  104. package/dist/Heplers/SuplaChannelContext.d.ts.map +1 -1
  105. package/dist/Heplers/SuplaChannelContext.js +3 -1
  106. package/dist/Heplers/SuplaChannelContext.js.map +1 -1
  107. package/dist/Heplers/SuplaMqttClient.d.ts +11 -3
  108. package/dist/Heplers/SuplaMqttClient.d.ts.map +1 -1
  109. package/dist/Heplers/SuplaMqttClient.js +215 -112
  110. package/dist/Heplers/SuplaMqttClient.js.map +1 -1
  111. package/dist/Heplers/SuplaMqttClientContext.d.ts +2 -1
  112. package/dist/Heplers/SuplaMqttClientContext.d.ts.map +1 -1
  113. package/dist/Heplers/SuplaMqttClientContext.js +2 -1
  114. package/dist/Heplers/SuplaMqttClientContext.js.map +1 -1
  115. package/dist/platform.d.ts +92 -36
  116. package/dist/platform.d.ts.map +1 -1
  117. package/dist/platform.js +1253 -235
  118. package/dist/platform.js.map +1 -1
  119. package/package.json +10 -5
  120. package/config.json +0 -3
package/README.md CHANGED
@@ -14,12 +14,36 @@
14
14
 
15
15
  This is an accessory plugin for Supla devices. It allows you to control your Supla devices with HomeKit and Siri.
16
16
 
17
- Supports Homebridge 1.6 or later, including Homebridge 2.1.1. Homebridge 2 requires Node.js 22.12 or 24.
17
+ Supports Homebridge 1.6 or later, including Homebridge 2.1.1, on Node.js 22.12+ or Node.js 24.
18
18
 
19
19
  ### How it works
20
20
 
21
21
  This plugin uses the mqtt protocol to communicate with the Supla server. It subscribes to the topics of the devices you want to control and publishes the commands you send to the devices.
22
22
 
23
+ Discovered channel metadata is cached in a versioned, per-platform-instance file under Homebridge's storage directory. A legacy
24
+ `channels` value is migrated once for compatibility; the plugin does not rewrite Homebridge's `config.json` at runtime.
25
+ Cached cloud-topic accessories can be safely migrated in place because their topic contains the Supla account name. Older
26
+ roller-shutter topics contain no account identity, so they receive a new account-scoped HomeKit identity by default. Set
27
+ `migrateUnscopedLegacyAccessories` to `true` only for a one-time migration when you know the cached accessories belong to the
28
+ currently configured account; do not enable it when changing accounts.
29
+
30
+ Supla captions are retained in Unicode NFC form, so Polish diacritics and other scripts are not passed through an ASCII-only
31
+ sanitizer. HomeKit-facing names preserve Unicode letters and numbers while mapping only typography unsupported by HAP and respecting
32
+ the Name characteristic's 64 UTF-16-code-unit limit. Generated, blank, malformed, or partial-discovery captions never replace a
33
+ meaningful cached name; an existing name changes only with durable retained-caption evidence or a complete authoritative snapshot.
34
+ The plugin does not write HomeKit's user-controlled `ConfiguredName` characteristic.
35
+ Accessory UUIDs and service identities are based only on the account plus channel IDs (or a stable legacy topic), never on captions;
36
+ renaming a channel therefore does not create a new HomeKit accessory.
37
+
38
+ MQTT publish completion confirms delivery to the MQTT client/broker, not physical-device application. HomeKit setters surface
39
+ transport failures, and state is reconciled from subsequent Supla state topics.
40
+
41
+ Electricity meters retain the existing HomeKit `LightSensor` service for automation and accessory-identity compatibility.
42
+ `CurrentAmbientLightLevel` is therefore a compatibility carrier, not a lux reading: its numeric value uses the one Supla metric and
43
+ unit shown explicitly in the service name (for example, `Voltage; V` or `Active power; W`). On first setup the plugin selects one
44
+ metric deterministically from the retained snapshot and persists that choice. It will not silently switch units on later starts; if
45
+ the selected metric is absent, the service remains unavailable. The generic `value` metric is labeled `unknown unit`.
46
+
23
47
 
24
48
  ### How to use
25
49
 
@@ -30,3 +54,45 @@ $ npm i homebridge-supla-plugin
30
54
  2. Configure the plugin. You can find your MQTT credentials in the [Supla Cloud](https://cloud.supla.org/).
31
55
  3. Restart Homebridge
32
56
  4. Plugin will automatically discover your devices and add them to HomeKit
57
+
58
+ ### Front-gate safety model
59
+
60
+ Supla front gates controlled through the non-idempotent `open_close` action need a closed end-stop sensor. If the sensor is on a
61
+ separate channel, the plugin pairs it only when there is one unambiguous candidate. Configure one of these overrides if automatic
62
+ pairing is not possible:
63
+
64
+ ```json
65
+ {
66
+ "frontGateSensorTopic": "supla/USER/devices/123/channels/456"
67
+ }
68
+ ```
69
+
70
+ Alternatively, use `frontGateSensorDeviceId` and `frontGateSensorChannelId`. A missing or ambiguous sensor keeps the gate unavailable.
71
+ The legacy control-channel sensor fallback is disabled unless `frontGateSensorFallbackToControlChannel` is explicitly enabled.
72
+
73
+ With only a closed sensor, `false` means “not fully closed”; it does not prove that the gate is fully open or reveal its direction.
74
+ The plugin therefore reports an unproven non-closed position as HomeKit `STOPPED` and rejects ambiguous open and close requests by
75
+ default:
76
+
77
+ ```json
78
+ {
79
+ "frontGateUnknownOpenPolicy": "reject",
80
+ "frontGateUnknownClosePolicy": "reject",
81
+ "frontGateAssumeOpenAfterTravel": false
82
+ }
83
+ ```
84
+
85
+ Optional compatibility policies are:
86
+
87
+ - `accept_non_closed` for open requests: accepts any non-closed position without sending a pulse.
88
+ - `single_pulse_best_effort` for close requests: sends one pulse but continues reporting `STOPPED` until hard evidence arrives.
89
+ - `seek_closed` for close requests: sends up to `frontGateSeekClosedMaxPulses` pulses, one full travel interval apart, until the closed
90
+ sensor activates. The search can initially move the gate in the opposite direction and must only be enabled with that behavior
91
+ understood.
92
+
93
+ `frontGateAssumeOpenAfterTravel` is also an approximation and is disabled by default. An IR remote cannot be observed by the plugin,
94
+ so external IR use can always invalidate a direction estimate until new sensor evidence arrives.
95
+
96
+ Front-gate action publications always use MQTT QoS 0 and `retain: false`, independently of the global command settings. Retained
97
+ `execute_action` messages are ignored by the state estimator; any old retained action already stored on the broker should be removed.
98
+ MQTT 5 enables a No Local subscription for safer self-echo handling by setting `mqttProtocolVersion` to `5`, if the broker supports it.
@@ -2,7 +2,18 @@
2
2
  "pluginAlias": "SuplaPlatform",
3
3
  "pluginType": "platform",
4
4
  "singular": true,
5
+ "strictValidation": false,
5
6
  "schema": {
7
+ "type": "object",
8
+ "required": [
9
+ "name",
10
+ "host",
11
+ "port",
12
+ "username",
13
+ "password"
14
+ ],
15
+ "additionalProperties": true,
16
+ "properties": {
6
17
  "name": {
7
18
  "title": "Name",
8
19
  "type": "string",
@@ -58,95 +69,88 @@
58
69
  "auto"
59
70
  ]
60
71
  },
61
- "gateControlMode": {
62
- "title": "Gate Control Mode",
63
- "type": "string",
64
- "default": "execute_action",
65
- "enum": [
66
- "execute_action",
67
- "toggle"
68
- ]
69
- },
70
- "gateExecuteActionOpen": {
71
- "title": "Gate Execute Action Open",
72
- "type": "string",
73
- "default": "open_close"
74
- },
75
- "gateExecuteActionClose": {
76
- "title": "Gate Execute Action Close",
77
- "type": "string",
78
- "default": "open_close"
72
+ "migrateUnscopedLegacyAccessories": {
73
+ "title": "Adopt Legacy Unscoped Accessories",
74
+ "type": "boolean",
75
+ "default": false,
76
+ "description": "One-time compatibility opt-in for legacy roller-shutter accessories whose cached topics contain no Supla account identity. Leave disabled after changing accounts."
79
77
  },
80
78
  "gateExecuteActionToggle": {
81
- "title": "Gate Execute Action Toggle",
79
+ "title": "Front Gate Toggle Action",
82
80
  "type": "string",
83
81
  "default": "open_close"
84
82
  },
85
- "gatePartialHiMode": {
86
- "title": "Gate Partial Hi Mode",
87
- "type": "string",
88
- "default": "moving",
89
- "enum": [
90
- "moving",
91
- "open_endstop",
92
- "pedestrian_endstop",
93
- "ignore"
94
- ]
95
- },
96
- "gateReverseFollowUpDelayMs": {
97
- "title": "Gate Reverse Follow-up Delay (ms)",
83
+ "frontGateFullTravelMs": {
84
+ "title": "Front Gate Full Travel (ms)",
98
85
  "type": "number",
99
- "default": 3000
86
+ "default": 25000,
87
+ "minimum": 5000,
88
+ "maximum": 120000
100
89
  },
101
- "gateOpenAssumeDelayMs": {
102
- "title": "Gate Open Assume Delay (ms)",
90
+ "frontGateReversePauseMs": {
91
+ "title": "Front Gate Reverse Pause (ms)",
103
92
  "type": "number",
104
- "default": 22000
93
+ "default": 3000,
94
+ "minimum": 3000,
95
+ "maximum": 15000
105
96
  },
106
- "gateCommandCooldownMs": {
107
- "title": "Gate Command Cooldown (ms)",
97
+ "frontGateMinimumPulseGapMs": {
98
+ "title": "Front Gate Minimum Pulse Gap (ms)",
108
99
  "type": "number",
109
- "default": 700
100
+ "default": 3000,
101
+ "minimum": 0,
102
+ "maximum": 15000
110
103
  },
111
- "gatePublishRetryDelayMs": {
112
- "title": "Gate Publish Retry Delay (ms)",
113
- "type": "number",
114
- "default": 300
104
+ "frontGateUnknownOpenPolicy": {
105
+ "title": "Unknown-State Open Policy",
106
+ "type": "string",
107
+ "default": "reject",
108
+ "enum": [
109
+ "reject",
110
+ "accept_non_closed"
111
+ ]
115
112
  },
116
- "gateStrictReverseDoublePulse": {
117
- "title": "Gate Strict Reverse Double Pulse",
118
- "type": "boolean",
119
- "default": true
113
+ "frontGateUnknownClosePolicy": {
114
+ "title": "Unknown-State Close Policy",
115
+ "type": "string",
116
+ "default": "reject",
117
+ "enum": [
118
+ "reject",
119
+ "single_pulse_best_effort",
120
+ "seek_closed"
121
+ ]
122
+ },
123
+ "frontGateSeekClosedMaxPulses": {
124
+ "title": "Seek-Closed Maximum Pulses",
125
+ "type": "number",
126
+ "default": 3,
127
+ "minimum": 1,
128
+ "maximum": 3
120
129
  },
121
- "gateDebugTimeline": {
122
- "title": "Gate Debug Timeline",
130
+ "frontGateAssumeOpenAfterTravel": {
131
+ "title": "Assume Fully Open After Travel Time",
123
132
  "type": "boolean",
124
133
  "default": false
125
134
  },
126
- "frontGateFullTravelMs": {
127
- "title": "Front Gate Full Travel (ms)",
128
- "type": "number",
129
- "default": 25000
130
- },
131
- "frontGateReversePauseMs": {
132
- "title": "Front Gate Reverse Pause (ms)",
133
- "type": "number",
134
- "default": 900
135
+ "frontGateSensorTopic": {
136
+ "title": "Front Gate Sensor Base Topic",
137
+ "type": "string",
138
+ "default": ""
135
139
  },
136
- "frontGateWrongDirectionRunMs": {
137
- "title": "Front Gate Wrong Direction Run (ms)",
138
- "type": "number",
139
- "default": 700
140
+ "frontGateSensorDeviceId": {
141
+ "title": "Front Gate Sensor Device ID",
142
+ "type": "string",
143
+ "default": ""
140
144
  },
141
- "frontGateMinimumPulseGapMs": {
142
- "title": "Front Gate Minimum Pulse Gap (ms)",
143
- "type": "number",
144
- "default": 400
145
+ "frontGateSensorChannelId": {
146
+ "title": "Front Gate Sensor Channel ID",
147
+ "type": "string",
148
+ "default": ""
145
149
  },
146
- "frontGateCloseRetryLimit": {
147
- "title": "Front Gate Close Retry Limit",
148
- "type": "number",
149
- "default": 1
150
+ "frontGateSensorFallbackToControlChannel": {
151
+ "title": "Use Control Channel as Sensor Fallback",
152
+ "type": "boolean",
153
+ "default": false
150
154
  },
151
155
  "gateLockControlMode": {
152
156
  "title": "Gate Lock Control Mode",
@@ -170,7 +174,9 @@
170
174
  "gateLockPulseSeconds": {
171
175
  "title": "Gate Lock Pulse Seconds",
172
176
  "type": "number",
173
- "default": 0
177
+ "default": 1,
178
+ "minimum": 0.1,
179
+ "maximum": 60
174
180
  },
175
181
  "gateLockSetOnPayload": {
176
182
  "title": "Gate Lock Set On Payload",
@@ -222,6 +228,15 @@
222
228
  "type": "number",
223
229
  "default": 0
224
230
  },
231
+ "mqttProtocolVersion": {
232
+ "title": "MQTT Protocol Version",
233
+ "type": "number",
234
+ "default": 4,
235
+ "enum": [
236
+ 4,
237
+ 5
238
+ ]
239
+ },
225
240
  "commandQos": {
226
241
  "title": "Command QoS",
227
242
  "type": "number",
@@ -239,18 +254,20 @@
239
254
  },
240
255
  "username": {
241
256
  "title": "Username",
242
- "type": "string",
243
- "default": "admin"
257
+ "type": "string"
244
258
  },
245
259
  "password": {
246
260
  "title": "Password",
247
261
  "type": "string",
248
- "default": "admin"
262
+ "format": "password"
249
263
  },
250
264
  "channels": {
251
265
  "title": "Cached Channels",
252
266
  "type": "string",
253
- "default": "[]"
267
+ "description": "Deprecated legacy cache. It is read once for migration and is no longer written.",
268
+ "deprecated": true,
269
+ "hidden": true
270
+ }
254
271
  }
255
272
  }
256
273
  }
@@ -6,7 +6,6 @@ export declare class ActionTriggerAccessory {
6
6
  private readonly accessory;
7
7
  private readonly context;
8
8
  private service;
9
- private connected;
10
9
  constructor(platform: SuplaPlatform, accessory: PlatformAccessory, context: SuplaChannelContext);
11
10
  private parseEvent;
12
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ActionTriggerAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/ActionTriggerAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,qBAAa,sBAAsB;IAK/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,SAAS,CAAQ;gBAGN,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IAmC/C,OAAO,CAAC,UAAU;CAUnB"}
1
+ {"version":3,"file":"ActionTriggerAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/ActionTriggerAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,qBAAa,sBAAsB;IAI/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,OAAO,CAAU;gBAGN,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IAoC/C,OAAO,CAAC,UAAU;CAanB"}
@@ -6,32 +6,38 @@ class ActionTriggerAccessory {
6
6
  this.platform = platform;
7
7
  this.accessory = accessory;
8
8
  this.context = context;
9
- this.connected = true;
10
9
  this.accessory.getService(this.platform.Service.AccessoryInformation)
11
10
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Supla')
12
11
  .setCharacteristic(this.platform.Characteristic.Model, 'ActionTrigger');
13
12
  this.service = this.accessory.getService(this.platform.Service.StatelessProgrammableSwitch)
14
13
  || this.accessory.addService(this.platform.Service.StatelessProgrammableSwitch);
15
14
  this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
16
- this.platform.registerMqttHandler(`${this.context.topic}/state/action`, (message) => {
15
+ this.platform.registerMqttHandler(`${this.context.topic}/state/action`, (message, _topic, packet) => {
16
+ if (packet.retain) {
17
+ this.platform.log.debug(`Ignoring retained action trigger event for ${this.context.channelCaption}`);
18
+ return;
19
+ }
17
20
  const event = this.parseEvent(message.toString());
21
+ if (event === undefined) {
22
+ this.platform.log.debug(`Ignoring unknown action trigger payload for ${this.context.channelCaption}`);
23
+ return;
24
+ }
18
25
  this.platform.log.debug(`Action trigger ${this.context.channelCaption} event=${event}`);
19
26
  this.service.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, event);
20
27
  }, this.accessory.UUID);
21
- this.platform.registerMqttHandler(`${this.context.topic}/state/connected`, (message) => {
22
- this.connected = this.platform.parseBoolean(message.toString());
23
- this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, this.connected ? 0 : 1);
24
- }, this.accessory.UUID);
25
28
  }
26
29
  parseEvent(payload) {
27
30
  const value = payload.trim().toLowerCase();
28
- if (value === '1' || value.includes('double')) {
31
+ if (['1', 'double', 'double_press'].includes(value)) {
29
32
  return this.platform.Characteristic.ProgrammableSwitchEvent.DOUBLE_PRESS;
30
33
  }
31
- if (value === '2' || value.includes('long') || value.includes('hold')) {
34
+ if (['2', 'long', 'long_press', 'hold'].includes(value)) {
32
35
  return this.platform.Characteristic.ProgrammableSwitchEvent.LONG_PRESS;
33
36
  }
34
- return this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS;
37
+ if (['0', 'single', 'single_press', 'click'].includes(value)) {
38
+ return this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS;
39
+ }
40
+ return undefined;
35
41
  }
36
42
  }
37
43
  exports.ActionTriggerAccessory = ActionTriggerAccessory;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionTriggerAccessory.js","sourceRoot":"","sources":["../../src/Accesories/ActionTriggerAccessory.ts"],"names":[],"mappings":";;;AAIA,MAAa,sBAAsB;IAIjC,YACmB,QAAuB,EACvB,SAA4B,EAC5B,OAA4B;QAF5B,aAAQ,GAAR,QAAQ,CAAe;QACvB,cAAS,GAAT,SAAS,CAAmB;QAC5B,YAAO,GAAP,OAAO,CAAqB;QALvC,cAAS,GAAG,IAAI,CAAC;QAOvB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAE;aACnE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC;aACrE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAE1E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,2BAA2B,CAAC;eACtF,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAElF,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QAEzF,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAC/B,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,eAAe,EACpC,CAAC,OAAO,EAAE,EAAE;YACV,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CACrB,kBAAkB,IAAI,CAAC,OAAO,CAAC,cAAc,UAAU,KAAK,EAAE,CAC/D,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QACjG,CAAC,EACD,IAAI,CAAC,SAAS,CAAC,IAAI,CACpB,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAC/B,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,kBAAkB,EACvC,CAAC,OAAO,EAAE,EAAE;YACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAC/B,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,EACxC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACvB,CAAC;QACJ,CAAC,EACD,IAAI,CAAC,SAAS,CAAC,IAAI,CACpB,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,OAAe;QAChC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,uBAAuB,CAAC,YAAY,CAAC;QAC3E,CAAC;QACD,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACtE,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,uBAAuB,CAAC,UAAU,CAAC;QACzE,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,uBAAuB,CAAC,YAAY,CAAC;IAC3E,CAAC;CACF;AApDD,wDAoDC"}
1
+ {"version":3,"file":"ActionTriggerAccessory.js","sourceRoot":"","sources":["../../src/Accesories/ActionTriggerAccessory.ts"],"names":[],"mappings":"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"}
@@ -7,10 +7,12 @@ export declare class AirQualityAccessory {
7
7
  private readonly context;
8
8
  private service;
9
9
  private value;
10
- private connected;
10
+ private connected?;
11
+ private hasValue;
11
12
  private kind;
12
13
  constructor(platform: SuplaPlatform, accessory: PlatformAccessory, context: SuplaChannelContext);
13
14
  handleAirQualityGet(): Promise<CharacteristicValue>;
15
+ private updateFault;
14
16
  private updateMeasurements;
15
17
  private resolveKind;
16
18
  private toAirQuality;
@@ -1 +1 @@
1
- {"version":3,"file":"AirQualityAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/AirQualityAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAIrE,qBAAa,mBAAmB;IAO5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,IAAI,CAAiB;gBAGV,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IAuCzC,mBAAmB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIzD,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,YAAY;CA8BrB"}
1
+ {"version":3,"file":"AirQualityAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/AirQualityAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAIrE,qBAAa,mBAAmB;IAQ5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAT1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAC,CAAU;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAiB;gBAGV,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IAyDzC,mBAAmB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IASzD,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,YAAY;CA8BrB"}
@@ -7,8 +7,12 @@ class AirQualityAccessory {
7
7
  this.accessory = accessory;
8
8
  this.context = context;
9
9
  this.value = 0;
10
- this.connected = true;
10
+ this.hasValue = false;
11
11
  this.kind = this.resolveKind();
12
+ // Caption heuristics are only a legacy bootstrap. Persist the selected
13
+ // measurement semantics so a later channel rename cannot silently switch
14
+ // PM10 thresholds/characteristics to PM2.5 (or vice versa) after restart.
15
+ this.accessory.context.suplaAirQualityKind = this.kind;
12
16
  this.accessory.getService(this.platform.Service.AccessoryInformation)
13
17
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Supla')
14
18
  .setCharacteristic(this.platform.Characteristic.Model, 'AirQualitySensor');
@@ -18,20 +22,43 @@ class AirQualityAccessory {
18
22
  this.service.getCharacteristic(this.platform.Characteristic.AirQuality)
19
23
  .onGet(this.handleAirQualityGet.bind(this));
20
24
  this.platform.registerMqttHandler(`${this.context.topic}/state/value`, (message) => {
21
- const value = parseFloat(message.toString());
22
- if (!Number.isNaN(value)) {
25
+ const value = this.platform.parseFiniteNumberStrict(message.toString());
26
+ if (value !== undefined && value >= 0) {
23
27
  this.value = value;
28
+ this.hasValue = true;
24
29
  this.updateMeasurements();
30
+ this.updateFault();
25
31
  }
26
32
  }, this.accessory.UUID);
27
33
  this.platform.registerMqttHandler(`${this.context.topic}/state/connected`, (message) => {
28
- this.connected = this.platform.parseBoolean(message.toString());
29
- this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, this.connected ? 0 : 1);
34
+ const connected = this.platform.parseBooleanStrict(message.toString());
35
+ if (connected === undefined) {
36
+ return;
37
+ }
38
+ this.connected = connected;
39
+ if (!connected) {
40
+ this.hasValue = false;
41
+ }
42
+ this.updateFault();
43
+ }, this.accessory.UUID);
44
+ this.platform.registerMqttTransportHandler?.((transportConnected) => {
45
+ if (!transportConnected) {
46
+ this.connected = undefined;
47
+ this.hasValue = false;
48
+ this.updateFault();
49
+ }
30
50
  }, this.accessory.UUID);
51
+ this.updateFault();
31
52
  }
32
53
  async handleAirQualityGet() {
54
+ if (this.connected !== true || !this.hasValue) {
55
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
56
+ }
33
57
  return this.toAirQuality(this.value);
34
58
  }
59
+ updateFault() {
60
+ this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, this.connected === true && this.hasValue ? 0 : 1);
61
+ }
35
62
  updateMeasurements() {
36
63
  if (this.kind === 'pm25') {
37
64
  this.service.updateCharacteristic(this.platform.Characteristic.PM2_5Density, this.value);
@@ -42,6 +69,21 @@ class AirQualityAccessory {
42
69
  this.service.updateCharacteristic(this.platform.Characteristic.AirQuality, this.toAirQuality(this.value));
43
70
  }
44
71
  resolveKind() {
72
+ const persisted = this.accessory.context.suplaAirQualityKind;
73
+ if (persisted === 'pm10' || persisted === 'pm25') {
74
+ return persisted;
75
+ }
76
+ const functionName = (this.context.channelFunction ?? '')
77
+ .toUpperCase()
78
+ .replace(/[^A-Z0-9]+/g, '');
79
+ if (functionName.includes('PM10')) {
80
+ return 'pm10';
81
+ }
82
+ if (functionName.includes('PM25') || functionName.includes('PM2')) {
83
+ return 'pm25';
84
+ }
85
+ // Old Supla metadata can expose only GENERAL_PURPOSE_MEASUREMENT. Retain
86
+ // the former caption inference once, then use the persisted value above.
45
87
  const caption = (this.context.channelCaption ?? '').toLowerCase();
46
88
  if (caption.includes('pm10')) {
47
89
  return 'pm10';
@@ -1 +1 @@
1
- {"version":3,"file":"AirQualityAccessory.js","sourceRoot":"","sources":["../../src/Accesories/AirQualityAccessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AirQualityAccessory.js","sourceRoot":"","sources":["../../src/Accesories/AirQualityAccessory.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,10 @@ export declare class ContactSensorAccessory {
7
7
  private readonly context;
8
8
  private service;
9
9
  private state;
10
- private connected;
10
+ private connected?;
11
+ private hasState;
11
12
  constructor(platform: SuplaPlatform, accessory: PlatformAccessory, context: SuplaChannelContext);
12
13
  handleStateGet(): Promise<CharacteristicValue>;
14
+ private updateFault;
13
15
  }
14
16
  //# sourceMappingURL=ContactSensorAccessory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContactSensorAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/ContactSensorAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,qBAAa,sBAAsB;IAM/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAoE;IACjF,OAAO,CAAC,SAAS,CAAQ;gBAGN,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IAsCzC,cAAc,IAAI,OAAO,CAAC,mBAAmB,CAAC;CAGrD"}
1
+ {"version":3,"file":"ContactSensorAccessory.d.ts","sourceRoot":"","sources":["../../src/Accesories/ContactSensorAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,qBAAa,sBAAsB;IAO/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAoE;IACjF,OAAO,CAAC,SAAS,CAAC,CAAU;IAC5B,OAAO,CAAC,QAAQ,CAAS;gBAGN,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,mBAAmB;IAuDzC,cAAc,IAAI,OAAO,CAAC,mBAAmB,CAAC;IASpD,OAAO,CAAC,WAAW;CAQpB"}
@@ -7,7 +7,7 @@ class ContactSensorAccessory {
7
7
  this.accessory = accessory;
8
8
  this.context = context;
9
9
  this.state = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
10
- this.connected = true;
10
+ this.hasState = false;
11
11
  this.accessory.getService(this.platform.Service.AccessoryInformation)
12
12
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Supla')
13
13
  .setCharacteristic(this.platform.Characteristic.Model, 'ContactSensor');
@@ -17,20 +17,48 @@ class ContactSensorAccessory {
17
17
  this.service.getCharacteristic(this.platform.Characteristic.ContactSensorState)
18
18
  .onGet(this.handleStateGet.bind(this));
19
19
  this.platform.registerMqttHandler(`${this.context.topic}/state/hi`, (message) => {
20
- const closed = this.platform.parseBoolean(message.toString());
20
+ const closed = this.platform.parseBooleanStrict(message.toString());
21
+ if (closed === undefined) {
22
+ return;
23
+ }
24
+ this.hasState = true;
21
25
  this.state = closed
22
26
  ? this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED
23
27
  : this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
24
28
  this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, this.state);
29
+ this.updateFault();
25
30
  }, this.accessory.UUID);
26
31
  this.platform.registerMqttHandler(`${this.context.topic}/state/connected`, (message) => {
27
- this.connected = this.platform.parseBoolean(message.toString());
28
- this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, this.connected ? 0 : 1);
32
+ const connected = this.platform.parseBooleanStrict(message.toString());
33
+ if (connected === undefined) {
34
+ return;
35
+ }
36
+ this.connected = connected;
37
+ if (!connected) {
38
+ this.hasState = false;
39
+ }
40
+ this.updateFault();
29
41
  }, this.accessory.UUID);
42
+ this.platform.registerMqttTransportHandler?.((transportConnected) => {
43
+ if (!transportConnected) {
44
+ this.connected = undefined;
45
+ this.hasState = false;
46
+ this.updateFault();
47
+ }
48
+ }, this.accessory.UUID);
49
+ this.updateFault();
30
50
  }
31
51
  async handleStateGet() {
52
+ if (this.connected !== true || !this.hasState) {
53
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
54
+ }
32
55
  return this.state;
33
56
  }
57
+ updateFault() {
58
+ this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, this.connected === true && this.hasState
59
+ ? this.platform.Characteristic.StatusFault.NO_FAULT
60
+ : this.platform.Characteristic.StatusFault.GENERAL_FAULT);
61
+ }
34
62
  }
35
63
  exports.ContactSensorAccessory = ContactSensorAccessory;
36
64
  //# sourceMappingURL=ContactSensorAccessory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContactSensorAccessory.js","sourceRoot":"","sources":["../../src/Accesories/ContactSensorAccessory.ts"],"names":[],"mappings":";;;AAIA,MAAa,sBAAsB;IAKjC,YACmB,QAAuB,EACvB,SAA4B,EAC5B,OAA4B;QAF5B,aAAQ,GAAR,QAAQ,CAAe;QACvB,cAAS,GAAT,SAAS,CAAmB;QAC5B,YAAO,GAAP,OAAO,CAAqB;QANvC,UAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC,gBAAgB,CAAC;QACzE,cAAS,GAAG,IAAI,CAAC;QAOvB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAE;aACnE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC;aACrE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAE1E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC;eACxE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAEpE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QAEzF,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC;aAC5E,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEzC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAC/B,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,WAAW,EAChC,CAAC,OAAO,EAAE,EAAE;YACV,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,KAAK,GAAG,MAAM;gBACjB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC,gBAAgB;gBAClE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC,oBAAoB,CAAC;YACzE,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACjG,CAAC,EACD,IAAI,CAAC,SAAS,CAAC,IAAI,CACpB,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAC/B,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,kBAAkB,EACvC,CAAC,OAAO,EAAE,EAAE;YACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAC/B,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,EACxC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACvB,CAAC;QACJ,CAAC,EACD,IAAI,CAAC,SAAS,CAAC,IAAI,CACpB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF;AAjDD,wDAiDC"}
1
+ {"version":3,"file":"ContactSensorAccessory.js","sourceRoot":"","sources":["../../src/Accesories/ContactSensorAccessory.ts"],"names":[],"mappings":"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"}
@@ -9,14 +9,16 @@ export declare class DimmerAccessory {
9
9
  private state;
10
10
  private brightness;
11
11
  private connected;
12
- private overcurrent;
12
+ private overcurrent?;
13
+ private hasState;
14
+ private hasBrightness;
13
15
  private updateTimer?;
14
16
  constructor(platform: SuplaPlatform, accessory: PlatformAccessory, context: SuplaChannelContext);
15
17
  handleOnGet(): Promise<CharacteristicValue>;
16
18
  handleOnSet(value: CharacteristicValue): Promise<void>;
17
19
  handleBrightnessGet(): Promise<CharacteristicValue>;
18
20
  handleBrightnessSet(value: CharacteristicValue): Promise<void>;
19
- private updateFault;
20
21
  private clearUpdateTimer;
22
+ private assertAvailable;
21
23
  }
22
24
  //# sourceMappingURL=DimmerAccessory.d.ts.map