4
0
Эх сурвалжийг харах

feat (devices): add support for Moes Smart Wake Up Light alarm clock

Issue #3821

- add support for time entity specified by a hhmmss string
 - allow variants with colons and without seconds (code also handles
   hours only, but unadvertised since it isn't really useful)
Jason Rumney 4 сар өмнө
parent
commit
3e29fd8679

+ 2 - 0
ACKNOWLEDGEMENTS.md

@@ -1082,3 +1082,5 @@ Further device support has been made with the assistance of users. Please consid
 - [diegaccio](https://github.com/diegaccio) for contributing improvements for Beok TGM50-WPB-WF / M5-G2 variants.
 - [Kriseh1337](https://github.com/Kriseh1337) for assisting with support for Livn Arosa electric fireplace.
 - [AD8-sven](https://github.com/AD8-sven) for assisting with support for ZMP71SH variable speed pool pump.
+- [f3peter](https://github.com/f3peter) for assisting with support for Moes smart wake up light alarm clock.
+.

+ 1 - 0
DEVICES.md

@@ -1072,6 +1072,7 @@ port and password.
 - Mirabella Genio motion sensor
 - Moes human presence sensor
 - Moes single outlet water timer
+- Moes smart wake up light alarm clock
 - Momcozy white noise machine (2 variants)
 - Mustool MT15/MT29 air quality box
 - Nedis WIFIPD10WT pill dispenser

+ 1 - 0
custom_components/tuya_local/devices/README.md

@@ -766,6 +766,7 @@ to use it for other length timers.
 - **hour** (optional, integer in range 0-24) - the hours component
 - **minute** (optional, integer in range 0-60 or 0-1440 if the only dp) - the minute component
 - **second** (optional, integer in range 0-60 or 0-84600 if the only dp) - the second component
+- **hms** (optional, string in format "hh:mm", "hh:mm:ss", "hhmm" or "hhmmss" - all components as a string
 
 ### `vacuum`
 - **status** (required, mapping of strings): a dp to report and control the status of the vacuum.

+ 243 - 0
custom_components/tuya_local/devices/moes_zcjk_alarmclock.yaml

@@ -0,0 +1,243 @@
+name: Alarm clock
+products:
+  - id: rslo8vqc1xjtaoy9
+    manufacturer: Moes House
+    model: Smart Wake Up Light
+    model_id: ZC-JK
+entities:
+  - entity: light
+    dps:
+      - id: 101
+        type: boolean
+        name: switch
+      - id: 102
+        type: integer
+        name: brightness
+        range:
+          min: 10
+          max: 1000
+  - entity: time
+    icon: "mdi:clock-digital"
+    dps:
+      - id: 103
+        type: string
+        name: hms
+  - entity: select
+    name: Display
+    icon: "mdi:clock-digital"
+    category: config
+    dps:
+      - id: 104
+        type: integer
+        name: option
+        mapping:
+          - dps_val: 0
+            value: "Off"
+          - dps_val: 1
+            value: Day
+          - dps_val: 2
+            value: Night
+          - dps_val: 3
+            value: Auto
+  - entity: switch
+    name: Radio
+    icon: "mdi:radio"
+    dps:
+      - id: 105
+        type: boolean
+        name: switch
+  - entity: number
+    name: Volume
+    icon: "mdi:volume-high"
+    dps:
+      - id: 106
+        type: integer
+        name: value
+        range:
+          min: 1
+          max: 16
+  - entity: text
+    name: Station list
+    category: config
+    icon: "mdi:playlist-music"
+    hidden: true
+    dps:
+      - id: 107
+        type: base64
+        optional: true
+        name: value
+  - entity: switch
+    name: Alarm 1
+    icon: "mdi:alarm"
+    category: config
+    dps:
+      - id: 109
+        type: boolean
+        name: switch
+  - entity: number
+    name: Snooze time
+    class: duration
+    category: config
+    icon: "mdi:alarm-snooze"
+    dps:
+      - id: 116
+        type: integer
+        name: value
+        unit: min
+        range:
+          min: 8
+          max: 15
+  - entity: select
+    name: Snooze type
+    icon: "mdi:alarm-snooze"
+    category: config
+    dps:
+      - id: 117
+        type: string
+        name: option
+        mapping:
+          - dps_val: "1"
+            value: Sound + Radio
+          - dps_val: "2"
+            value: Light
+          - dps_val: "3"
+            value: Radio
+          - dps_val: "4"
+            value: Radio + Sound + Light
+  - entity: switch
+    name: Sleep
+    icon: "mdi:sleep"
+    dps:
+      - id: 121
+        type: boolean
+        name: switch
+  - entity: switch
+    name: Alarm 2
+    icon: "mdi:alarm"
+    category: config
+    dps:
+      - id: 122
+        type: boolean
+        name: switch
+  - entity: switch
+    name: Alarm 3
+    icon: "mdi:alarm"
+    category: config
+    dps:
+      - id: 123
+        type: boolean
+        name: switch
+  - entity: switch
+    name: Alarm 4
+    icon: "mdi:alarm"
+    category: config
+    dps:
+      - id: 124
+        type: boolean
+        name: switch
+  - entity: switch
+    name: Internet time
+    icon: "mdi:weather-cloudy-clock"
+    category: config
+    dps:
+      - id: 125
+        type: boolean
+        name: switch
+  - entity: button
+    name: Radio seek
+    icon: "mdi:fast-forward"
+    dps:
+      - id: 126
+        type: boolean
+        name: button
+      - id: 125
+        type: boolean
+        name: available
+        mapping:
+          - dps_val: true
+            value: false
+          - dps_val: false
+            value: true
+  - entity: button
+    name: Radio stop
+    icon: "mdi:stop"
+    dps:
+      - id: 126
+        type: boolean
+        name: button
+        mapping:
+          - dps_val: true
+            value: false
+          - dps_val: false
+            value: true
+      - id: 125
+        type: boolean
+        name: available
+  - entity: text
+    name: Alarm settings
+    category: config
+    icon: "mdi:alarm"
+    hidden: true
+    dps:
+      - id: 127
+        type: base64
+        optional: true
+        name: value
+  - entity: text
+    name: Sleep settings
+    category: config
+    icon: "mdi:sleep"
+    hidden: true
+    dps:
+      - id: 128
+        type: base64
+        optional: true
+        name: value
+  - entity: light
+    name: Ambient
+    dps:
+      - id: 129
+        type: boolean
+        name: switch
+      - id: 132
+        type: string
+        name: named_color
+        mapping:
+          - dps_val: "1"
+            value: white
+          - dps_val: "2"
+            value: red
+          - dps_val: "3"
+            value: orange
+          - dps_val: "4"
+            value: yellow
+          - dps_val: "5"
+            value: lime
+          - dps_val: "6"
+            value: cyan
+          - dps_val: "7"
+            value: blue
+          - dps_val: "8"
+            value: magenta
+  - entity: switch
+    name: Snooze
+    icon: "mdi:alarm-snooze"
+    dps:
+      - id: 130
+        type: boolean
+        name: switch
+  - entity: select
+    name: Time format
+    icon: "mdi:hours-24"
+    category: config
+    dps:
+      - id: 131
+        type: boolean
+        name: option
+        mapping:
+          - dps_val: false
+            value: "12 hour"
+            icon: "mdi:hours-12"
+            icon_priority: 1
+          - dps_val: true
+            value: "24 hour"

+ 24 - 0
custom_components/tuya_local/time.py

@@ -45,10 +45,12 @@ class TuyaLocalTime(TuyaLocalEntity, TimeEntity):
         self._hour_dps = dps_map.pop("hour", None)
         self._minute_dps = dps_map.pop("minute", None)
         self._second_dps = dps_map.pop("second", None)
+        self._hms_dps = dps_map.pop("hms", None)
         if (
             self._hour_dps is None
             and self._minute_dps is None
             and self._second_dps is None
+            and self._hms_dps is None
         ):
             raise AttributeError(
                 f"{config.config_id} is missing an hour, minute or second dp"
@@ -65,6 +67,28 @@ class TuyaLocalTime(TuyaLocalEntity, TimeEntity):
             minutes = self._minute_dps.get_value(self._device)
         if self._second_dps:
             seconds = self._second_dps.get_value(self._device)
+        if self._hms_dps:
+            hms = self._hms_dps.get_value(self._device)
+            if hms is not None and isinstance(hms, str):
+                parts = hms.split(":")
+                if len(parts) == 3:
+                    hours = int(parts[0])
+                    minutes = int(parts[1])
+                    seconds = int(parts[2])
+                elif len(parts) == 2:
+                    hours = int(parts[0])
+                    minutes = int(parts[1])
+                    seconds = 0
+                elif len(parts) == 1:
+                    if len(hms) <= 2:
+                        hours = hms
+                    elif len(hms) <= 4:
+                        hours = hms[0 : len(hms) - 2]
+                        minutes = hms[len(hms) - 2 :]
+                    else:
+                        hours = hms.substring(0, len(hms) - 4)
+                        minutes = hms.substring(len(hms) - 4, len(hms) - 2)
+                        seconds = hms.substring(len(hms) - 2)
         if hours is None and minutes is None and seconds is None:
             return None
         hours = hours or 0