@mp-consulting/homebridge-lg-thinq 1.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 (241) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/CHANGELOG.md +98 -0
  3. package/LICENSE +176 -0
  4. package/README.md +114 -0
  5. package/config.schema.json +399 -0
  6. package/dist/__tests__/baseDevice.spec.d.ts +1 -0
  7. package/dist/__tests__/baseDevice.spec.js +96 -0
  8. package/dist/__tests__/baseDevice.spec.js.map +1 -0
  9. package/dist/__tests__/deviceControl.coercion.spec.d.ts +1 -0
  10. package/dist/__tests__/deviceControl.coercion.spec.js +53 -0
  11. package/dist/__tests__/deviceControl.coercion.spec.js.map +1 -0
  12. package/dist/__tests__/helper.spec.d.ts +1 -0
  13. package/dist/__tests__/helper.spec.js +74 -0
  14. package/dist/__tests__/helper.spec.js.map +1 -0
  15. package/dist/baseDevice.d.ts +40 -0
  16. package/dist/baseDevice.js +85 -0
  17. package/dist/baseDevice.js.map +1 -0
  18. package/dist/baseDevice.spec.d.ts +1 -0
  19. package/dist/baseDevice.spec.js +107 -0
  20. package/dist/baseDevice.spec.js.map +1 -0
  21. package/dist/characteristics/TotalConsumption.d.ts +2 -0
  22. package/dist/characteristics/TotalConsumption.js +17 -0
  23. package/dist/characteristics/TotalConsumption.js.map +1 -0
  24. package/dist/characteristics/index.d.ts +2 -0
  25. package/dist/characteristics/index.js +7 -0
  26. package/dist/characteristics/index.js.map +1 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.js +89 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/devices/AeroTower.d.ts +24 -0
  31. package/dist/devices/AeroTower.js +113 -0
  32. package/dist/devices/AeroTower.js.map +1 -0
  33. package/dist/devices/AirConditioner.d.ts +425 -0
  34. package/dist/devices/AirConditioner.js +1253 -0
  35. package/dist/devices/AirConditioner.js.map +1 -0
  36. package/dist/devices/AirPurifier.d.ts +50 -0
  37. package/dist/devices/AirPurifier.js +281 -0
  38. package/dist/devices/AirPurifier.js.map +1 -0
  39. package/dist/devices/Dehumidifier.d.ts +28 -0
  40. package/dist/devices/Dehumidifier.js +175 -0
  41. package/dist/devices/Dehumidifier.js.map +1 -0
  42. package/dist/devices/Dishwasher.d.ts +64 -0
  43. package/dist/devices/Dishwasher.js +740 -0
  44. package/dist/devices/Dishwasher.js.map +1 -0
  45. package/dist/devices/Microwave.d.ts +128 -0
  46. package/dist/devices/Microwave.js +1939 -0
  47. package/dist/devices/Microwave.js.map +1 -0
  48. package/dist/devices/Oven.d.ts +148 -0
  49. package/dist/devices/Oven.js +1850 -0
  50. package/dist/devices/Oven.js.map +1 -0
  51. package/dist/devices/RangeHood.d.ts +16 -0
  52. package/dist/devices/RangeHood.js +99 -0
  53. package/dist/devices/RangeHood.js.map +1 -0
  54. package/dist/devices/Refrigerator.d.ts +50 -0
  55. package/dist/devices/Refrigerator.js +325 -0
  56. package/dist/devices/Refrigerator.js.map +1 -0
  57. package/dist/devices/Styler.d.ts +27 -0
  58. package/dist/devices/Styler.js +76 -0
  59. package/dist/devices/Styler.js.map +1 -0
  60. package/dist/devices/WasherDryer.d.ts +39 -0
  61. package/dist/devices/WasherDryer.js +170 -0
  62. package/dist/devices/WasherDryer.js.map +1 -0
  63. package/dist/devices/WasherDryer2.d.ts +9 -0
  64. package/dist/devices/WasherDryer2.js +16 -0
  65. package/dist/devices/WasherDryer2.js.map +1 -0
  66. package/dist/errors/AuthenticationError.d.ts +2 -0
  67. package/dist/errors/AuthenticationError.js +3 -0
  68. package/dist/errors/AuthenticationError.js.map +1 -0
  69. package/dist/errors/ManualProcessNeeded.d.ts +3 -0
  70. package/dist/errors/ManualProcessNeeded.js +4 -0
  71. package/dist/errors/ManualProcessNeeded.js.map +1 -0
  72. package/dist/errors/MonitorError.d.ts +2 -0
  73. package/dist/errors/MonitorError.js +3 -0
  74. package/dist/errors/MonitorError.js.map +1 -0
  75. package/dist/errors/NotConnectedError.d.ts +3 -0
  76. package/dist/errors/NotConnectedError.js +4 -0
  77. package/dist/errors/NotConnectedError.js.map +1 -0
  78. package/dist/errors/TokenError.d.ts +2 -0
  79. package/dist/errors/TokenError.js +3 -0
  80. package/dist/errors/TokenError.js.map +1 -0
  81. package/dist/errors/TokenExpiredError.d.ts +3 -0
  82. package/dist/errors/TokenExpiredError.js +4 -0
  83. package/dist/errors/TokenExpiredError.js.map +1 -0
  84. package/dist/errors/index.d.ts +6 -0
  85. package/dist/errors/index.js +7 -0
  86. package/dist/errors/index.js.map +1 -0
  87. package/dist/helper.d.ts +24 -0
  88. package/dist/helper.js +66 -0
  89. package/dist/helper.js.map +1 -0
  90. package/dist/helper.spec.d.ts +1 -0
  91. package/dist/helper.spec.js +74 -0
  92. package/dist/helper.spec.js.map +1 -0
  93. package/dist/index.d.ts +6 -0
  94. package/dist/index.js +9 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/lib/API.d.ts +141 -0
  97. package/dist/lib/API.js +362 -0
  98. package/dist/lib/API.js.map +1 -0
  99. package/dist/lib/API.spec.d.ts +1 -0
  100. package/dist/lib/API.spec.js +55 -0
  101. package/dist/lib/API.spec.js.map +1 -0
  102. package/dist/lib/Auth.d.ts +99 -0
  103. package/dist/lib/Auth.js +348 -0
  104. package/dist/lib/Auth.js.map +1 -0
  105. package/dist/lib/Auth.spec.d.ts +1 -0
  106. package/dist/lib/Auth.spec.js +111 -0
  107. package/dist/lib/Auth.spec.js.map +1 -0
  108. package/dist/lib/Device.d.ts +88 -0
  109. package/dist/lib/Device.js +95 -0
  110. package/dist/lib/Device.js.map +1 -0
  111. package/dist/lib/Device.spec.d.ts +1 -0
  112. package/dist/lib/Device.spec.js +53 -0
  113. package/dist/lib/Device.spec.js.map +1 -0
  114. package/dist/lib/DeviceModel.d.ts +164 -0
  115. package/dist/lib/DeviceModel.js +321 -0
  116. package/dist/lib/DeviceModel.js.map +1 -0
  117. package/dist/lib/DeviceModel.spec.d.ts +1 -0
  118. package/dist/lib/DeviceModel.spec.js +90 -0
  119. package/dist/lib/DeviceModel.spec.js.map +1 -0
  120. package/dist/lib/Gateway.d.ts +18 -0
  121. package/dist/lib/Gateway.js +25 -0
  122. package/dist/lib/Gateway.js.map +1 -0
  123. package/dist/lib/Gateway.spec.d.ts +1 -0
  124. package/dist/lib/Gateway.spec.js +35 -0
  125. package/dist/lib/Gateway.spec.js.map +1 -0
  126. package/dist/lib/Persist.d.ts +101 -0
  127. package/dist/lib/Persist.js +245 -0
  128. package/dist/lib/Persist.js.map +1 -0
  129. package/dist/lib/Persist.spec.d.ts +1 -0
  130. package/dist/lib/Persist.spec.js +90 -0
  131. package/dist/lib/Persist.spec.js.map +1 -0
  132. package/dist/lib/Session.d.ts +80 -0
  133. package/dist/lib/Session.js +100 -0
  134. package/dist/lib/Session.js.map +1 -0
  135. package/dist/lib/Session.spec.d.ts +1 -0
  136. package/dist/lib/Session.spec.js +43 -0
  137. package/dist/lib/Session.spec.js.map +1 -0
  138. package/dist/lib/ThinQ.d.ts +28 -0
  139. package/dist/lib/ThinQ.js +373 -0
  140. package/dist/lib/ThinQ.js.map +1 -0
  141. package/dist/lib/__tests__/API.spec.d.ts +1 -0
  142. package/dist/lib/__tests__/API.spec.js +55 -0
  143. package/dist/lib/__tests__/API.spec.js.map +1 -0
  144. package/dist/lib/__tests__/Auth.spec.d.ts +1 -0
  145. package/dist/lib/__tests__/Auth.spec.js +110 -0
  146. package/dist/lib/__tests__/Auth.spec.js.map +1 -0
  147. package/dist/lib/__tests__/Device.spec.d.ts +1 -0
  148. package/dist/lib/__tests__/Device.spec.js +53 -0
  149. package/dist/lib/__tests__/Device.spec.js.map +1 -0
  150. package/dist/lib/__tests__/DeviceModel.spec.d.ts +1 -0
  151. package/dist/lib/__tests__/DeviceModel.spec.js +90 -0
  152. package/dist/lib/__tests__/DeviceModel.spec.js.map +1 -0
  153. package/dist/lib/__tests__/Gateway.spec.d.ts +1 -0
  154. package/dist/lib/__tests__/Gateway.spec.js +35 -0
  155. package/dist/lib/__tests__/Gateway.spec.js.map +1 -0
  156. package/dist/lib/__tests__/Persist.spec.d.ts +1 -0
  157. package/dist/lib/__tests__/Persist.spec.js +90 -0
  158. package/dist/lib/__tests__/Persist.spec.js.map +1 -0
  159. package/dist/lib/__tests__/Session.spec.d.ts +1 -0
  160. package/dist/lib/__tests__/Session.spec.js +43 -0
  161. package/dist/lib/__tests__/Session.spec.js.map +1 -0
  162. package/dist/lib/constants.d.ts +95 -0
  163. package/dist/lib/constants.js +106 -0
  164. package/dist/lib/constants.js.map +1 -0
  165. package/dist/lib/request.d.ts +2 -0
  166. package/dist/lib/request.js +66 -0
  167. package/dist/lib/request.js.map +1 -0
  168. package/dist/platform.d.ts +41 -0
  169. package/dist/platform.js +229 -0
  170. package/dist/platform.js.map +1 -0
  171. package/dist/settings.d.ts +8 -0
  172. package/dist/settings.js +9 -0
  173. package/dist/settings.js.map +1 -0
  174. package/dist/status/BaseStatus.d.ts +48 -0
  175. package/dist/status/BaseStatus.js +59 -0
  176. package/dist/status/BaseStatus.js.map +1 -0
  177. package/dist/types/snapshots.d.ts +142 -0
  178. package/dist/types/snapshots.js +6 -0
  179. package/dist/types/snapshots.js.map +1 -0
  180. package/dist/utils/__tests__/normalize.spec.d.ts +1 -0
  181. package/dist/utils/__tests__/normalize.spec.js +95 -0
  182. package/dist/utils/__tests__/normalize.spec.js.map +1 -0
  183. package/dist/utils/normalize.d.ts +22 -0
  184. package/dist/utils/normalize.js +51 -0
  185. package/dist/utils/normalize.js.map +1 -0
  186. package/dist/v1/__tests__/prepareControlData.spec.d.ts +1 -0
  187. package/dist/v1/__tests__/prepareControlData.spec.js +48 -0
  188. package/dist/v1/__tests__/prepareControlData.spec.js.map +1 -0
  189. package/dist/v1/devices/AC.d.ts +13 -0
  190. package/dist/v1/devices/AC.js +112 -0
  191. package/dist/v1/devices/AC.js.map +1 -0
  192. package/dist/v1/devices/AirPurifier.d.ts +15 -0
  193. package/dist/v1/devices/AirPurifier.js +57 -0
  194. package/dist/v1/devices/AirPurifier.js.map +1 -0
  195. package/dist/v1/devices/RangeHood.d.ts +6 -0
  196. package/dist/v1/devices/RangeHood.js +12 -0
  197. package/dist/v1/devices/RangeHood.js.map +1 -0
  198. package/dist/v1/devices/Refrigerator.d.ts +17 -0
  199. package/dist/v1/devices/Refrigerator.js +69 -0
  200. package/dist/v1/devices/Refrigerator.js.map +1 -0
  201. package/dist/v1/devices/Washer.d.ts +10 -0
  202. package/dist/v1/devices/Washer.js +23 -0
  203. package/dist/v1/devices/Washer.js.map +1 -0
  204. package/dist/v1/devices/index.d.ts +6 -0
  205. package/dist/v1/devices/index.js +7 -0
  206. package/dist/v1/devices/index.js.map +1 -0
  207. package/dist/v1/helper.d.ts +14 -0
  208. package/dist/v1/helper.js +111 -0
  209. package/dist/v1/helper.js.map +1 -0
  210. package/dist/v1/transforms/AirPurifierState.d.ts +2 -0
  211. package/dist/v1/transforms/AirPurifierState.js +9 -0
  212. package/dist/v1/transforms/AirPurifierState.js.map +1 -0
  213. package/dist/v1/transforms/AirState.d.ts +9 -0
  214. package/dist/v1/transforms/AirState.js +55 -0
  215. package/dist/v1/transforms/AirState.js.map +1 -0
  216. package/dist/v1/transforms/HoodState.d.ts +17 -0
  217. package/dist/v1/transforms/HoodState.js +20 -0
  218. package/dist/v1/transforms/HoodState.js.map +1 -0
  219. package/dist/v1/transforms/RefState.d.ts +6 -0
  220. package/dist/v1/transforms/RefState.js +29 -0
  221. package/dist/v1/transforms/RefState.js.map +1 -0
  222. package/dist/v1/transforms/WasherDryer.d.ts +49 -0
  223. package/dist/v1/transforms/WasherDryer.js +56 -0
  224. package/dist/v1/transforms/WasherDryer.js.map +1 -0
  225. package/docs/authorization.md +40 -0
  226. package/docs/device-configuration.md +68 -0
  227. package/homebridge-ui/public/index.html +120 -0
  228. package/homebridge-ui/public/js/app.js +300 -0
  229. package/homebridge-ui/public/js/countries.js +233 -0
  230. package/homebridge-ui/public/styles.css +185 -0
  231. package/homebridge-ui/server.js +103 -0
  232. package/jest.config.ts +39 -0
  233. package/package.json +83 -0
  234. package/sample/README.md +10 -0
  235. package/sample/airconditioner-model.json +3080 -0
  236. package/sample/airconditioner-snapshot.json +49 -0
  237. package/sample/airconditioner.json +157 -0
  238. package/sample/dishwasher-model.json +869 -0
  239. package/sample/dishwasher.json +125 -0
  240. package/sample/washer_dryer-model.json +1294 -0
  241. package/sample/washer_dryer.json +126 -0
@@ -0,0 +1,399 @@
1
+ {
2
+ "pluginAlias": "LGThinQ",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "customUi": true,
6
+ "strictValidation": false,
7
+ "schema": {
8
+ "auth_mode": {
9
+ "title": "Auth Mode",
10
+ "type": "string",
11
+ "default": "account",
12
+ "oneOf": [
13
+ {
14
+ "title": "LG Account",
15
+ "enum": [
16
+ "account"
17
+ ]
18
+ },
19
+ {
20
+ "title": "Token",
21
+ "enum": [
22
+ "token"
23
+ ]
24
+ }
25
+ ]
26
+ },
27
+ "username": {
28
+ "title": "Username",
29
+ "type": "string",
30
+ "condition": {
31
+ "functionBody": "return model.auth_mode === 'account';"
32
+ }
33
+ },
34
+ "password": {
35
+ "title": "Password",
36
+ "type": "string",
37
+ "condition": {
38
+ "functionBody": "return model.auth_mode === 'account';"
39
+ }
40
+ },
41
+ "refresh_token": {
42
+ "title": "Refresh Token",
43
+ "type": "string",
44
+ "condition": {
45
+ "functionBody": "return model.auth_mode === 'token';"
46
+ }
47
+ },
48
+ "country": {
49
+ "title": "Country",
50
+ "type": "string",
51
+ "default": "US",
52
+ "required": true
53
+ },
54
+ "language": {
55
+ "title": "Language",
56
+ "type": "string",
57
+ "default": "en-US",
58
+ "required": true
59
+ },
60
+ "thinq1": {
61
+ "title": "Enable ThinQ1 Support?",
62
+ "type": "boolean",
63
+ "default": false
64
+ },
65
+ "refresh_interval": {
66
+ "title": "Refresh interval (in second)",
67
+ "type": "number",
68
+ "default": 60,
69
+ "condition": {
70
+ "functionBody": "return !!model.thinq1;"
71
+ }
72
+ },
73
+ "devices": {
74
+ "title": "Devices",
75
+ "description": "leave it empty to enable all device in account",
76
+ "type": "array",
77
+ "items": {
78
+ "type": "object",
79
+ "properties": {
80
+ "id": {
81
+ "title": "Device ID",
82
+ "type": "string",
83
+ "required": true
84
+ },
85
+ "name": {
86
+ "title": "Device Name",
87
+ "type": "string"
88
+ },
89
+ "type": {
90
+ "title": "Device Type",
91
+ "type": "string",
92
+ "enum": [
93
+ "AC",
94
+ "WASHER",
95
+ "WASHER_NEW",
96
+ "WASH_TOWER",
97
+ "DRYER",
98
+ "REFRIGERATOR",
99
+ "DISHWASHER",
100
+ "AIR_PURIFIER",
101
+ "DEHUMIDIFIER",
102
+ "AERO_TOWER",
103
+ "OVEN",
104
+ "RANGE",
105
+ "COOKTOP"
106
+ ],
107
+ "condition": {
108
+ "functionBody": "return false;"
109
+ }
110
+ },
111
+ "serial_number": {
112
+ "title": "Serial Number (optional)",
113
+ "type": "string"
114
+ },
115
+ "dishwasher_trigger": {
116
+ "title": "Enable program finished trigger?",
117
+ "type": "boolean"
118
+ },
119
+ "washer_tub_clean": {
120
+ "title": "Enable Tub Clean Event",
121
+ "type": "boolean"
122
+ },
123
+ "washer_trigger": {
124
+ "title": "Enable program finished trigger?",
125
+ "type": "boolean"
126
+ },
127
+ "washer_door_lock": {
128
+ "title": "Enable door lock status",
129
+ "type": "boolean"
130
+ },
131
+ "ac_air_quality": {
132
+ "title": "Enable Air Quality",
133
+ "description": "if your device supported Air Quality sensor",
134
+ "type": "boolean"
135
+ },
136
+ "ac_mode": {
137
+ "title": "AC Mode (Heating or Cooling or Both)",
138
+ "type": "string",
139
+ "oneOf": [
140
+ {
141
+ "title": "Both Heating and Cooling mode",
142
+ "enum": [
143
+ "BOTH"
144
+ ]
145
+ },
146
+ {
147
+ "title": "Cooling mode only",
148
+ "enum": [
149
+ "COOLING"
150
+ ]
151
+ },
152
+ {
153
+ "title": "Heating mode only",
154
+ "enum": [
155
+ "HEATING"
156
+ ]
157
+ }
158
+ ]
159
+ },
160
+ "ac_swing_mode": {
161
+ "title": "Swing Mode (vertical or horizontal)",
162
+ "type": "string",
163
+ "oneOf": [
164
+ {
165
+ "title": "Both vertical and horizontal swing",
166
+ "enum": [
167
+ "BOTH"
168
+ ]
169
+ },
170
+ {
171
+ "title": "Vertical swing only",
172
+ "enum": [
173
+ "VERTICAL"
174
+ ]
175
+ },
176
+ {
177
+ "title": "Horizontal swing only",
178
+ "enum": [
179
+ "HORIZONTAL"
180
+ ]
181
+ }
182
+ ]
183
+ },
184
+ "ac_temperature_sensor": {
185
+ "title": "Current temperature as sensor",
186
+ "type": "boolean"
187
+ },
188
+ "ac_humidity_sensor": {
189
+ "title": "Enable humidity sensor",
190
+ "type": "boolean"
191
+ },
192
+ "ac_led_control": {
193
+ "title": "Enable led panel control",
194
+ "type": "boolean"
195
+ },
196
+ "ac_fan_control": {
197
+ "title": "Enable separate fan control",
198
+ "type": "boolean"
199
+ },
200
+ "ac_jet_control": {
201
+ "title": "Enable separate jet control",
202
+ "type": "boolean"
203
+ },
204
+ "ac_buttons": {
205
+ "title": "Customize AC buttons",
206
+ "type": "array",
207
+ "items": {
208
+ "type": "object",
209
+ "properties": {
210
+ "name": {
211
+ "type": "string"
212
+ },
213
+ "op_mode": {
214
+ "type": "integer"
215
+ }
216
+ }
217
+ }
218
+ },
219
+ "ac_energy_save": {
220
+ "title": "Energy save as switch",
221
+ "type": "boolean",
222
+ "default": true
223
+ },
224
+ "ac_air_clean": {
225
+ "title": "Air purify as switch",
226
+ "type": "boolean",
227
+ "default": true
228
+ },
229
+ "ac_temperature_unit": {
230
+ "title": "Temperature Unit",
231
+ "type": "string",
232
+ "oneOf": [
233
+ {
234
+ "title": "Celsius",
235
+ "enum": [
236
+ "C"
237
+ ]
238
+ },
239
+ {
240
+ "title": "Fahrenheit",
241
+ "enum": [
242
+ "F"
243
+ ]
244
+ }
245
+ ]
246
+ },
247
+ "ref_express_freezer": {
248
+ "title": "Express Freezer / Ice Plus",
249
+ "type": "boolean"
250
+ },
251
+ "ref_express_fridge": {
252
+ "title": "Express Fridge",
253
+ "type": "boolean"
254
+ },
255
+ "ref_eco_friendly": {
256
+ "title": "Eco Friendly",
257
+ "type": "boolean"
258
+ },
259
+ "air_fast_mode": {
260
+ "title": "Air Fast Mode",
261
+ "type": "boolean"
262
+ }
263
+ }
264
+ }
265
+ }
266
+ },
267
+ "layout": [
268
+ "auth_mode",
269
+ {
270
+ "type": "flex",
271
+ "flex-flow": "row wrap",
272
+ "items": [
273
+ "username",
274
+ {
275
+ "key": "password",
276
+ "type": "password"
277
+ }
278
+ ]
279
+ },
280
+ "refresh_token",
281
+ {
282
+ "type": "flex",
283
+ "flex-flow": "row wrap",
284
+ "items": [
285
+ "country",
286
+ "language"
287
+ ]
288
+ },
289
+ "thinq1",
290
+ "refresh_interval",
291
+ {
292
+ "key": "devices",
293
+ "type": "tabarray",
294
+ "title": "{{ value.name || 'new device' }}",
295
+ "items": [
296
+ "devices[].name",
297
+ "devices[].id",
298
+ "devices[].type",
299
+ "devices[].serial_number",
300
+ {
301
+ "key": "devices[]",
302
+ "type": "fieldset",
303
+ "title": "{{ value.title }}",
304
+ "items": [
305
+ {
306
+ "type": "fieldset",
307
+ "title": "Air purifier specific settings",
308
+ "description": "Configure air purifier device settings.",
309
+ "expandable": true,
310
+ "expanded": false,
311
+ "items": [
312
+ "devices[].air_fast_mode"
313
+ ],
314
+ "condition": {
315
+ "functionBody": "return model.devices && model.devices[arrayIndices] && ['AIR_PURIFIER'].includes(model.devices[arrayIndices].type);"
316
+ }
317
+ },
318
+ {
319
+ "type": "fieldset",
320
+ "title": "Washer / Dryer specific settings",
321
+ "description": "Configure washer/dryer device settings.",
322
+ "expandable": true,
323
+ "expanded": false,
324
+ "items": [
325
+ "devices[].washer_trigger",
326
+ "devices[].washer_tub_clean",
327
+ "devices[].washer_door_lock"
328
+ ],
329
+ "condition": {
330
+ "functionBody": "return model.devices && model.devices[arrayIndices] && ['WASHER','WASHER_NEW', 'WASH_TOWER', 'DRYER', 'WASH_TOWER_2'].includes(model.devices[arrayIndices].type);"
331
+ }
332
+ },
333
+ {
334
+ "type": "fieldset",
335
+ "title": "Air conditioner specific settings",
336
+ "description": "Configure AC device settings.",
337
+ "expandable": true,
338
+ "expanded": false,
339
+ "items": [
340
+ "devices[].ac_air_quality",
341
+ "devices[].ac_mode",
342
+ "devices[].ac_swing_mode",
343
+ "devices[].ac_temperature_sensor",
344
+ "devices[].ac_humidity_sensor",
345
+ "devices[].ac_fan_control",
346
+ "devices[].ac_jet_control",
347
+ "devices[].ac_energy_save",
348
+ "devices[].ac_air_clean",
349
+ "devices[].ac_temperature_unit",
350
+ {
351
+ "key": "devices[].ac_buttons",
352
+ "title": "AC buttons",
353
+ "description": "Configure AC buttons. For details check README.",
354
+ "type": "array",
355
+ "buttonText": "Add button",
356
+ "items": [
357
+ "devices[].ac_buttons[].name",
358
+ "devices[].ac_buttons[].op_mode"
359
+ ]
360
+ }
361
+ ],
362
+ "condition": {
363
+ "functionBody": "return model.devices && model.devices[arrayIndices] && ['AC'].includes(model.devices[arrayIndices].type);"
364
+ }
365
+ },
366
+ {
367
+ "type": "fieldset",
368
+ "title": "Refrigerator specific settings",
369
+ "description": "Configure refrigerator device settings.",
370
+ "expandable": true,
371
+ "expanded": false,
372
+ "items": [
373
+ "devices[].ref_express_freezer",
374
+ "devices[].ref_express_fridge",
375
+ "devices[].ref_eco_friendly"
376
+ ],
377
+ "condition": {
378
+ "functionBody": "return model.devices && model.devices[arrayIndices] && ['REFRIGERATOR'].includes(model.devices[arrayIndices].type);"
379
+ }
380
+ },
381
+ {
382
+ "type": "fieldset",
383
+ "title": "Dishwasher specific settings",
384
+ "description": "Configure dishwasher device settings.",
385
+ "expandable": true,
386
+ "expanded": false,
387
+ "items": [
388
+ "devices[].dishwasher_trigger"
389
+ ],
390
+ "condition": {
391
+ "functionBody": "return model.devices && model.devices[arrayIndices] && ['DISHWASHER'].includes(model.devices[arrayIndices].type);"
392
+ }
393
+ }
394
+ ]
395
+ }
396
+ ]
397
+ }
398
+ ]
399
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,96 @@
1
+ import { BaseDevice } from '../baseDevice.js';
2
+ import { Device } from '../lib/Device.js';
3
+ import { describe, expect, it, jest, beforeEach } from '@jest/globals';
4
+ // Mock dependencies
5
+ jest.mock('../platform.js');
6
+ jest.mock('../lib/Device');
7
+ // Test suite for BaseDevice class
8
+ describe('BaseDevice', () => {
9
+ let platform;
10
+ let accessory;
11
+ let logger;
12
+ let device;
13
+ let baseDevice;
14
+ const mockDeviceData = {
15
+ deviceId: '12345',
16
+ alias: 'Smart Fridge',
17
+ deviceType: 101,
18
+ modelName: 'FR123-US',
19
+ modelJsonUri: 'https://example.com/model.json',
20
+ manufacture: {
21
+ macAddress: '00:1A:2B:3C:4D:5E',
22
+ salesModel: 'FR123',
23
+ serialNo: 'SN123456789',
24
+ manufactureModel: 'FR123-M',
25
+ },
26
+ online: true,
27
+ modemInfo: {
28
+ appVersion: '1.0.0',
29
+ modelName: 'FR123-MODEM',
30
+ },
31
+ snapshot: {
32
+ online: true,
33
+ },
34
+ platformType: 'ThinQ2',
35
+ };
36
+ beforeEach(() => {
37
+ logger = {
38
+ debug: jest.fn(),
39
+ info: jest.fn(),
40
+ warn: jest.fn(),
41
+ error: jest.fn(),
42
+ };
43
+ platform = {
44
+ Service: {
45
+ AccessoryInformation: function AccessoryInformation() { },
46
+ },
47
+ Characteristic: {
48
+ Manufacturer: 'Manufacturer',
49
+ Model: 'Model',
50
+ SerialNumber: 'SerialNumber',
51
+ },
52
+ config: {
53
+ devices: [
54
+ { id: '12345', customConfig: true },
55
+ ],
56
+ },
57
+ log: logger,
58
+ };
59
+ accessory = {
60
+ context: {
61
+ device: new Device(mockDeviceData),
62
+ },
63
+ getService: jest.fn().mockReturnValue(null),
64
+ addService: jest.fn().mockImplementation(() => ({
65
+ setCharacteristic: jest.fn().mockReturnThis(),
66
+ })),
67
+ };
68
+ device = accessory.context.device;
69
+ });
70
+ it('should set accessory information on initialization', () => {
71
+ baseDevice = new BaseDevice(platform, accessory, logger);
72
+ expect(accessory.addService).toHaveBeenCalled();
73
+ const calledArg = accessory.addService.mock.calls[0][0];
74
+ if (typeof calledArg === 'function') {
75
+ expect(calledArg.name).toBe('AccessoryInformation');
76
+ }
77
+ else {
78
+ expect(calledArg.displayName).toBe('AccessoryInformation');
79
+ }
80
+ });
81
+ it('should update accessory characteristics', () => {
82
+ baseDevice = new BaseDevice(platform, accessory, logger);
83
+ const newDevice = { ...device, name: 'Updated Device' };
84
+ baseDevice.updateAccessoryCharacteristic(newDevice);
85
+ expect(accessory.context.device).toEqual(newDevice);
86
+ });
87
+ it('should return an empty object if no configuration is found for the device', () => {
88
+ baseDevice = new BaseDevice(platform, accessory, logger);
89
+ platform.config.devices = [];
90
+ expect(baseDevice.config).toEqual({});
91
+ });
92
+ it('should return an empty string for the static model method', () => {
93
+ expect(BaseDevice.model()).toBe('');
94
+ });
95
+ });
96
+ //# sourceMappingURL=baseDevice.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseDevice.spec.js","sourceRoot":"","sources":["../../src/__tests__/baseDevice.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ import { describe, test, expect, beforeEach, jest } from '@jest/globals';
2
+ import { ThinQ } from '../lib/ThinQ.js';
3
+ import { ValueType } from '../lib/DeviceModel.js';
4
+ describe('ThinQ.deviceControl coercion', () => {
5
+ let thinq;
6
+ beforeEach(() => {
7
+ // Minimal fake platform/config/logger to instantiate ThinQ
8
+ const platform = { api: { user: { storagePath: () => process.cwd() } } };
9
+ const config = { country: 'US', language: 'en' };
10
+ const logger = { debug: () => { }, info: () => { }, warn: () => { }, error: () => { } };
11
+ thinq = new ThinQ(platform, config, logger);
12
+ // stub out network calls
13
+ thinq.api = {
14
+ sendCommandToDevice: jest.fn(async () => ({ resultCode: '0000' })),
15
+ };
16
+ });
17
+ test('coerces Bit value (boolean -> 1)', async () => {
18
+ // fake model that reports key 'power' as Bit
19
+ const fakeModel = {
20
+ value: (k) => (k === 'power' ? { type: ValueType.Bit } : null),
21
+ };
22
+ thinq.deviceModel.dev1 = fakeModel;
23
+ const values = { dataKey: 'power', dataValue: true };
24
+ await thinq.deviceControl('dev1', values);
25
+ // assert that api.sendCommandToDevice received coerced numeric value
26
+ expect(thinq.api.sendCommandToDevice.mock.calls.length).toBe(1);
27
+ const sentValues = thinq.api.sendCommandToDevice.mock.calls[0][1];
28
+ expect(sentValues.dataValue).toBe(1);
29
+ });
30
+ test('coerces Range value (string -> number)', async () => {
31
+ const fakeModel = {
32
+ value: (k) => (k === 'temp' ? { type: ValueType.Range } : null),
33
+ };
34
+ thinq.deviceModel.dev2 = fakeModel;
35
+ const values = { dataSetList: { temp: '23' } };
36
+ await thinq.deviceControl('dev2', values);
37
+ const sentValues2 = thinq.api.sendCommandToDevice.mock.calls[0][1];
38
+ expect(typeof sentValues2.dataSetList.temp).toBe('number');
39
+ expect(sentValues2.dataSetList.temp).toBe(23);
40
+ });
41
+ test('maps Enum label to enum key using model.enumValue', async () => {
42
+ const fakeModel = {
43
+ value: (k) => (k === 'mode' ? { type: ValueType.Enum } : null),
44
+ enumValue: (k, name) => (k === 'mode' && name === 'Cool' ? '1' : null),
45
+ };
46
+ thinq.deviceModel.dev3 = fakeModel;
47
+ const values = { dataSetList: { mode: 'Cool' } };
48
+ await thinq.deviceControl('dev3', values);
49
+ const sentValues3 = thinq.api.sendCommandToDevice.mock.calls[0][1];
50
+ expect(sentValues3.dataSetList.mode).toBe('1');
51
+ });
52
+ });
53
+ //# sourceMappingURL=deviceControl.coercion.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceControl.coercion.spec.js","sourceRoot":"","sources":["../../src/__tests__/deviceControl.coercion.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import { Helper, fToC, cToF } from '../helper.js';
2
+ import { PlatformType } from '../lib/constants.js';
3
+ import { describe, expect, it, jest } from '@jest/globals';
4
+ // Mock dependencies
5
+ jest.mock('../lib/Device');
6
+ jest.mock('../lib/constants', () => ({
7
+ PlatformType: {
8
+ ThinQ1: 'ThinQ1',
9
+ ThinQ2: 'ThinQ2',
10
+ },
11
+ }));
12
+ // Test suite for Helper class and utility functions
13
+ describe('Helper', () => {
14
+ describe('make', () => {
15
+ it('should return V1helper.make for ThinQ1 platform', () => {
16
+ const mockDevice = { platform: PlatformType.ThinQ1 };
17
+ const result = Helper.make(mockDevice);
18
+ expect(result).toBeDefined();
19
+ });
20
+ it('should return the correct class for ThinQ2 devices', () => {
21
+ const mockDevice = { platform: PlatformType.ThinQ2, type: 'AC' };
22
+ const result = Helper.make(mockDevice);
23
+ expect(result).toBeDefined();
24
+ });
25
+ it('should return null for unknown device types', () => {
26
+ const mockDevice = { platform: PlatformType.ThinQ2, type: 'UNKNOWN' };
27
+ const result = Helper.make(mockDevice);
28
+ expect(result).toBeNull();
29
+ });
30
+ it('should return null for unsupported platform types', () => {
31
+ const mockDevice = { platform: 'UnsupportedPlatform' };
32
+ const result = Helper.make(mockDevice);
33
+ expect(result).toBeNull();
34
+ });
35
+ });
36
+ describe('category', () => {
37
+ it('should return the correct category for known device types', () => {
38
+ const mockDevice = { type: 'AIR_PURIFIER' };
39
+ const result = Helper.category(mockDevice);
40
+ expect(result).toBe(19 /* Categories.AIR_PURIFIER */);
41
+ });
42
+ it('should return Categories.OTHER for unknown device types', () => {
43
+ const mockDevice = { type: 'UNKNOWN' };
44
+ const result = Helper.category(mockDevice);
45
+ expect(result).toBe(1 /* Categories.OTHER */);
46
+ });
47
+ it('should return Categories.AIR_CONDITIONER for AC device type', () => {
48
+ const mockDevice = { type: 'AC' };
49
+ const result = Helper.category(mockDevice);
50
+ expect(result).toBe(21 /* Categories.AIR_CONDITIONER */);
51
+ });
52
+ });
53
+ });
54
+ describe('Utility functions', () => {
55
+ describe('fToC', () => {
56
+ it('should convert Fahrenheit to Celsius', () => {
57
+ expect(fToC(32)).toBe(0);
58
+ expect(fToC(212)).toBe(100);
59
+ });
60
+ it('should handle negative Fahrenheit values', () => {
61
+ expect(fToC(-40)).toBe(-40);
62
+ });
63
+ });
64
+ describe('cToF', () => {
65
+ it('should convert Celsius to Fahrenheit', () => {
66
+ expect(cToF(0)).toBe(32);
67
+ expect(cToF(100)).toBe(212);
68
+ });
69
+ it('should handle negative Celsius values', () => {
70
+ expect(cToF(-40)).toBe(-40);
71
+ });
72
+ });
73
+ });
74
+ //# sourceMappingURL=helper.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.spec.js","sourceRoot":"","sources":["../../src/__tests__/helper.spec.ts"],"names":[],"mappings":"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"}