node-red-contrib-huemagic 4.2.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +89 -5
- package/README.md +506 -123
- package/examples/Deutsch/Hue Automation.json +176 -0
- package/examples/Deutsch/Hue Bridge.json +256 -0
- package/examples/Deutsch/Hue Brightness.json +150 -0
- package/examples/Deutsch/Hue Buttons.json +88 -0
- package/examples/Deutsch/Hue Contact.json +150 -0
- package/examples/Deutsch/Hue Group.json +658 -0
- package/examples/Deutsch/Hue Light.json +893 -0
- package/examples/Deutsch/Hue Magic.json +148 -0
- package/examples/Deutsch/Hue Motion.json +150 -0
- package/examples/Deutsch/Hue Rules.json +150 -0
- package/examples/Deutsch/Hue Scene.json +178 -0
- package/examples/Deutsch/Hue Speaker.json +274 -0
- package/examples/Deutsch/Hue Sync Box.json +378 -0
- package/examples/Deutsch/Hue Temperature.json +150 -0
- package/examples/English/Hue Automation.json +176 -0
- package/examples/{Hue Bridge.json → English/Hue Bridge.json } +1 -1
- package/examples/{Hue Brightness.json → English/Hue Brightness.json } +1 -1
- package/examples/{Hue Buttons.json → English/Hue Buttons.json } +1 -1
- package/examples/English/Hue Contact.json +150 -0
- package/examples/{Hue Group.json → English/Hue Group.json } +1 -1
- package/examples/{Hue Light.json → English/Hue Light.json } +1 -1
- package/examples/{Hue Magic.json → English/Hue Magic.json } +1 -1
- package/examples/{Hue Motion.json → English/Hue Motion.json } +1 -1
- package/examples/{Hue Rules.json → English/Hue Rules.json } +1 -1
- package/examples/{Hue Scene.json → English/Hue Scene.json } +1 -1
- package/examples/English/Hue Speaker.json +274 -0
- package/examples/English/Hue Sync Box.json +378 -0
- package/examples/{Hue Temperature.json → English/Hue Temperature.json } +1 -1
- package/examples/Espa/303/261ol/Hue Automation.json" +176 -0
- package/examples/Espa/303/261ol/Hue Bridge.json" +256 -0
- package/examples/Espa/303/261ol/Hue Brightness.json" +150 -0
- package/examples/Espa/303/261ol/Hue Buttons.json" +88 -0
- package/examples/Espa/303/261ol/Hue Contact.json" +150 -0
- package/examples/Espa/303/261ol/Hue Group.json" +658 -0
- package/examples/Espa/303/261ol/Hue Light.json" +893 -0
- package/examples/Espa/303/261ol/Hue Magic.json" +148 -0
- package/examples/Espa/303/261ol/Hue Motion.json" +150 -0
- package/examples/Espa/303/261ol/Hue Rules.json" +150 -0
- package/examples/Espa/303/261ol/Hue Scene.json" +178 -0
- package/examples/Espa/303/261ol/Hue Speaker.json" +274 -0
- package/examples/Espa/303/261ol/Hue Sync Box.json" +378 -0
- package/examples/Espa/303/261ol/Hue Temperature.json" +150 -0
- package/examples/Fran/303/247ais/Hue Automation.json" +176 -0
- package/examples/Fran/303/247ais/Hue Bridge.json" +256 -0
- package/examples/Fran/303/247ais/Hue Brightness.json" +150 -0
- package/examples/Fran/303/247ais/Hue Buttons.json" +88 -0
- package/examples/Fran/303/247ais/Hue Contact.json" +150 -0
- package/examples/Fran/303/247ais/Hue Group.json" +658 -0
- package/examples/Fran/303/247ais/Hue Light.json" +893 -0
- package/examples/Fran/303/247ais/Hue Magic.json" +148 -0
- package/examples/Fran/303/247ais/Hue Motion.json" +150 -0
- package/examples/Fran/303/247ais/Hue Rules.json" +150 -0
- package/examples/Fran/303/247ais/Hue Scene.json" +178 -0
- package/examples/Fran/303/247ais/Hue Speaker.json" +274 -0
- package/examples/Fran/303/247ais/Hue Sync Box.json" +378 -0
- package/examples/Fran/303/247ais/Hue Temperature.json" +150 -0
- package/examples/Italiano/Hue Automation.json +176 -0
- package/examples/Italiano/Hue Bridge.json +256 -0
- package/examples/Italiano/Hue Brightness.json +150 -0
- package/examples/Italiano/Hue Buttons.json +88 -0
- package/examples/Italiano/Hue Contact.json +150 -0
- package/examples/Italiano/Hue Group.json +658 -0
- package/examples/Italiano/Hue Light.json +893 -0
- package/examples/Italiano/Hue Magic.json +148 -0
- package/examples/Italiano/Hue Motion.json +150 -0
- package/examples/Italiano/Hue Rules.json +150 -0
- package/examples/Italiano/Hue Scene.json +178 -0
- package/examples/Italiano/Hue Speaker.json +274 -0
- package/examples/Italiano/Hue Sync Box.json +378 -0
- package/examples/Italiano/Hue Temperature.json +150 -0
- package/examples/Nederlands/Hue Automation.json +176 -0
- package/examples/Nederlands/Hue Bridge.json +256 -0
- package/examples/Nederlands/Hue Brightness.json +150 -0
- package/examples/Nederlands/Hue Buttons.json +88 -0
- package/examples/Nederlands/Hue Contact.json +150 -0
- package/examples/Nederlands/Hue Group.json +658 -0
- package/examples/Nederlands/Hue Light.json +893 -0
- package/examples/Nederlands/Hue Magic.json +148 -0
- package/examples/Nederlands/Hue Motion.json +150 -0
- package/examples/Nederlands/Hue Rules.json +150 -0
- package/examples/Nederlands/Hue Scene.json +178 -0
- package/examples/Nederlands/Hue Speaker.json +274 -0
- package/examples/Nederlands/Hue Sync Box.json +378 -0
- package/examples/Nederlands/Hue Temperature.json +150 -0
- package/examples/Polski/Hue Automation.json +176 -0
- package/examples/Polski/Hue Bridge.json +256 -0
- package/examples/Polski/Hue Brightness.json +150 -0
- package/examples/Polski/Hue Buttons.json +88 -0
- package/examples/Polski/Hue Contact.json +150 -0
- package/examples/Polski/Hue Group.json +658 -0
- package/examples/Polski/Hue Light.json +893 -0
- package/examples/Polski/Hue Magic.json +148 -0
- package/examples/Polski/Hue Motion.json +150 -0
- package/examples/Polski/Hue Rules.json +150 -0
- package/examples/Polski/Hue Scene.json +178 -0
- package/examples/Polski/Hue Speaker.json +274 -0
- package/examples/Polski/Hue Sync Box.json +378 -0
- package/examples/Polski/Hue Temperature.json +150 -0
- package/examples/Portugu/303/252s/Hue Automation.json" +176 -0
- package/examples/Portugu/303/252s/Hue Bridge.json" +256 -0
- package/examples/Portugu/303/252s/Hue Brightness.json" +150 -0
- package/examples/Portugu/303/252s/Hue Buttons.json" +88 -0
- package/examples/Portugu/303/252s/Hue Contact.json" +150 -0
- package/examples/Portugu/303/252s/Hue Group.json" +658 -0
- package/examples/Portugu/303/252s/Hue Light.json" +893 -0
- package/examples/Portugu/303/252s/Hue Magic.json" +148 -0
- package/examples/Portugu/303/252s/Hue Motion.json" +150 -0
- package/examples/Portugu/303/252s/Hue Rules.json" +150 -0
- package/examples/Portugu/303/252s/Hue Scene.json" +178 -0
- package/examples/Portugu/303/252s/Hue Speaker.json" +274 -0
- package/examples/Portugu/303/252s/Hue Sync Box.json" +378 -0
- package/examples/Portugu/303/252s/Hue Temperature.json" +150 -0
- package/examples/T/303/274rk/303/247e/Hue Automation.json" +176 -0
- package/examples/T/303/274rk/303/247e/Hue Bridge.json" +256 -0
- package/examples/T/303/274rk/303/247e/Hue Brightness.json" +150 -0
- package/examples/T/303/274rk/303/247e/Hue Buttons.json" +88 -0
- package/examples/T/303/274rk/303/247e/Hue Contact.json" +150 -0
- package/examples/T/303/274rk/303/247e/Hue Group.json" +658 -0
- package/examples/T/303/274rk/303/247e/Hue Light.json" +893 -0
- package/examples/T/303/274rk/303/247e/Hue Magic.json" +148 -0
- package/examples/T/303/274rk/303/247e/Hue Motion.json" +150 -0
- package/examples/T/303/274rk/303/247e/Hue Rules.json" +150 -0
- package/examples/T/303/274rk/303/247e/Hue Scene.json" +178 -0
- package/examples/T/303/274rk/303/247e/Hue Speaker.json" +274 -0
- package/examples/T/303/274rk/303/247e/Hue Sync Box.json" +378 -0
- package/examples/T/303/274rk/303/247e/Hue Temperature.json" +150 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Automation.json" +176 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Bridge.json" +256 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Brightness.json" +150 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Buttons.json" +88 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Contact.json" +150 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Group.json" +658 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Light.json" +893 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Magic.json" +148 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Motion.json" +150 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Rules.json" +150 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Scene.json" +178 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Speaker.json" +274 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Sync Box.json" +378 -0
- package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Temperature.json" +150 -0
- package/huemagic/assets/huemagic-examples.gif +0 -0
- package/huemagic/hue-automation.html +218 -0
- package/huemagic/hue-automation.js +173 -0
- package/huemagic/hue-bridge-config.html +39 -32
- package/huemagic/hue-bridge-config.js +290 -99
- package/huemagic/hue-bridge.html +8 -8
- package/huemagic/hue-bridge.js +29 -4
- package/huemagic/hue-brightness.html +21 -9
- package/huemagic/hue-brightness.js +20 -10
- package/huemagic/hue-buttons.html +16 -9
- package/huemagic/hue-buttons.js +90 -27
- package/huemagic/hue-contact.html +218 -0
- package/huemagic/hue-contact.js +209 -0
- package/huemagic/hue-group.html +16 -9
- package/huemagic/hue-group.js +141 -179
- package/huemagic/hue-light.html +19 -12
- package/huemagic/hue-light.js +222 -167
- package/huemagic/hue-magic.html +3 -5
- package/huemagic/hue-motion.html +16 -9
- package/huemagic/hue-motion.js +37 -8
- package/huemagic/hue-rules.html +16 -9
- package/huemagic/hue-rules.js +16 -8
- package/huemagic/hue-scene.html +9 -5
- package/huemagic/hue-scene.js +52 -16
- package/huemagic/hue-speaker.html +218 -0
- package/huemagic/hue-speaker.js +257 -0
- package/huemagic/hue-syncbox-config.html +123 -0
- package/huemagic/hue-syncbox-config.js +179 -0
- package/huemagic/hue-syncbox.html +82 -0
- package/huemagic/hue-syncbox.js +274 -0
- package/huemagic/hue-temperature.html +21 -9
- package/huemagic/hue-temperature.js +18 -10
- package/huemagic/icons/hue-automation.png +0 -0
- package/huemagic/icons/hue-automation.svg +3 -0
- package/huemagic/icons/hue-contact.png +0 -0
- package/huemagic/icons/hue-contact.svg +4 -0
- package/huemagic/icons/hue-speaker.png +0 -0
- package/huemagic/icons/hue-speaker.svg +6 -0
- package/huemagic/icons/hue-syncbox.png +0 -0
- package/huemagic/icons/hue-syncbox.svg +7 -0
- package/huemagic/locales/de/hue-automation.html +59 -0
- package/huemagic/locales/de/hue-automation.json +33 -0
- package/huemagic/locales/de/hue-bridge-config.json +23 -12
- package/huemagic/locales/de/hue-bridge.html +7 -4
- package/huemagic/locales/de/hue-bridge.json +9 -10
- package/huemagic/locales/de/hue-brightness.html +9 -6
- package/huemagic/locales/de/hue-brightness.json +13 -9
- package/huemagic/locales/de/hue-buttons.html +5 -4
- package/huemagic/locales/de/hue-buttons.json +22 -8
- package/huemagic/locales/de/hue-contact.html +67 -0
- package/huemagic/locales/de/hue-contact.json +35 -0
- package/huemagic/locales/de/hue-group.html +17 -6
- package/huemagic/locales/de/hue-group.json +16 -9
- package/huemagic/locales/de/hue-light.html +6 -6
- package/huemagic/locales/de/hue-light.json +17 -9
- package/huemagic/locales/de/hue-magic.html +1 -1
- package/huemagic/locales/de/hue-magic.json +6 -8
- package/huemagic/locales/de/hue-motion.html +4 -4
- package/huemagic/locales/de/hue-motion.json +14 -9
- package/huemagic/locales/de/hue-rules.html +2 -2
- package/huemagic/locales/de/hue-rules.json +10 -9
- package/huemagic/locales/de/hue-scene.html +11 -3
- package/huemagic/locales/de/hue-scene.json +9 -9
- package/huemagic/locales/de/hue-speaker.html +80 -0
- package/huemagic/locales/de/hue-speaker.json +38 -0
- package/huemagic/locales/de/hue-syncbox-config.html +19 -0
- package/huemagic/locales/de/hue-syncbox-config.json +25 -0
- package/huemagic/locales/de/hue-syncbox.html +86 -0
- package/huemagic/locales/de/hue-syncbox.json +30 -0
- package/huemagic/locales/de/hue-temperature.html +7 -5
- package/huemagic/locales/de/hue-temperature.json +13 -9
- package/huemagic/locales/el/hue-automation.html +59 -0
- package/huemagic/locales/el/hue-automation.json +33 -0
- package/huemagic/locales/el/hue-bridge-config.html +31 -0
- package/huemagic/locales/el/hue-bridge-config.json +40 -0
- package/huemagic/locales/el/hue-bridge.html +96 -0
- package/huemagic/locales/el/hue-bridge.json +26 -0
- package/huemagic/locales/el/hue-brightness.html +70 -0
- package/huemagic/locales/el/hue-brightness.json +37 -0
- package/huemagic/locales/el/hue-buttons.html +59 -0
- package/huemagic/locales/el/hue-buttons.json +42 -0
- package/huemagic/locales/el/hue-contact.html +67 -0
- package/huemagic/locales/el/hue-contact.json +35 -0
- package/huemagic/locales/el/hue-group.html +87 -0
- package/huemagic/locales/el/hue-group.json +46 -0
- package/huemagic/locales/el/hue-light.html +97 -0
- package/huemagic/locales/el/hue-light.json +44 -0
- package/huemagic/locales/el/hue-magic.html +68 -0
- package/huemagic/locales/el/hue-magic.json +26 -0
- package/huemagic/locales/el/hue-motion.html +64 -0
- package/huemagic/locales/el/hue-motion.json +36 -0
- package/huemagic/locales/el/hue-rules.html +69 -0
- package/huemagic/locales/el/hue-rules.json +30 -0
- package/huemagic/locales/el/hue-scene.html +43 -0
- package/huemagic/locales/el/hue-scene.json +32 -0
- package/huemagic/locales/el/hue-speaker.html +80 -0
- package/huemagic/locales/el/hue-speaker.json +38 -0
- package/huemagic/locales/el/hue-syncbox-config.html +19 -0
- package/huemagic/locales/el/hue-syncbox-config.json +25 -0
- package/huemagic/locales/el/hue-syncbox.html +86 -0
- package/huemagic/locales/el/hue-syncbox.json +30 -0
- package/huemagic/locales/el/hue-temperature.html +69 -0
- package/huemagic/locales/el/hue-temperature.json +33 -0
- package/huemagic/locales/en/hue-automation.html +59 -0
- package/huemagic/locales/en/hue-automation.json +33 -0
- package/huemagic/locales/en/hue-bridge-config.json +40 -0
- package/huemagic/locales/{en-US → en}/hue-bridge.html +5 -2
- package/huemagic/locales/{en-US → en}/hue-bridge.json +8 -9
- package/huemagic/locales/{en-US → en}/hue-brightness.html +6 -3
- package/huemagic/locales/{en-US → en}/hue-brightness.json +11 -9
- package/huemagic/locales/{en-US → en}/hue-buttons.html +4 -3
- package/huemagic/locales/en/hue-buttons.json +42 -0
- package/huemagic/locales/en/hue-contact.html +67 -0
- package/huemagic/locales/en/hue-contact.json +35 -0
- package/huemagic/locales/{en-US → en}/hue-group.html +16 -5
- package/huemagic/locales/{en-US → en}/hue-group.json +15 -10
- package/huemagic/locales/{en-US → en}/hue-light.html +3 -3
- package/huemagic/locales/en/hue-light.json +44 -0
- package/huemagic/locales/{en-US → en}/hue-magic.html +1 -1
- package/huemagic/locales/{en-US → en}/hue-motion.html +2 -2
- package/huemagic/locales/{en-US → en}/hue-motion.json +12 -9
- package/huemagic/locales/{en-US → en}/hue-rules.html +2 -2
- package/huemagic/locales/{en-US → en}/hue-rules.json +10 -9
- package/huemagic/locales/{en-US → en}/hue-scene.html +11 -3
- package/huemagic/locales/{en-US → en}/hue-scene.json +9 -9
- package/huemagic/locales/en/hue-speaker.html +80 -0
- package/huemagic/locales/en/hue-speaker.json +38 -0
- package/huemagic/locales/en/hue-syncbox-config.html +19 -0
- package/huemagic/locales/en/hue-syncbox-config.json +25 -0
- package/huemagic/locales/en/hue-syncbox.html +86 -0
- package/huemagic/locales/en/hue-syncbox.json +30 -0
- package/huemagic/locales/{en-US → en}/hue-temperature.html +4 -2
- package/huemagic/locales/{en-US → en}/hue-temperature.json +11 -9
- package/huemagic/locales/es/hue-automation.html +59 -0
- package/huemagic/locales/es/hue-automation.json +33 -0
- package/huemagic/locales/es/hue-bridge-config.html +31 -0
- package/huemagic/locales/es/hue-bridge-config.json +40 -0
- package/huemagic/locales/es/hue-bridge.html +96 -0
- package/huemagic/locales/es/hue-bridge.json +26 -0
- package/huemagic/locales/es/hue-brightness.html +70 -0
- package/huemagic/locales/es/hue-brightness.json +37 -0
- package/huemagic/locales/es/hue-buttons.html +59 -0
- package/huemagic/locales/es/hue-buttons.json +42 -0
- package/huemagic/locales/es/hue-contact.html +67 -0
- package/huemagic/locales/es/hue-contact.json +35 -0
- package/huemagic/locales/es/hue-group.html +87 -0
- package/huemagic/locales/es/hue-group.json +46 -0
- package/huemagic/locales/es/hue-light.html +97 -0
- package/huemagic/locales/es/hue-light.json +44 -0
- package/huemagic/locales/es/hue-magic.html +68 -0
- package/huemagic/locales/es/hue-magic.json +26 -0
- package/huemagic/locales/es/hue-motion.html +64 -0
- package/huemagic/locales/es/hue-motion.json +36 -0
- package/huemagic/locales/es/hue-rules.html +69 -0
- package/huemagic/locales/es/hue-rules.json +30 -0
- package/huemagic/locales/es/hue-scene.html +43 -0
- package/huemagic/locales/es/hue-scene.json +32 -0
- package/huemagic/locales/es/hue-speaker.html +80 -0
- package/huemagic/locales/es/hue-speaker.json +38 -0
- package/huemagic/locales/es/hue-syncbox-config.html +19 -0
- package/huemagic/locales/es/hue-syncbox-config.json +25 -0
- package/huemagic/locales/es/hue-syncbox.html +86 -0
- package/huemagic/locales/es/hue-syncbox.json +30 -0
- package/huemagic/locales/es/hue-temperature.html +69 -0
- package/huemagic/locales/es/hue-temperature.json +33 -0
- package/huemagic/locales/fr/hue-automation.html +59 -0
- package/huemagic/locales/fr/hue-automation.json +33 -0
- package/huemagic/locales/fr/hue-bridge-config.html +31 -0
- package/huemagic/locales/fr/hue-bridge-config.json +40 -0
- package/huemagic/locales/fr/hue-bridge.html +96 -0
- package/huemagic/locales/fr/hue-bridge.json +26 -0
- package/huemagic/locales/fr/hue-brightness.html +70 -0
- package/huemagic/locales/fr/hue-brightness.json +37 -0
- package/huemagic/locales/fr/hue-buttons.html +59 -0
- package/huemagic/locales/fr/hue-buttons.json +42 -0
- package/huemagic/locales/fr/hue-contact.html +67 -0
- package/huemagic/locales/fr/hue-contact.json +35 -0
- package/huemagic/locales/fr/hue-group.html +87 -0
- package/huemagic/locales/fr/hue-group.json +46 -0
- package/huemagic/locales/fr/hue-light.html +97 -0
- package/huemagic/locales/fr/hue-light.json +44 -0
- package/huemagic/locales/fr/hue-magic.html +68 -0
- package/huemagic/locales/fr/hue-magic.json +26 -0
- package/huemagic/locales/fr/hue-motion.html +64 -0
- package/huemagic/locales/fr/hue-motion.json +36 -0
- package/huemagic/locales/fr/hue-rules.html +69 -0
- package/huemagic/locales/fr/hue-rules.json +30 -0
- package/huemagic/locales/fr/hue-scene.html +43 -0
- package/huemagic/locales/fr/hue-scene.json +32 -0
- package/huemagic/locales/fr/hue-speaker.html +80 -0
- package/huemagic/locales/fr/hue-speaker.json +38 -0
- package/huemagic/locales/fr/hue-syncbox-config.html +19 -0
- package/huemagic/locales/fr/hue-syncbox-config.json +25 -0
- package/huemagic/locales/fr/hue-syncbox.html +86 -0
- package/huemagic/locales/fr/hue-syncbox.json +30 -0
- package/huemagic/locales/fr/hue-temperature.html +69 -0
- package/huemagic/locales/fr/hue-temperature.json +33 -0
- package/huemagic/locales/it/hue-automation.html +59 -0
- package/huemagic/locales/it/hue-automation.json +33 -0
- package/huemagic/locales/it/hue-bridge-config.html +31 -0
- package/huemagic/locales/it/hue-bridge-config.json +40 -0
- package/huemagic/locales/it/hue-bridge.html +96 -0
- package/huemagic/locales/it/hue-bridge.json +26 -0
- package/huemagic/locales/it/hue-brightness.html +70 -0
- package/huemagic/locales/it/hue-brightness.json +37 -0
- package/huemagic/locales/it/hue-buttons.html +59 -0
- package/huemagic/locales/it/hue-buttons.json +42 -0
- package/huemagic/locales/it/hue-contact.html +67 -0
- package/huemagic/locales/it/hue-contact.json +35 -0
- package/huemagic/locales/it/hue-group.html +87 -0
- package/huemagic/locales/it/hue-group.json +46 -0
- package/huemagic/locales/it/hue-light.html +97 -0
- package/huemagic/locales/it/hue-light.json +44 -0
- package/huemagic/locales/it/hue-magic.html +68 -0
- package/huemagic/locales/it/hue-magic.json +26 -0
- package/huemagic/locales/it/hue-motion.html +64 -0
- package/huemagic/locales/it/hue-motion.json +36 -0
- package/huemagic/locales/it/hue-rules.html +69 -0
- package/huemagic/locales/it/hue-rules.json +30 -0
- package/huemagic/locales/it/hue-scene.html +43 -0
- package/huemagic/locales/it/hue-scene.json +32 -0
- package/huemagic/locales/it/hue-speaker.html +80 -0
- package/huemagic/locales/it/hue-speaker.json +38 -0
- package/huemagic/locales/it/hue-syncbox-config.html +19 -0
- package/huemagic/locales/it/hue-syncbox-config.json +25 -0
- package/huemagic/locales/it/hue-syncbox.html +86 -0
- package/huemagic/locales/it/hue-syncbox.json +30 -0
- package/huemagic/locales/it/hue-temperature.html +69 -0
- package/huemagic/locales/it/hue-temperature.json +33 -0
- package/huemagic/locales/nl/hue-automation.html +59 -0
- package/huemagic/locales/nl/hue-automation.json +33 -0
- package/huemagic/locales/nl/hue-bridge-config.html +31 -0
- package/huemagic/locales/nl/hue-bridge-config.json +40 -0
- package/huemagic/locales/nl/hue-bridge.html +96 -0
- package/huemagic/locales/nl/hue-bridge.json +26 -0
- package/huemagic/locales/nl/hue-brightness.html +70 -0
- package/huemagic/locales/nl/hue-brightness.json +37 -0
- package/huemagic/locales/nl/hue-buttons.html +59 -0
- package/huemagic/locales/nl/hue-buttons.json +42 -0
- package/huemagic/locales/nl/hue-contact.html +67 -0
- package/huemagic/locales/nl/hue-contact.json +35 -0
- package/huemagic/locales/nl/hue-group.html +87 -0
- package/huemagic/locales/nl/hue-group.json +46 -0
- package/huemagic/locales/nl/hue-light.html +97 -0
- package/huemagic/locales/nl/hue-light.json +44 -0
- package/huemagic/locales/nl/hue-magic.html +68 -0
- package/huemagic/locales/nl/hue-magic.json +26 -0
- package/huemagic/locales/nl/hue-motion.html +64 -0
- package/huemagic/locales/nl/hue-motion.json +36 -0
- package/huemagic/locales/nl/hue-rules.html +69 -0
- package/huemagic/locales/nl/hue-rules.json +30 -0
- package/huemagic/locales/nl/hue-scene.html +43 -0
- package/huemagic/locales/nl/hue-scene.json +32 -0
- package/huemagic/locales/nl/hue-speaker.html +80 -0
- package/huemagic/locales/nl/hue-speaker.json +38 -0
- package/huemagic/locales/nl/hue-syncbox-config.html +19 -0
- package/huemagic/locales/nl/hue-syncbox-config.json +25 -0
- package/huemagic/locales/nl/hue-syncbox.html +86 -0
- package/huemagic/locales/nl/hue-syncbox.json +30 -0
- package/huemagic/locales/nl/hue-temperature.html +69 -0
- package/huemagic/locales/nl/hue-temperature.json +33 -0
- package/huemagic/locales/pl/hue-automation.html +59 -0
- package/huemagic/locales/pl/hue-automation.json +33 -0
- package/huemagic/locales/pl/hue-bridge-config.html +31 -0
- package/huemagic/locales/pl/hue-bridge-config.json +40 -0
- package/huemagic/locales/pl/hue-bridge.html +96 -0
- package/huemagic/locales/pl/hue-bridge.json +26 -0
- package/huemagic/locales/pl/hue-brightness.html +70 -0
- package/huemagic/locales/pl/hue-brightness.json +37 -0
- package/huemagic/locales/pl/hue-buttons.html +59 -0
- package/huemagic/locales/pl/hue-buttons.json +42 -0
- package/huemagic/locales/pl/hue-contact.html +67 -0
- package/huemagic/locales/pl/hue-contact.json +35 -0
- package/huemagic/locales/pl/hue-group.html +87 -0
- package/huemagic/locales/pl/hue-group.json +46 -0
- package/huemagic/locales/pl/hue-light.html +97 -0
- package/huemagic/locales/pl/hue-light.json +44 -0
- package/huemagic/locales/pl/hue-magic.html +68 -0
- package/huemagic/locales/pl/hue-magic.json +26 -0
- package/huemagic/locales/pl/hue-motion.html +64 -0
- package/huemagic/locales/pl/hue-motion.json +36 -0
- package/huemagic/locales/pl/hue-rules.html +69 -0
- package/huemagic/locales/pl/hue-rules.json +30 -0
- package/huemagic/locales/pl/hue-scene.html +43 -0
- package/huemagic/locales/pl/hue-scene.json +32 -0
- package/huemagic/locales/pl/hue-speaker.html +80 -0
- package/huemagic/locales/pl/hue-speaker.json +38 -0
- package/huemagic/locales/pl/hue-syncbox-config.html +19 -0
- package/huemagic/locales/pl/hue-syncbox-config.json +25 -0
- package/huemagic/locales/pl/hue-syncbox.html +86 -0
- package/huemagic/locales/pl/hue-syncbox.json +30 -0
- package/huemagic/locales/pl/hue-temperature.html +69 -0
- package/huemagic/locales/pl/hue-temperature.json +33 -0
- package/huemagic/locales/pt/hue-automation.html +59 -0
- package/huemagic/locales/pt/hue-automation.json +33 -0
- package/huemagic/locales/pt/hue-bridge-config.html +31 -0
- package/huemagic/locales/pt/hue-bridge-config.json +40 -0
- package/huemagic/locales/pt/hue-bridge.html +96 -0
- package/huemagic/locales/pt/hue-bridge.json +26 -0
- package/huemagic/locales/pt/hue-brightness.html +70 -0
- package/huemagic/locales/pt/hue-brightness.json +37 -0
- package/huemagic/locales/pt/hue-buttons.html +59 -0
- package/huemagic/locales/pt/hue-buttons.json +42 -0
- package/huemagic/locales/pt/hue-contact.html +67 -0
- package/huemagic/locales/pt/hue-contact.json +35 -0
- package/huemagic/locales/pt/hue-group.html +87 -0
- package/huemagic/locales/pt/hue-group.json +46 -0
- package/huemagic/locales/pt/hue-light.html +97 -0
- package/huemagic/locales/pt/hue-light.json +44 -0
- package/huemagic/locales/pt/hue-magic.html +68 -0
- package/huemagic/locales/pt/hue-magic.json +26 -0
- package/huemagic/locales/pt/hue-motion.html +64 -0
- package/huemagic/locales/pt/hue-motion.json +36 -0
- package/huemagic/locales/pt/hue-rules.html +69 -0
- package/huemagic/locales/pt/hue-rules.json +30 -0
- package/huemagic/locales/pt/hue-scene.html +43 -0
- package/huemagic/locales/pt/hue-scene.json +32 -0
- package/huemagic/locales/pt/hue-speaker.html +80 -0
- package/huemagic/locales/pt/hue-speaker.json +38 -0
- package/huemagic/locales/pt/hue-syncbox-config.html +19 -0
- package/huemagic/locales/pt/hue-syncbox-config.json +25 -0
- package/huemagic/locales/pt/hue-syncbox.html +86 -0
- package/huemagic/locales/pt/hue-syncbox.json +30 -0
- package/huemagic/locales/pt/hue-temperature.html +69 -0
- package/huemagic/locales/pt/hue-temperature.json +33 -0
- package/huemagic/locales/tr/hue-automation.html +59 -0
- package/huemagic/locales/tr/hue-automation.json +33 -0
- package/huemagic/locales/tr/hue-bridge-config.html +31 -0
- package/huemagic/locales/tr/hue-bridge-config.json +40 -0
- package/huemagic/locales/tr/hue-bridge.html +96 -0
- package/huemagic/locales/tr/hue-bridge.json +26 -0
- package/huemagic/locales/tr/hue-brightness.html +70 -0
- package/huemagic/locales/tr/hue-brightness.json +37 -0
- package/huemagic/locales/tr/hue-buttons.html +59 -0
- package/huemagic/locales/tr/hue-buttons.json +42 -0
- package/huemagic/locales/tr/hue-contact.html +67 -0
- package/huemagic/locales/tr/hue-contact.json +35 -0
- package/huemagic/locales/tr/hue-group.html +87 -0
- package/huemagic/locales/tr/hue-group.json +46 -0
- package/huemagic/locales/tr/hue-light.html +97 -0
- package/huemagic/locales/tr/hue-light.json +44 -0
- package/huemagic/locales/tr/hue-magic.html +68 -0
- package/huemagic/locales/tr/hue-magic.json +26 -0
- package/huemagic/locales/tr/hue-motion.html +64 -0
- package/huemagic/locales/tr/hue-motion.json +36 -0
- package/huemagic/locales/tr/hue-rules.html +69 -0
- package/huemagic/locales/tr/hue-rules.json +30 -0
- package/huemagic/locales/tr/hue-scene.html +43 -0
- package/huemagic/locales/tr/hue-scene.json +32 -0
- package/huemagic/locales/tr/hue-speaker.html +80 -0
- package/huemagic/locales/tr/hue-speaker.json +38 -0
- package/huemagic/locales/tr/hue-syncbox-config.html +19 -0
- package/huemagic/locales/tr/hue-syncbox-config.json +25 -0
- package/huemagic/locales/tr/hue-syncbox.html +86 -0
- package/huemagic/locales/tr/hue-syncbox.json +30 -0
- package/huemagic/locales/tr/hue-temperature.html +69 -0
- package/huemagic/locales/tr/hue-temperature.json +33 -0
- package/huemagic/utils/api.js +158 -54
- package/huemagic/utils/color.js +20 -2
- package/huemagic/utils/merge.js +3 -2
- package/huemagic/utils/messages.js +506 -120
- package/huemagic/utils/sse.js +51 -0
- package/huemagic/utils/syncbox.js +84 -0
- package/package.json +19 -11
- package/.github/FUNDING.yml +0 -2
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/.github/workflows/npm.yml +0 -18
- package/huemagic/locales/en-US/hue-bridge-config.json +0 -29
- package/huemagic/locales/en-US/hue-buttons.json +0 -34
- package/huemagic/locales/en-US/hue-light.json +0 -38
- /package/huemagic/locales/{en-US → en}/hue-bridge-config.html +0 -0
- /package/huemagic/locales/{en-US → en}/hue-magic.json +0 -0
package/huemagic/utils/api.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const dayjs = require('dayjs');
|
|
3
3
|
const https = require('https');
|
|
4
|
-
const
|
|
4
|
+
const { parseEventStream } = require('./sse');
|
|
5
|
+
|
|
6
|
+
// Node is somehow not able to parse the official Philips Hue PEM
|
|
7
|
+
const httpsAgent = new https.Agent({ rejectUnauthorized: false, keepAlive: true });
|
|
5
8
|
|
|
6
9
|
function API()
|
|
7
10
|
{
|
|
@@ -28,7 +31,9 @@ function API()
|
|
|
28
31
|
"method": "GET",
|
|
29
32
|
"url": "https://" + config.bridge + "/api/config",
|
|
30
33
|
"headers": { "Content-Type": "application/json; charset=utf-8" },
|
|
31
|
-
"httpsAgent":
|
|
34
|
+
"httpsAgent": httpsAgent,
|
|
35
|
+
"proxy": false, // THE BRIDGE IS ON THE LOCAL NETWORK, NEVER GO THROUGH A PROXY
|
|
36
|
+
"timeout": 10000,
|
|
32
37
|
})
|
|
33
38
|
.then(function(response)
|
|
34
39
|
{
|
|
@@ -62,7 +67,9 @@ function API()
|
|
|
62
67
|
"Content-Type": "application/json; charset=utf-8",
|
|
63
68
|
"hue-application-key": config.key
|
|
64
69
|
},
|
|
65
|
-
"httpsAgent":
|
|
70
|
+
"httpsAgent": httpsAgent,
|
|
71
|
+
"proxy": false, // THE BRIDGE IS ON THE LOCAL NETWORK, NEVER GO THROUGH A PROXY
|
|
72
|
+
"timeout": 15000,
|
|
66
73
|
};
|
|
67
74
|
|
|
68
75
|
// HAS RESOURCE? -> APPEND
|
|
@@ -90,6 +97,7 @@ function API()
|
|
|
90
97
|
{
|
|
91
98
|
if(version === 2)
|
|
92
99
|
{
|
|
100
|
+
// THE BRIDGE ALSO PUTS NON-FATAL HINTS INTO "errors", SO ONLY THE STATUS COUNTS
|
|
93
101
|
resolve(response.data.data);
|
|
94
102
|
}
|
|
95
103
|
else if(version === 1)
|
|
@@ -99,64 +107,143 @@ function API()
|
|
|
99
107
|
})
|
|
100
108
|
.catch(function(error)
|
|
101
109
|
{
|
|
102
|
-
|
|
110
|
+
if (error.response)
|
|
111
|
+
{
|
|
112
|
+
let errors = error.response.data;
|
|
113
|
+
|
|
114
|
+
// AN OVERLOADED BRIDGE ANSWERS WITH A HTML ERROR PAGE
|
|
115
|
+
if(typeof errors === 'string') { errors = "The bridge is currently not able to answer (HTTP " + error.response.status + ")."; }
|
|
116
|
+
else if(errors && errors.errors) { errors = errors.errors; }
|
|
117
|
+
|
|
118
|
+
reject({ status: error.response.status, errors: errors });
|
|
119
|
+
}
|
|
120
|
+
else
|
|
121
|
+
{
|
|
122
|
+
reject({ status: error.code, errors: error.message});
|
|
123
|
+
}
|
|
103
124
|
});
|
|
104
125
|
});
|
|
105
126
|
}
|
|
106
127
|
|
|
107
128
|
//
|
|
108
129
|
// SUBSCRIBE TO BRIDGE EVENTS
|
|
109
|
-
this.subscribe = function(config, callback)
|
|
130
|
+
this.subscribe = function(config, callback, log = null)
|
|
110
131
|
{
|
|
111
132
|
const scope = this;
|
|
112
133
|
return new Promise(function(resolve, reject)
|
|
113
134
|
{
|
|
114
|
-
|
|
135
|
+
// ONLY ONE STREAM PER BRIDGE
|
|
136
|
+
scope.unsubscribe(config);
|
|
137
|
+
|
|
138
|
+
const stream = { active: true, request: null, retry: null, attempt: 0, lastEventId: null, connected: false };
|
|
139
|
+
scope.events[config.id] = stream;
|
|
140
|
+
|
|
141
|
+
// (RE)CONNECT TO THE EVENT STREAM
|
|
142
|
+
const connect = function()
|
|
115
143
|
{
|
|
116
|
-
|
|
144
|
+
if(stream.active === false) { return false; }
|
|
145
|
+
|
|
146
|
+
const [host, port] = config.bridge.trim().split(":");
|
|
147
|
+
const headers = {
|
|
148
|
+
"Accept": "text/event-stream",
|
|
149
|
+
"Cache-Control": "no-cache",
|
|
150
|
+
"hue-application-key": config.key
|
|
151
|
+
};
|
|
117
152
|
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
153
|
+
// CONTINUE WHERE WE LEFT OFF
|
|
154
|
+
if(stream.lastEventId) { headers["Last-Event-ID"] = stream.lastEventId; }
|
|
155
|
+
|
|
156
|
+
stream.request = https.request({
|
|
157
|
+
host: host,
|
|
158
|
+
port: port ? parseInt(port) : 443,
|
|
159
|
+
path: "/eventstream/clip/v2",
|
|
160
|
+
method: "GET",
|
|
161
|
+
headers: headers,
|
|
162
|
+
agent: false,
|
|
163
|
+
rejectUnauthorized: false
|
|
122
164
|
});
|
|
123
165
|
|
|
124
|
-
//
|
|
125
|
-
|
|
166
|
+
// ONLY GUARD THE HANDSHAKE, AN IDLE EVENT STREAM IS PERFECTLY NORMAL
|
|
167
|
+
stream.request.setTimeout(15000, function() { stream.request.destroy(new Error("the bridge did not answer")); });
|
|
168
|
+
|
|
169
|
+
stream.request.on('response', function(response)
|
|
126
170
|
{
|
|
127
|
-
if(
|
|
171
|
+
if(response.statusCode !== 200)
|
|
128
172
|
{
|
|
129
|
-
|
|
130
|
-
|
|
173
|
+
response.resume();
|
|
174
|
+
reconnect("The bridge rejected the event stream (HTTP " + response.statusCode + ")");
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// CONNECTED -> LET THE OS DETECT DEAD PEERS
|
|
179
|
+
const isReconnect = (stream.attempt > 0);
|
|
180
|
+
|
|
181
|
+
stream.request.setTimeout(0);
|
|
182
|
+
stream.attempt = 0;
|
|
183
|
+
stream.connected = true;
|
|
184
|
+
response.setEncoding('utf8');
|
|
185
|
+
if(response.socket) { response.socket.setKeepAlive(true, 30000); }
|
|
186
|
+
|
|
187
|
+
// EVENTS MAY HAVE BEEN MISSED WHILE WE WERE AWAY
|
|
188
|
+
if(isReconnect) { callback([], "reconnect"); }
|
|
189
|
+
|
|
190
|
+
let buffer = "";
|
|
191
|
+
|
|
192
|
+
response.on('data', function(chunk)
|
|
193
|
+
{
|
|
194
|
+
const parsed = parseEventStream(buffer + chunk);
|
|
195
|
+
buffer = (parsed.rest.length > 1048576) ? "" : parsed.rest;
|
|
196
|
+
|
|
197
|
+
for(let event of parsed.events)
|
|
131
198
|
{
|
|
132
|
-
|
|
133
|
-
if(
|
|
199
|
+
if(event.id) { stream.lastEventId = event.id; }
|
|
200
|
+
if(!event.data) { continue; }
|
|
201
|
+
|
|
202
|
+
let messages = [];
|
|
203
|
+
try { messages = JSON.parse(event.data); }
|
|
204
|
+
catch(error) { continue; }
|
|
205
|
+
|
|
206
|
+
for(let message of messages)
|
|
134
207
|
{
|
|
135
|
-
callback(message.data);
|
|
208
|
+
if(message.data) { callback(message.data, message.type); }
|
|
136
209
|
}
|
|
137
210
|
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
211
|
+
});
|
|
140
212
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
{
|
|
144
|
-
resolve(true);
|
|
145
|
-
}
|
|
213
|
+
response.on('end', function() { reconnect("The bridge closed the event stream"); });
|
|
214
|
+
response.on('error', function(error) { reconnect(error.message); });
|
|
146
215
|
|
|
147
|
-
// ERROR? -> RETRY?
|
|
148
|
-
scope.events[config.id].onerror = function(error)
|
|
149
|
-
{
|
|
150
|
-
console.log("HueMagic:", "Connection to bridge lost. Trying to reconnect again in 30 seconds…", error);
|
|
151
|
-
setTimeout(function(){ scope.subscribe(config, callback); }, 30000);
|
|
152
216
|
resolve(true);
|
|
153
|
-
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
stream.request.on('error', function(error) { reconnect(error.message); });
|
|
220
|
+
stream.request.end();
|
|
154
221
|
}
|
|
155
|
-
|
|
222
|
+
|
|
223
|
+
// RECONNECT WITH A BACKOFF, BUT NEVER MORE THAN ONCE AT A TIME
|
|
224
|
+
const reconnect = function(reason)
|
|
156
225
|
{
|
|
157
|
-
|
|
158
|
-
|
|
226
|
+
if(stream.active === false || stream.retry !== null) { return false; }
|
|
227
|
+
|
|
228
|
+
stream.connected = false;
|
|
229
|
+
if(stream.request) { stream.request.destroy(); stream.request = null; }
|
|
230
|
+
|
|
231
|
+
const delay = Math.min(30000, 1000 * Math.pow(2, stream.attempt));
|
|
232
|
+
const seconds = Math.round(delay/1000);
|
|
233
|
+
stream.attempt += 1;
|
|
234
|
+
|
|
235
|
+
if(log) { log(reason, seconds); }
|
|
236
|
+
else { console.log("HueMagic:", "Connection to bridge lost (" + reason + "). Trying to reconnect in " + seconds + " seconds…"); }
|
|
237
|
+
stream.retry = setTimeout(function()
|
|
238
|
+
{
|
|
239
|
+
stream.retry = null;
|
|
240
|
+
connect();
|
|
241
|
+
}, delay);
|
|
242
|
+
|
|
243
|
+
resolve(true);
|
|
159
244
|
}
|
|
245
|
+
|
|
246
|
+
connect();
|
|
160
247
|
});
|
|
161
248
|
}
|
|
162
249
|
|
|
@@ -164,22 +251,40 @@ function API()
|
|
|
164
251
|
// UNSUBSCRIBE
|
|
165
252
|
this.unsubscribe = function(config)
|
|
166
253
|
{
|
|
167
|
-
|
|
168
|
-
|
|
254
|
+
const stream = this.events[config.id];
|
|
255
|
+
if(!stream) { return false; }
|
|
256
|
+
|
|
257
|
+
stream.active = false;
|
|
258
|
+
if(stream.retry !== null) { clearTimeout(stream.retry); }
|
|
259
|
+
if(stream.request) { stream.request.destroy(); }
|
|
260
|
+
|
|
261
|
+
delete this.events[config.id];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
//
|
|
265
|
+
// IS THE EVENT STREAM ALIVE?
|
|
266
|
+
this.connected = function(config)
|
|
267
|
+
{
|
|
268
|
+
const stream = this.events[config.id];
|
|
269
|
+
return !!stream && stream.connected === true;
|
|
169
270
|
}
|
|
170
271
|
|
|
171
272
|
//
|
|
172
273
|
// GET FULL/ROOT RESOURCE
|
|
173
|
-
this.fullResource = function(resource, allResources = {})
|
|
274
|
+
this.fullResource = function(resource, allResources = {}, seen = {})
|
|
174
275
|
{
|
|
175
276
|
const scope = this;
|
|
176
277
|
var fullResource = Object.assign({}, resource);
|
|
177
278
|
|
|
178
|
-
|
|
279
|
+
// PROTECT AGAINST BROKEN OWNER CHAINS
|
|
280
|
+
if(seen[resource["id"]]) { return fullResource; }
|
|
281
|
+
seen[resource["id"]] = true;
|
|
282
|
+
|
|
283
|
+
if(resource["owner"] && typeof allResources[fullResource["owner"]["rid"]] !== 'undefined')
|
|
179
284
|
{
|
|
180
|
-
fullResource = scope.fullResource(allResources[fullResource["owner"]["rid"]], allResources);
|
|
285
|
+
fullResource = scope.fullResource(allResources[fullResource["owner"]["rid"]], allResources, seen);
|
|
181
286
|
}
|
|
182
|
-
else if(resource["
|
|
287
|
+
else if(Array.isArray(resource["services"]))
|
|
183
288
|
{
|
|
184
289
|
// RESOLVE SERVICES
|
|
185
290
|
var allServices = {};
|
|
@@ -190,6 +295,7 @@ function API()
|
|
|
190
295
|
const targetType = targetService["rtype"];
|
|
191
296
|
const targetID = targetService["rid"];
|
|
192
297
|
|
|
298
|
+
if(!allResources[targetID]) { continue; }
|
|
193
299
|
if(!allServices[targetType]) { allServices[targetType] = {}; }
|
|
194
300
|
allServices[targetType][targetID] = Object.assign({}, allResources[targetID]);
|
|
195
301
|
}
|
|
@@ -221,11 +327,9 @@ function API()
|
|
|
221
327
|
// CREATE ID BASED OBJECT OF ALL RESOURCES
|
|
222
328
|
resources.forEach(function(resource, index)
|
|
223
329
|
{
|
|
224
|
-
// IS BUTTON? -> REMOVE PREVIOUS STATE
|
|
225
|
-
if(resource.type === "button")
|
|
226
|
-
{
|
|
227
|
-
delete resource["button"];
|
|
228
|
-
}
|
|
330
|
+
// IS BUTTON OR DIAL? -> REMOVE PREVIOUS STATE
|
|
331
|
+
if(resource.type === "button") { delete resource["button"]; }
|
|
332
|
+
else if(resource.type === "relative_rotary") { delete resource["relative_rotary"]; }
|
|
229
333
|
|
|
230
334
|
resourceList[resource.id] = resource;
|
|
231
335
|
});
|
|
@@ -236,6 +340,9 @@ function API()
|
|
|
236
340
|
// GET FULL RESOURCE
|
|
237
341
|
let fullResource = scope.fullResource(resource, resourceList);
|
|
238
342
|
|
|
343
|
+
// A RESOURCE AND EACH OF ITS SERVICES RESOLVE TO THE SAME ROOT
|
|
344
|
+
if(processedResources[fullResource.id]) { return; }
|
|
345
|
+
|
|
239
346
|
// ADD CURRENT DATE/TIME
|
|
240
347
|
fullResource["updated"] = currentDateTime;
|
|
241
348
|
|
|
@@ -249,15 +356,12 @@ function API()
|
|
|
249
356
|
|
|
250
357
|
// SET ADDITIONAL TYPES BEHIND RECCOURCE
|
|
251
358
|
fullResource["types"] = fullResource["types"].concat(additionalServiceTypes);
|
|
252
|
-
}
|
|
253
359
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
{
|
|
257
|
-
for (serviceType in fullResource["services"])
|
|
360
|
+
// RESOURCE HAS GROUPED SERVICES?
|
|
361
|
+
for (const serviceType in fullResource["services"])
|
|
258
362
|
{
|
|
259
|
-
const
|
|
260
|
-
for (groupedServiceID in
|
|
363
|
+
const groupedServices = fullResource['services'][serviceType];
|
|
364
|
+
for (const groupedServiceID in groupedServices)
|
|
261
365
|
{
|
|
262
366
|
if (!processedResources["_groupsOf"][groupedServiceID]) { processedResources["_groupsOf"][groupedServiceID] = []; }
|
|
263
367
|
processedResources["_groupsOf"][groupedServiceID].push(fullResource.id);
|
|
@@ -275,4 +379,4 @@ function API()
|
|
|
275
379
|
}
|
|
276
380
|
|
|
277
381
|
// EXPORT
|
|
278
|
-
module.exports = new API;
|
|
382
|
+
module.exports = new API;
|
package/huemagic/utils/color.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
// EXTERNAL HELPERS
|
|
2
2
|
const colornames = require("colornames");
|
|
3
3
|
const colornamer = require('color-namer');
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// LOADED ON DEMAND, IT PULLS IN A LARGE DEPENDENCY TREE
|
|
6
|
+
function getColors(...args)
|
|
7
|
+
{
|
|
8
|
+
return require('get-image-colors')(...args);
|
|
9
|
+
}
|
|
5
10
|
|
|
6
11
|
// RGB -> XY
|
|
7
12
|
function rgbToXy(red, green, blue, gamut = null)
|
|
8
13
|
{
|
|
9
14
|
var colorGamut = { red: [1.0, 0], green: [0.0, 1.0], blue: [0.0, 0.0] };
|
|
10
|
-
if(!!gamut)
|
|
15
|
+
if(!!gamut && !!gamut.red && !!gamut.green && !!gamut.blue)
|
|
11
16
|
{
|
|
12
17
|
colorGamut = { red: [gamut.red.x, gamut.red.y], green: [gamut.green.x, gamut.green.y], blue: [gamut.blue.x, gamut.blue.y] };
|
|
13
18
|
}
|
|
@@ -34,9 +39,19 @@ function rgbToXy(red, green, blue, gamut = null)
|
|
|
34
39
|
xy = _getClosestColor(xy, colorGamut);
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
// THE BRIDGE REJECTS ANYTHING OUTSIDE 0…1 WITH A 400
|
|
43
|
+
xy.x = _clampToColorSpace(xy.x);
|
|
44
|
+
xy.y = _clampToColorSpace(xy.y);
|
|
45
|
+
|
|
37
46
|
return xy;
|
|
38
47
|
}
|
|
39
48
|
|
|
49
|
+
function _clampToColorSpace(value)
|
|
50
|
+
{
|
|
51
|
+
if(isNaN(value)) { return 0; }
|
|
52
|
+
return (value < 0) ? 0 : ((value > 1) ? 1 : value);
|
|
53
|
+
}
|
|
54
|
+
|
|
40
55
|
function _getGammaCorrectedValue(value)
|
|
41
56
|
{
|
|
42
57
|
return (value > 0.04045) ? Math.pow((value + 0.055) / (1.0 + 0.055), 2.4) : (value / 12.92)
|
|
@@ -153,6 +168,9 @@ function _getClosestPoint(xy, pointA, pointB)
|
|
|
153
168
|
let xy2a_dot_a2b = xy2a[0] * a2b[0] + xy2a[1] * a2b[1];
|
|
154
169
|
let t = xy2a_dot_a2b /a2bSqr;
|
|
155
170
|
|
|
171
|
+
// STAY ON THE EDGE OF THE GAMUT, NOT ON THE INFINITE LINE BEHIND IT
|
|
172
|
+
t = (t < 0) ? 0 : ((t > 1) ? 1 : t);
|
|
173
|
+
|
|
156
174
|
return {
|
|
157
175
|
x: pointA.x + a2b[0] * t,
|
|
158
176
|
y: pointA.y + a2b[1] * t
|
package/huemagic/utils/merge.js
CHANGED
|
@@ -13,9 +13,10 @@ function mergeDeep(...objects)
|
|
|
13
13
|
const pVal = prev[key];
|
|
14
14
|
const oVal = obj[key];
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// AN UPDATE REPLACES A LIST, IT NEVER APPENDS TO IT
|
|
17
|
+
if(Array.isArray(oVal))
|
|
17
18
|
{
|
|
18
|
-
prev[key] =
|
|
19
|
+
prev[key] = oVal;
|
|
19
20
|
}
|
|
20
21
|
else if (isObject(pVal) && isObject(oVal))
|
|
21
22
|
{
|