############################################################################### # One alarm's controls. Included once per alarm from wake-up-light-ii.yaml. # n = alarm number # o = offset of this alarm's 12-byte block inside DP127 # dp = this alarm's on/off datapoint # Byte layout is documented next to the DP127 handler in the main file. ############################################################################### # Bit 0 = Monday, per Tuya's definition and a ringing test. No days set = one time. packages: mon: !include { file: alarm_day.yaml, vars: { day: "Mon", bit: "0", w: "11" } } tue: !include { file: alarm_day.yaml, vars: { day: "Tue", bit: "1", w: "12" } } wed: !include { file: alarm_day.yaml, vars: { day: "Wed", bit: "2", w: "13" } } thu: !include { file: alarm_day.yaml, vars: { day: "Thu", bit: "3", w: "14" } } fri: !include { file: alarm_day.yaml, vars: { day: "Fri", bit: "4", w: "15" } } sat: !include { file: alarm_day.yaml, vars: { day: "Sat", bit: "5", w: "16" } } sun: !include { file: alarm_day.yaml, vars: { day: "Sun", bit: "6", w: "17" } } web_server: sorting_groups: - id: group_alarm_${n} name: "Alarm ${n}" sorting_weight: 3${n} switch: - platform: tuya id: alarm_${n}_enable name: "Alarm ${n}" switch_datapoint: ${dp} web_server: sorting_group_id: group_alarm_${n} sorting_weight: 1 # Stored inverted: 0 = snooze allowed, 1 = not allowed. - platform: template id: alarm_${n}_snooze_allowed name: "Alarm ${n} Snooze Allowed" web_server: sorting_group_id: group_alarm_${n} sorting_weight: 10 lambda: |- if (!id(alarm_raw_valid)) return {}; return id(alarm_raw)[${o} + 11] == 0; turn_on_action: - lambda: |- if (!id(alarm_raw_valid)) return; id(alarm_raw)[${o} + 11] = 0; - script.execute: send_alarm_settings turn_off_action: - lambda: |- if (!id(alarm_raw_valid)) return; id(alarm_raw)[${o} + 11] = 1; - script.execute: send_alarm_settings datetime: - platform: template id: alarm_${n}_time name: "Alarm ${n} Time" type: time update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 2 lambda: |- if (!id(alarm_raw_valid)) return {}; uint16_t mins = (static_cast(id(alarm_raw)[${o} + 1]) << 8) | id(alarm_raw)[${o} + 2]; if (mins >= 1440) return {}; ESPTime t{}; t.hour = mins / 60; t.minute = mins % 60; t.second = 0; return t; set_action: - lambda: |- if (!id(alarm_raw_valid)) return; uint16_t mins = static_cast(x.hour) * 60 + x.minute; id(alarm_raw)[${o} + 1] = (mins >> 8) & 0xFF; id(alarm_raw)[${o} + 2] = mins & 0xFF; - script.execute: send_alarm_settings select: - platform: template id: alarm_${n}_mode name: "Alarm ${n} Mode" options: - "Sound" - "Sound + Light" - "Radio" - "Radio + Light" update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 2.5 lambda: |- if (!id(alarm_raw_valid)) return {}; switch (id(alarm_raw)[${o} + 5]) { case 0: return std::string("Sound"); case 1: return std::string("Sound + Light"); case 2: return std::string("Radio"); case 3: return std::string("Radio + Light"); default: return {}; } set_action: - lambda: |- if (!id(alarm_raw_valid)) return; uint8_t value = 0; if (x == "Sound + Light") value = 1; else if (x == "Radio") value = 2; else if (x == "Radio + Light") value = 3; id(alarm_raw)[${o} + 5] = value; // The MCU drops a light mode if brightness is 0, so give it a level. if ((value == 1 || value == 3) && id(alarm_raw)[${o} + 10] == 0) id(alarm_raw)[${o} + 10] = 10; - script.execute: send_alarm_settings - platform: template id: alarm_${n}_sound name: "Alarm ${n} Sound" options: - "Off" - "Birds" - "Beach" - "Galaxy Twinkles" - "Piano and Birds" - "Happy Harp" - "Mechanical Alarm Clock" - "Digital Alarm Clock" update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 3 lambda: |- if (!id(alarm_raw_valid)) return {}; uint8_t s = id(alarm_raw)[${o} + 6]; static const char *const names[8] = {"Off", "Birds", "Beach", "Galaxy Twinkles", "Piano and Birds", "Happy Harp", "Mechanical Alarm Clock", "Digital Alarm Clock"}; if (s > 7) return {}; return std::string(names[s]); set_action: - lambda: |- if (!id(alarm_raw_valid)) return; uint8_t value = 0; if (x == "Birds") value = 1; else if (x == "Beach") value = 2; else if (x == "Galaxy Twinkles") value = 3; else if (x == "Piano and Birds") value = 4; else if (x == "Happy Harp") value = 5; else if (x == "Mechanical Alarm Clock") value = 6; else if (x == "Digital Alarm Clock") value = 7; id(alarm_raw)[${o} + 6] = value; - script.execute: send_alarm_settings number: - platform: template id: alarm_${n}_volume name: "Alarm ${n} Volume" min_value: 1 max_value: 16 step: 1 update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 4 lambda: |- if (!id(alarm_raw_valid)) return {}; return static_cast(id(alarm_raw)[${o} + 7]); set_action: - lambda: |- if (!id(alarm_raw_valid)) return; id(alarm_raw)[${o} + 7] = static_cast(x); - script.execute: send_alarm_settings - platform: template id: alarm_${n}_wake_brightness name: "Alarm ${n} Wake Light" # Reads 0 in modes without light, where the MCU ignores changes. min_value: 0 max_value: 20 step: 1 update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 5 lambda: |- if (!id(alarm_raw_valid)) return {}; return static_cast(id(alarm_raw)[${o} + 10]); set_action: - lambda: |- if (!id(alarm_raw_valid)) return; id(alarm_raw)[${o} + 10] = static_cast(x); - script.execute: send_alarm_settings # Tuya's definition says 10-20, default 15, but this lamp reports 30. - platform: template id: alarm_${n}_ring_duration name: "Alarm ${n} Ring Duration" unit_of_measurement: "min" min_value: 10 max_value: 60 step: 5 update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 8 lambda: |- if (!id(alarm_raw_valid)) return {}; return static_cast(id(alarm_raw)[${o} + 4]); set_action: - lambda: |- if (!id(alarm_raw_valid)) return; id(alarm_raw)[${o} + 4] = static_cast(x); - script.execute: send_alarm_settings - platform: template id: alarm_${n}_sunrise_duration name: "Alarm ${n} Sunrise Duration" unit_of_measurement: "min" min_value: 10 max_value: 60 step: 10 update_interval: 2s web_server: sorting_group_id: group_alarm_${n} sorting_weight: 6 lambda: |- if (!id(alarm_raw_valid)) return {}; return static_cast(id(alarm_raw)[${o} + 9]); set_action: - lambda: |- if (!id(alarm_raw_valid)) return; id(alarm_raw)[${o} + 9] = static_cast(x); - script.execute: send_alarm_settings text_sensor: - platform: template id: alarm_${n}_summary name: "Alarm ${n} Summary" update_interval: never web_server: sorting_group_id: group_alarm_${n} sorting_weight: 7