@mp-consulting/homebridge-daikin-cloud 1.3.6 → 1.3.8

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 (291) hide show
  1. package/LICENSE +39 -1
  2. package/README.md +3 -1
  3. package/dist/src/accessories/air-conditioning-accessory.d.ts +2 -2
  4. package/dist/src/accessories/air-conditioning-accessory.d.ts.map +1 -1
  5. package/dist/src/accessories/air-conditioning-accessory.js.map +1 -1
  6. package/dist/src/accessories/altherma-accessory.d.ts +2 -2
  7. package/dist/src/accessories/altherma-accessory.d.ts.map +1 -1
  8. package/dist/src/accessories/altherma-accessory.js.map +1 -1
  9. package/dist/src/accessories/base-accessory.d.ts +5 -5
  10. package/dist/src/accessories/base-accessory.d.ts.map +1 -1
  11. package/dist/src/accessories/base-accessory.js +7 -4
  12. package/dist/src/accessories/base-accessory.js.map +1 -1
  13. package/dist/src/api/daikin-api.d.ts +25 -25
  14. package/dist/src/api/daikin-api.d.ts.map +1 -1
  15. package/dist/src/api/daikin-api.js +41 -31
  16. package/dist/src/api/daikin-api.js.map +1 -1
  17. package/dist/src/api/daikin-cloud.repository.d.ts.map +1 -1
  18. package/dist/src/api/daikin-cloud.repository.js.map +1 -1
  19. package/dist/src/api/daikin-controller.d.ts +41 -42
  20. package/dist/src/api/daikin-controller.d.ts.map +1 -1
  21. package/dist/src/api/daikin-controller.js +39 -39
  22. package/dist/src/api/daikin-controller.js.map +1 -1
  23. package/dist/src/api/daikin-device.d.ts +33 -31
  24. package/dist/src/api/daikin-device.d.ts.map +1 -1
  25. package/dist/src/api/daikin-device.js +40 -29
  26. package/dist/src/api/daikin-device.js.map +1 -1
  27. package/dist/src/api/daikin-mobile-oauth.d.ts +16 -16
  28. package/dist/src/api/daikin-mobile-oauth.d.ts.map +1 -1
  29. package/dist/src/api/daikin-mobile-oauth.js +32 -22
  30. package/dist/src/api/daikin-mobile-oauth.js.map +1 -1
  31. package/dist/src/api/daikin-oauth.d.ts +29 -29
  32. package/dist/src/api/daikin-oauth.d.ts.map +1 -1
  33. package/dist/src/api/daikin-oauth.js +45 -35
  34. package/dist/src/api/daikin-oauth.js.map +1 -1
  35. package/dist/src/api/daikin-schemas.d.ts +4 -4
  36. package/dist/src/api/daikin-schemas.js +3 -3
  37. package/dist/src/api/daikin-schemas.js.map +1 -1
  38. package/dist/src/api/daikin-types.js.map +1 -1
  39. package/dist/src/api/daikin-websocket.d.ts +31 -32
  40. package/dist/src/api/daikin-websocket.d.ts.map +1 -1
  41. package/dist/src/api/daikin-websocket.js +30 -30
  42. package/dist/src/api/daikin-websocket.js.map +1 -1
  43. package/dist/src/api/index.d.ts +1 -1
  44. package/dist/src/api/index.d.ts.map +1 -1
  45. package/dist/src/api/index.js +2 -1
  46. package/dist/src/api/index.js.map +1 -1
  47. package/dist/src/api/token-storage.d.ts +1 -1
  48. package/dist/src/api/token-storage.d.ts.map +1 -1
  49. package/dist/src/api/token-storage.js +20 -11
  50. package/dist/src/api/token-storage.js.map +1 -1
  51. package/dist/src/config/config-manager.d.ts +33 -33
  52. package/dist/src/config/config-manager.d.ts.map +1 -1
  53. package/dist/src/config/config-manager.js +33 -33
  54. package/dist/src/config/config-manager.js.map +1 -1
  55. package/dist/src/constants/api.constants.js.map +1 -1
  56. package/dist/src/device/accessory-factory.d.ts +10 -10
  57. package/dist/src/device/accessory-factory.d.ts.map +1 -1
  58. package/dist/src/device/accessory-factory.js +6 -6
  59. package/dist/src/device/accessory-factory.js.map +1 -1
  60. package/dist/src/device/capability-detector.d.ts +8 -8
  61. package/dist/src/device/capability-detector.d.ts.map +1 -1
  62. package/dist/src/device/capability-detector.js +6 -6
  63. package/dist/src/device/capability-detector.js.map +1 -1
  64. package/dist/src/device/capability-docs.d.ts +1 -1
  65. package/dist/src/device/capability-docs.d.ts.map +1 -1
  66. package/dist/src/device/capability-docs.js +1 -2
  67. package/dist/src/device/capability-docs.js.map +1 -1
  68. package/dist/src/device/profiles/device-profile.d.ts +1 -1
  69. package/dist/src/device/profiles/device-profile.d.ts.map +1 -1
  70. package/dist/src/device/profiles/device-profile.js +4 -4
  71. package/dist/src/device/profiles/device-profile.js.map +1 -1
  72. package/dist/src/features/base-feature.d.ts +2 -2
  73. package/dist/src/features/base-feature.d.ts.map +1 -1
  74. package/dist/src/features/base-feature.js +2 -3
  75. package/dist/src/features/base-feature.js.map +1 -1
  76. package/dist/src/features/feature-manager.d.ts +8 -8
  77. package/dist/src/features/feature-manager.d.ts.map +1 -1
  78. package/dist/src/features/feature-manager.js +5 -5
  79. package/dist/src/features/feature-manager.js.map +1 -1
  80. package/dist/src/features/modes/dry-operation-mode.feature.d.ts +1 -1
  81. package/dist/src/features/modes/dry-operation-mode.feature.d.ts.map +1 -1
  82. package/dist/src/features/modes/dry-operation-mode.feature.js.map +1 -1
  83. package/dist/src/features/modes/econo-mode.feature.d.ts +1 -1
  84. package/dist/src/features/modes/econo-mode.feature.d.ts.map +1 -1
  85. package/dist/src/features/modes/econo-mode.feature.js.map +1 -1
  86. package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts +1 -1
  87. package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts.map +1 -1
  88. package/dist/src/features/modes/fan-only-operation-mode.feature.js.map +1 -1
  89. package/dist/src/features/modes/indoor-silent-mode.feature.d.ts +1 -1
  90. package/dist/src/features/modes/indoor-silent-mode.feature.d.ts.map +1 -1
  91. package/dist/src/features/modes/indoor-silent-mode.feature.js.map +1 -1
  92. package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts +1 -1
  93. package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts.map +1 -1
  94. package/dist/src/features/modes/outdoor-silent-mode.feature.js.map +1 -1
  95. package/dist/src/features/modes/powerful-mode.feature.d.ts +1 -1
  96. package/dist/src/features/modes/powerful-mode.feature.d.ts.map +1 -1
  97. package/dist/src/features/modes/powerful-mode.feature.js.map +1 -1
  98. package/dist/src/features/modes/streamer-mode.feature.d.ts +1 -1
  99. package/dist/src/features/modes/streamer-mode.feature.d.ts.map +1 -1
  100. package/dist/src/features/modes/streamer-mode.feature.js.map +1 -1
  101. package/dist/src/index.d.ts +1 -1
  102. package/dist/src/index.d.ts.map +1 -1
  103. package/dist/src/index.js.map +1 -1
  104. package/dist/src/platform.d.ts +6 -5
  105. package/dist/src/platform.d.ts.map +1 -1
  106. package/dist/src/platform.js +2 -2
  107. package/dist/src/platform.js.map +1 -1
  108. package/dist/src/services/climate-control.service.d.ts +8 -2
  109. package/dist/src/services/climate-control.service.d.ts.map +1 -1
  110. package/dist/src/services/climate-control.service.js +53 -59
  111. package/dist/src/services/climate-control.service.js.map +1 -1
  112. package/dist/src/services/hot-water-tank.service.d.ts +6 -2
  113. package/dist/src/services/hot-water-tank.service.d.ts.map +1 -1
  114. package/dist/src/services/hot-water-tank.service.js +31 -34
  115. package/dist/src/services/hot-water-tank.service.js.map +1 -1
  116. package/dist/src/types/daikin-enums.js +12 -12
  117. package/dist/src/types/daikin-enums.js.map +1 -1
  118. package/dist/src/types/device-capabilities.d.ts +1 -1
  119. package/dist/src/types/device-capabilities.d.ts.map +1 -1
  120. package/dist/src/utils/log-context.d.ts +23 -23
  121. package/dist/src/utils/log-context.d.ts.map +1 -1
  122. package/dist/src/utils/log-context.js +28 -28
  123. package/dist/src/utils/log-context.js.map +1 -1
  124. package/dist/src/utils/strings.d.ts.map +1 -1
  125. package/dist/src/utils/strings.js.map +1 -1
  126. package/dist/src/utils/update-mapper.d.ts +16 -16
  127. package/dist/src/utils/update-mapper.d.ts.map +1 -1
  128. package/dist/src/utils/update-mapper.js +14 -14
  129. package/dist/src/utils/update-mapper.js.map +1 -1
  130. package/homebridge-ui/public/index.html +24 -24
  131. package/homebridge-ui/public/lib/kit.css +253 -0
  132. package/homebridge-ui/public/lib/kit.js +133 -0
  133. package/homebridge-ui/public/script.js +957 -898
  134. package/homebridge-ui/public/styles.css +0 -1
  135. package/homebridge-ui/server.js +739 -695
  136. package/package.json +30 -25
  137. package/.claude/settings.json +0 -3
  138. package/.claude/settings.local.json +0 -24
  139. package/CHANGELOG.md +0 -114
  140. package/CLAUDE.md +0 -269
  141. package/config.md +0 -2
  142. package/docs/ARCHITECTURE.md +0 -645
  143. package/docs/IMPLEMENTATION_GUIDE.md +0 -899
  144. package/docs/IMPROVEMENTS_SUMMARY.md +0 -415
  145. package/docs/NEXT_STEPS.md +0 -368
  146. package/docs/Screenshot 2024-07-04 at 18.41.28.png +0 -0
  147. package/docs/TROUBLESHOOTING.md +0 -475
  148. package/docs/api-response-for-BRP069A8x.json +0 -520
  149. package/docs/api-response-for-BRP069C4x-2.json +0 -881
  150. package/docs/api-response-for-BRP069C4x.json +0 -916
  151. package/docs/api-response-for-altherma.json +0 -759
  152. package/docs/api-response-for-altherma2.json +0 -2735
  153. package/docs/api-response-with-multiple-devices-incl-heatpump.json +0 -2544
  154. package/docs/cr-insance-altherma-id-0.json +0 -834
  155. package/docs/mock-air-to-air-dx23.json +0 -759
  156. package/docs/mock-air-to-air-dx4.json +0 -1134
  157. package/docs/mock-airpurifier-with-humidifier.json +0 -732
  158. package/docs/mock-airpurifier.json +0 -450
  159. package/docs/mock-altherma-air-to-water-lan.json +0 -845
  160. package/docs/mock-altherma-air-to-water-wlan.json +0 -845
  161. package/docs/mock-d2cnd-gas-boiler.json +0 -649
  162. package/docs/setpointmode-vs-controlmode-vs-setpoints-vs-sensorydata.txt +0 -6
  163. package/images/fan-speed.jpeg +0 -0
  164. package/images/homekit-controls.jpeg +0 -0
  165. package/images/homekit-settings.jpeg +0 -0
  166. package/images/swing-mode.png +0 -0
  167. package/jest.config.ts +0 -21
  168. package/test/fixtures/altherma-crSense-2.ts +0 -834
  169. package/test/fixtures/altherma-fraction.ts +0 -718
  170. package/test/fixtures/altherma-heat-pump-2.ts +0 -479
  171. package/test/fixtures/altherma-heat-pump.ts +0 -757
  172. package/test/fixtures/altherma-miladcerkic-off.ts +0 -524
  173. package/test/fixtures/altherma-miladcerkic.ts +0 -524
  174. package/test/fixtures/altherma-v1ckoeln.ts +0 -644
  175. package/test/fixtures/altherma-with-embedded-id-zero.ts +0 -834
  176. package/test/fixtures/dx23-airco-2.ts +0 -343
  177. package/test/fixtures/dx23-airco.ts +0 -518
  178. package/test/fixtures/dx4-airco.ts +0 -914
  179. package/test/fixtures/unknown-jan.ts +0 -488
  180. package/test/fixtures/unknown-kitchen-guests.ts +0 -488
  181. package/test/hbConfig/.daikin-mobile-tokenset +0 -8
  182. package/test/hbConfig/.uix-dashboard.json +0 -1
  183. package/test/hbConfig/.uix-secrets +0 -1
  184. package/test/hbConfig/accessories/.cachedAccessories.bak +0 -1
  185. package/test/hbConfig/accessories/cachedAccessories +0 -1
  186. package/test/hbConfig/accessories/uiAccessoriesLayout.json +0 -1
  187. package/test/hbConfig/auth.json +0 -10
  188. package/test/hbConfig/backups/config-backups/config.json.1767953686461 +0 -25
  189. package/test/hbConfig/backups/config-backups/config.json.1767953695236 +0 -29
  190. package/test/hbConfig/backups/config-backups/config.json.1767953814763 +0 -29
  191. package/test/hbConfig/backups/config-backups/config.json.1767953823101 +0 -29
  192. package/test/hbConfig/backups/config-backups/config.json.1767954822835 +0 -29
  193. package/test/hbConfig/backups/config-backups/config.json.1767954859218 +0 -29
  194. package/test/hbConfig/backups/config-backups/config.json.1767960145503 +0 -33
  195. package/test/hbConfig/backups/config-backups/config.json.1767960168068 +0 -44
  196. package/test/hbConfig/backups/config-backups/config.json.1767960170333 +0 -46
  197. package/test/hbConfig/backups/config-backups/config.json.1767960172731 +0 -44
  198. package/test/hbConfig/backups/config-backups/config.json.1767960179323 +0 -44
  199. package/test/hbConfig/backups/config-backups/config.json.1767960182114 +0 -44
  200. package/test/hbConfig/backups/config-backups/config.json.1767960189302 +0 -44
  201. package/test/hbConfig/backups/config-backups/config.json.1767960195194 +0 -44
  202. package/test/hbConfig/backups/config-backups/config.json.1767960197301 +0 -44
  203. package/test/hbConfig/backups/config-backups/config.json.1767960199151 +0 -44
  204. package/test/hbConfig/backups/config-backups/config.json.1767960199667 +0 -44
  205. package/test/hbConfig/backups/config-backups/config.json.1767960329839 +0 -44
  206. package/test/hbConfig/backups/config-backups/config.json.1767960334503 +0 -44
  207. package/test/hbConfig/backups/config-backups/config.json.1767960336208 +0 -44
  208. package/test/hbConfig/backups/config-backups/config.json.1767960338537 +0 -44
  209. package/test/hbConfig/backups/config-backups/config.json.1767963223953 +0 -44
  210. package/test/hbConfig/backups/config-backups/config.json.1767963241753 +0 -44
  211. package/test/hbConfig/backups/config-backups/config.json.1767963252785 +0 -44
  212. package/test/hbConfig/backups/config-backups/config.json.1767963463944 +0 -44
  213. package/test/hbConfig/backups/config-backups/config.json.1767963834475 +0 -44
  214. package/test/hbConfig/backups/config-backups/config.json.1767963838474 +0 -44
  215. package/test/hbConfig/backups/config-backups/config.json.1767963843066 +0 -44
  216. package/test/hbConfig/backups/config-backups/config.json.1767965217715 +0 -44
  217. package/test/hbConfig/backups/config-backups/config.json.1767965419624 +0 -25
  218. package/test/hbConfig/backups/config-backups/config.json.1767965870934 +0 -32
  219. package/test/hbConfig/backups/config-backups/config.json.1767977675045 +0 -32
  220. package/test/hbConfig/backups/config-backups/config.json.1767977677222 +0 -33
  221. package/test/hbConfig/backups/config-backups/config.json.1767977710226 +0 -33
  222. package/test/hbConfig/backups/config-backups/config.json.1767977741397 +0 -33
  223. package/test/hbConfig/backups/config-backups/config.json.1767977977093 +0 -35
  224. package/test/hbConfig/backups/config-backups/config.json.1767977981773 +0 -35
  225. package/test/hbConfig/backups/config-backups/config.json.1767977986514 +0 -35
  226. package/test/hbConfig/backups/config-backups/config.json.1767977991174 +0 -35
  227. package/test/hbConfig/backups/config-backups/config.json.1767979424487 +0 -35
  228. package/test/hbConfig/backups/config-backups/config.json.1767979424987 +0 -35
  229. package/test/hbConfig/backups/config-backups/config.json.1767979432646 +0 -47
  230. package/test/hbConfig/backups/config-backups/config.json.1767979433150 +0 -47
  231. package/test/hbConfig/backups/config-backups/config.json.1767979436933 +0 -47
  232. package/test/hbConfig/backups/config-backups/config.json.1767979437438 +0 -47
  233. package/test/hbConfig/backups/config-backups/config.json.1767979441676 +0 -47
  234. package/test/hbConfig/backups/config-backups/config.json.1767979442180 +0 -47
  235. package/test/hbConfig/backups/config-backups/config.json.1767979466735 +0 -47
  236. package/test/hbConfig/backups/config-backups/config.json.1767979903636 +0 -47
  237. package/test/hbConfig/backups/config-backups/config.json.1767979904135 +0 -47
  238. package/test/hbConfig/backups/config-backups/config.json.1767979906606 +0 -47
  239. package/test/hbConfig/backups/config-backups/config.json.1767979907108 +0 -47
  240. package/test/hbConfig/backups/config-backups/config.json.1767988702341 +0 -47
  241. package/test/hbConfig/backups/config-backups/config.json.1767988702837 +0 -47
  242. package/test/hbConfig/backups/config-backups/config.json.1767988713159 +0 -47
  243. package/test/hbConfig/backups/config-backups/config.json.1767988713664 +0 -47
  244. package/test/hbConfig/backups/config-backups/config.json.1767988918139 +0 -47
  245. package/test/hbConfig/backups/config-backups/config.json.1767988918639 +0 -47
  246. package/test/hbConfig/backups/config-backups/config.json.1767988921120 +0 -47
  247. package/test/hbConfig/backups/config-backups/config.json.1767988921624 +0 -47
  248. package/test/hbConfig/backups/config-backups/config.json.1767988930307 +0 -47
  249. package/test/hbConfig/backups/config-backups/config.json.1767988935070 +0 -47
  250. package/test/hbConfig/backups/config-backups/config.json.1767988935574 +0 -47
  251. package/test/hbConfig/backups/config-backups/config.json.1767989710262 +0 -47
  252. package/test/hbConfig/backups/config-backups/config.json.1767989710760 +0 -47
  253. package/test/hbConfig/backups/config-backups/config.json.1767989729668 +0 -47
  254. package/test/hbConfig/backups/config-backups/config.json.1767990295225 +0 -47
  255. package/test/hbConfig/backups/config-backups/config.json.1767990479921 +0 -47
  256. package/test/hbConfig/backups/config-backups/config.json.1767990481702 +0 -49
  257. package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768010187391.tar.gz +0 -0
  258. package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768096587387.tar.gz +0 -0
  259. package/test/hbConfig/backups/instance-backups/homebridge-backup-1E4A432551BA.1768182987404.tar.gz +0 -0
  260. package/test/hbConfig/config.json +0 -47
  261. package/test/hbConfig/daikin-cloud-certs/server.crt +0 -22
  262. package/test/hbConfig/daikin-cloud-certs/server.key +0 -28
  263. package/test/hbConfig/persist/AccessoryInfo.1E4A432551BA.json +0 -1
  264. package/test/hbConfig/persist/IdentifierCache.1E4A432551BA.json +0 -1
  265. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14758 +0 -1
  266. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14759 +0 -1
  267. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14760 +0 -1
  268. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14761 +0 -1
  269. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14762 +0 -1
  270. package/test/hbConfig/tmp/daikin_request/api.onecta.daikineurope.com_01-09-2026-23-29-52/request_14764 +0 -1
  271. package/test/helpers/test-isolation.ts +0 -228
  272. package/test/integration/air-conditioning.test.ts +0 -396
  273. package/test/integration/altherma.test.ts +0 -279
  274. package/test/integration/platform.test.ts +0 -118
  275. package/test/mobile-tokens.json +0 -8
  276. package/test/mocks/index.ts +0 -27
  277. package/test/test-gigya-auth.js +0 -443
  278. package/test/test-mobile-oauth.js +0 -175
  279. package/test/test-websocket-mobile.js +0 -123
  280. package/test/test-websocket.js +0 -116
  281. package/test/unit/api/__snapshots__/daikinCloud.test.ts.snap +0 -1320
  282. package/test/unit/api/daikin-api.test.ts +0 -442
  283. package/test/unit/api/daikin-cloud-repository.test.ts +0 -107
  284. package/test/unit/api/daikin-oauth.test.ts +0 -214
  285. package/test/unit/api/daikinCloud.test.ts +0 -12
  286. package/test/unit/api/token-storage.test.ts +0 -90
  287. package/test/unit/config/config-manager.test.ts +0 -271
  288. package/test/unit/device/daikin-device.test.ts +0 -73
  289. package/test/unit/services/hot-water-tank.service.test.ts +0 -123
  290. package/test/unit/utils/log-context.test.ts +0 -271
  291. package/test/unit/utils/update-mapper.test.ts +0 -404
@@ -1,123 +0,0 @@
1
- import {HotWaterTankService} from '../../../src/services';
2
- import {DaikinCloudDevice, DaikinApi} from '../../../src/api';
3
- import {MockPlatformConfig} from '../../mocks';
4
- import {DaikinCloudAccessoryContext, DaikinCloudPlatform} from '../../../src/platform';
5
- import {PlatformAccessory} from 'homebridge/lib/platformAccessory';
6
- import {Characteristic, uuid} from 'hap-nodejs';
7
- import {althermaHeatPump} from '../../fixtures/altherma-heat-pump';
8
-
9
- import {HomebridgeAPI} from 'homebridge/lib/api.js';
10
- import {Logger} from 'homebridge/lib/logger.js';
11
-
12
- // Helper to get management point data from the device
13
- const getManagementPoint = (device: DaikinCloudDevice, embeddedId: string): any => {
14
- return (device as any).rawData.managementPoints.find((mp: any) => mp.embeddedId === embeddedId);
15
- };
16
-
17
- // Use fake timers to prevent tests from hanging due to setInterval/setTimeout in platform
18
- beforeEach(() => {
19
- jest.useFakeTimers();
20
- });
21
-
22
- afterEach(() => {
23
- jest.clearAllTimers();
24
- jest.useRealTimers();
25
- });
26
-
27
- describe('HotWaterTankService', () => {
28
- let accessory: PlatformAccessory<DaikinCloudAccessoryContext>;
29
- let service: HotWaterTankService;
30
-
31
- const EMBEDDED_ID = 'domesticHotWaterTank';
32
-
33
- beforeEach(() => {
34
- const mockApi = {} as DaikinApi;
35
- accessory = new PlatformAccessory<DaikinCloudAccessoryContext>('ACCESSORY_NAME', uuid.generate('ACCESSORY_UUID'));
36
- // Use a deep copy of the fixture to isolate test mutations
37
- accessory.context['device'] = new DaikinCloudDevice(JSON.parse(JSON.stringify(althermaHeatPump)) as any, mockApi);
38
- accessory.context.device.getLastUpdated = jest.fn().mockReturnValue(new Date(1987, 0, 19, 0, 0, 0, 0));
39
-
40
- const platform = new DaikinCloudPlatform(new Logger(), new MockPlatformConfig(true), new HomebridgeAPI());
41
-
42
- service = new HotWaterTankService(platform, accessory, EMBEDDED_ID);
43
- });
44
-
45
- it('should get the current heating cooling state', async () => {
46
- expect(await service.handleHotWaterTankCurrentHeatingCoolingStateGet()).toBe(Characteristic.CurrentHeatingCoolingState.HEAT);
47
-
48
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['onOffMode'] = { value: 'off' };
49
-
50
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.CurrentHeatingCoolingState.OFF);
51
- });
52
-
53
- it('should get the current temperature', async () => {
54
- expect(await service.handleHotWaterTankCurrentTemperatureGet()).toBe(48);
55
- });
56
-
57
- it('should get the target heating cooling temperature', async () => {
58
- expect(await service.handleHotWaterTankHeatingTargetTemperatureGet()).toBe(48);
59
- });
60
-
61
- it('should get the target heating cooling state', async () => {
62
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.HEAT);
63
-
64
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
65
- 'settable': true,
66
- 'values': [
67
- 'auto',
68
- 'dry',
69
- 'cooling',
70
- 'heating',
71
- 'fanOnly',
72
- ],
73
- 'value': 'cooling',
74
- };
75
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.COOL);
76
-
77
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
78
- 'settable': true,
79
- 'values': [
80
- 'auto',
81
- 'dry',
82
- 'cooling',
83
- 'heating',
84
- 'fanOnly',
85
- ],
86
- 'value': 'auto',
87
- };
88
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.AUTO);
89
-
90
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
91
- 'settable': true,
92
- 'values': [
93
- 'auto',
94
- 'dry',
95
- 'cooling',
96
- 'heating',
97
- 'fanOnly',
98
- ],
99
- 'value': 'fanOnly',
100
- };
101
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.AUTO);
102
-
103
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['operationMode'] = {
104
- 'settable': true,
105
- 'values': [
106
- 'auto',
107
- 'dry',
108
- 'cooling',
109
- 'heating',
110
- 'fanOnly',
111
- ],
112
- 'value': 'dry',
113
- };
114
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.AUTO);
115
-
116
- getManagementPoint(accessory.context.device, EMBEDDED_ID)['onOffMode'] = { value: 'off' };
117
- expect(await service.handleHotWaterTankTargetHeatingCoolingStateGet()).toBe(Characteristic.TargetHeatingCoolingState.OFF);
118
- });
119
-
120
- it('should get the powerful mode', async () => {
121
- expect(await service.handlePowerfulModeGet()).toBe(false);
122
- });
123
- });
@@ -1,271 +0,0 @@
1
- /**
2
- * StructuredLogger Tests
3
- */
4
-
5
- import {
6
- StructuredLogger,
7
- LogLevel,
8
- LogCategory,
9
- createLogger,
10
- createCategoryLogger,
11
- createDeviceLogger,
12
- } from '../../../src/utils/log-context';
13
- import {Logger} from 'homebridge';
14
-
15
- describe('StructuredLogger', () => {
16
- let mockLogger: Logger;
17
- let logger: StructuredLogger;
18
-
19
- beforeEach(() => {
20
- mockLogger = {
21
- debug: jest.fn(),
22
- info: jest.fn(),
23
- warn: jest.fn(),
24
- error: jest.fn(),
25
- log: jest.fn(),
26
- } as unknown as Logger;
27
-
28
- logger = new StructuredLogger(mockLogger);
29
- });
30
-
31
- describe('basic logging', () => {
32
- it('should log debug messages', () => {
33
- logger.debug('Debug message');
34
- expect(mockLogger.debug).toHaveBeenCalledWith('Debug message');
35
- });
36
-
37
- it('should log info messages', () => {
38
- logger.info('Info message');
39
- expect(mockLogger.info).toHaveBeenCalledWith('Info message');
40
- });
41
-
42
- it('should log warn messages', () => {
43
- logger.warn('Warning message');
44
- expect(mockLogger.warn).toHaveBeenCalledWith('Warning message');
45
- });
46
-
47
- it('should log error messages', () => {
48
- logger.error('Error message');
49
- expect(mockLogger.error).toHaveBeenCalledWith('Error message');
50
- });
51
- });
52
-
53
- describe('context formatting', () => {
54
- it('should include category in log message', () => {
55
- logger.log(LogLevel.INFO, 'Test', {category: LogCategory.API});
56
- expect(mockLogger.info).toHaveBeenCalledWith('[API] Test');
57
- });
58
-
59
- it('should include device name in log message', () => {
60
- logger.log(LogLevel.INFO, 'Test', {deviceName: 'Living Room'});
61
- expect(mockLogger.info).toHaveBeenCalledWith('[Living Room] Test');
62
- });
63
-
64
- it('should include device ID when no name', () => {
65
- logger.log(LogLevel.INFO, 'Test', {deviceId: 'device123'});
66
- expect(mockLogger.info).toHaveBeenCalledWith('[Device:device123] Test');
67
- });
68
-
69
- it('should include operation in log message', () => {
70
- logger.log(LogLevel.INFO, 'Test', {operation: 'update'});
71
- expect(mockLogger.info).toHaveBeenCalledWith('(update) Test');
72
- });
73
-
74
- it('should include embedded ID', () => {
75
- logger.log(LogLevel.INFO, 'Test', {embeddedId: 'climateControl'});
76
- expect(mockLogger.info).toHaveBeenCalledWith('[climateControl] Test');
77
- });
78
-
79
- it('should include feature name', () => {
80
- logger.log(LogLevel.INFO, 'Test', {feature: 'PowerfulMode'});
81
- expect(mockLogger.info).toHaveBeenCalledWith('[Feature:PowerfulMode] Test');
82
- });
83
-
84
- it('should combine multiple context fields', () => {
85
- logger.log(LogLevel.INFO, 'Test', {
86
- category: LogCategory.DEVICE,
87
- deviceName: 'Kitchen',
88
- operation: 'setState',
89
- });
90
- expect(mockLogger.info).toHaveBeenCalledWith('[Device] [Kitchen] (setState) Test');
91
- });
92
-
93
- it('should append metadata as JSON', () => {
94
- logger.log(LogLevel.INFO, 'Test', {
95
- metadata: {temp: 25, mode: 'cool'},
96
- });
97
-
98
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
99
- expect(logCall).toContain('{"temp":25,"mode":"cool"}');
100
- });
101
- });
102
-
103
- describe('default context', () => {
104
- it('should merge default context with call context', () => {
105
- const loggerWithDefaults = new StructuredLogger(mockLogger, {
106
- category: LogCategory.PLATFORM,
107
- });
108
-
109
- loggerWithDefaults.log(LogLevel.INFO, 'Test', {deviceId: 'device123'});
110
-
111
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
112
- expect(logCall).toContain('[Platform]');
113
- expect(logCall).toContain('[Device:device123]');
114
- });
115
-
116
- it('should override default context with call context', () => {
117
- const loggerWithDefaults = new StructuredLogger(mockLogger, {
118
- category: LogCategory.PLATFORM,
119
- });
120
-
121
- loggerWithDefaults.log(LogLevel.INFO, 'Test', {
122
- category: LogCategory.API,
123
- });
124
-
125
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
126
- expect(logCall).toContain('[API]');
127
- expect(logCall).not.toContain('[Platform]');
128
- });
129
-
130
- it('should merge metadata objects', () => {
131
- const loggerWithDefaults = new StructuredLogger(mockLogger, {
132
- metadata: {defaultKey: 'defaultValue'},
133
- });
134
-
135
- loggerWithDefaults.log(LogLevel.INFO, 'Test', {
136
- metadata: {callKey: 'callValue'},
137
- });
138
-
139
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
140
- expect(logCall).toContain('defaultKey');
141
- expect(logCall).toContain('callKey');
142
- });
143
- });
144
-
145
- describe('child logger', () => {
146
- it('should create child logger with additional context', () => {
147
- const child = logger.child({category: LogCategory.DEVICE});
148
- child.info('Test message');
149
-
150
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
151
- expect(logCall).toContain('[Device]');
152
- });
153
-
154
- it('should inherit parent context', () => {
155
- const parent = new StructuredLogger(mockLogger, {
156
- category: LogCategory.PLATFORM,
157
- });
158
-
159
- const child = parent.child({deviceName: 'Kitchen'});
160
- child.info('Test');
161
-
162
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
163
- expect(logCall).toContain('[Platform]');
164
- expect(logCall).toContain('[Kitchen]');
165
- });
166
- });
167
-
168
- describe('log history', () => {
169
- it('should record log entries in history', () => {
170
- logger.info('Message 1');
171
- logger.warn('Message 2');
172
- logger.error('Message 3');
173
-
174
- const history = logger.getHistory();
175
- expect(history).toHaveLength(3);
176
- });
177
-
178
- it('should return limited history', () => {
179
- for (let i = 0; i < 10; i++) {
180
- logger.info(`Message ${i}`);
181
- }
182
-
183
- const history = logger.getHistory(5);
184
- expect(history).toHaveLength(5);
185
- });
186
-
187
- it('should include context in history entries', () => {
188
- logger.info('Test', {category: LogCategory.API, deviceId: 'device123'});
189
-
190
- const history = logger.getHistory();
191
- expect(history[0].message).toBe('Test');
192
- expect(history[0].context?.category).toBe(LogCategory.API);
193
- expect(history[0].context?.deviceId).toBe('device123');
194
- });
195
-
196
- it('should include timestamp in history entries', () => {
197
- const before = new Date();
198
- logger.info('Test');
199
- const after = new Date();
200
-
201
- const history = logger.getHistory();
202
- expect(history[0].timestamp.getTime()).toBeGreaterThanOrEqual(before.getTime());
203
- expect(history[0].timestamp.getTime()).toBeLessThanOrEqual(after.getTime());
204
- });
205
-
206
- it('should clear history', () => {
207
- logger.info('Message 1');
208
- logger.info('Message 2');
209
- expect(logger.getHistory()).toHaveLength(2);
210
-
211
- logger.clearHistory();
212
- expect(logger.getHistory()).toHaveLength(0);
213
- });
214
- });
215
-
216
- describe('helper functions', () => {
217
- it('createLogger should create StructuredLogger', () => {
218
- const newLogger = createLogger(mockLogger);
219
- expect(newLogger).toBeInstanceOf(StructuredLogger);
220
- });
221
-
222
- it('createLogger should accept default context', () => {
223
- const newLogger = createLogger(mockLogger, {category: LogCategory.API});
224
- newLogger.info('Test');
225
-
226
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
227
- expect(logCall).toContain('[API]');
228
- });
229
-
230
- it('createCategoryLogger should create logger with category', () => {
231
- const newLogger = createCategoryLogger(mockLogger, LogCategory.WEBSOCKET);
232
- newLogger.info('Test');
233
-
234
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
235
- expect(logCall).toContain('[WebSocket]');
236
- });
237
-
238
- it('createDeviceLogger should create logger with device context', () => {
239
- const newLogger = createDeviceLogger(mockLogger, 'device123', 'Kitchen AC');
240
- newLogger.info('Test');
241
-
242
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
243
- expect(logCall).toContain('[Device]');
244
- expect(logCall).toContain('[Kitchen AC]');
245
- });
246
- });
247
-
248
- describe('edge cases', () => {
249
- it('should handle empty message', () => {
250
- logger.info('');
251
- expect(mockLogger.info).toHaveBeenCalled();
252
- });
253
-
254
- it('should handle undefined context', () => {
255
- logger.info('Test', undefined);
256
- expect(mockLogger.info).toHaveBeenCalledWith('Test');
257
- });
258
-
259
- it('should handle empty metadata', () => {
260
- logger.info('Test', {metadata: {}});
261
-
262
- const logCall = (mockLogger.info as jest.Mock).mock.calls[0][0];
263
- expect(logCall).toBe('Test');
264
- });
265
-
266
- it('should handle special characters in messages', () => {
267
- logger.info('Test [brackets] (parens) {braces}');
268
- expect(mockLogger.info).toHaveBeenCalled();
269
- });
270
- });
271
- });