586 lines
18 KiB
YAML
586 lines
18 KiB
YAML
###############################################################################
|
|||
|
|
# Wake Up Light II -> ESPHome
|
||
|
|
# Tuya PID: ya39qahrcdhvxowz
|
||
|
|
# Hardware observed in this unit: Tuya WBR3 / Realtek RTL8720CF
|
||
|
|
# Main appliance MCU <-> WBR3: TuyaMCU protocol, UART0, 9600 8N1
|
||
|
|
# WBR3 PA13 = RX0 (from appliance MCU)
|
||
|
|
# WBR3 PA14 = TX0 (to appliance MCU)
|
||
|
|
#
|
||
|
|
# IMPORTANT: stock ESPHome/LibreTiny UART selection may not route UART0 to
|
||
|
|
# PA13/PA14 on WBR3. Apply patches/wbr3-pa13-pa14-uart.patch (or the helper
|
||
|
|
# script in patches/) before compiling if Tuya stays at init_state 0.
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
substitutions:
|
||
|
|
device_name: wake-up-light-ii
|
||
|
|
friendly_name: "Wake Up Light II"
|
||
|
|
ap_ssid: "Wake-Up-Light-II"
|
||
|
|
ap_password: "wakeup1234" # Change before publishing/regular use.
|
||
|
|
timezone: "Europe/Berlin" # Change to your IANA timezone.
|
||
|
|
|
||
|
|
esphome:
|
||
|
|
name: ${device_name}
|
||
|
|
friendly_name: ${friendly_name}
|
||
|
|
|
||
|
|
rtl87xx:
|
||
|
|
board: wbr3
|
||
|
|
|
||
|
|
# Disable serial logging: PA13/PA14 belong to the Tuya MCU link.
|
||
|
|
logger:
|
||
|
|
baud_rate: 0
|
||
|
|
level: DEBUG
|
||
|
|
|
||
|
|
uart:
|
||
|
|
id: tuya_uart
|
||
|
|
rx_pin: PA13
|
||
|
|
tx_pin: PA14
|
||
|
|
baud_rate: 9600
|
||
|
|
data_bits: 8
|
||
|
|
parity: NONE
|
||
|
|
stop_bits: 1
|
||
|
|
|
||
|
|
# Useful while reverse-engineering additional datapoints:
|
||
|
|
# debug:
|
||
|
|
# direction: BOTH
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Cached state
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
globals:
|
||
|
|
# DP127 is a 16-byte alarm structure on this unit. Never build it from
|
||
|
|
# scratch: cache what the appliance MCU reported and only edit known bytes.
|
||
|
|
- id: alarm_raw
|
||
|
|
type: uint8_t[16]
|
||
|
|
restore_value: no
|
||
|
|
|
||
|
|
- id: alarm_raw_valid
|
||
|
|
type: bool
|
||
|
|
restore_value: no
|
||
|
|
initial_value: 'false'
|
||
|
|
|
||
|
|
- id: lamp_clock_hour
|
||
|
|
type: uint8_t
|
||
|
|
restore_value: no
|
||
|
|
initial_value: '0'
|
||
|
|
|
||
|
|
- id: lamp_clock_minute
|
||
|
|
type: uint8_t
|
||
|
|
restore_value: no
|
||
|
|
initial_value: '0'
|
||
|
|
|
||
|
|
- id: lamp_clock_second
|
||
|
|
type: uint8_t
|
||
|
|
restore_value: no
|
||
|
|
initial_value: '0'
|
||
|
|
|
||
|
|
- id: lamp_clock_valid
|
||
|
|
type: bool
|
||
|
|
restore_value: no
|
||
|
|
initial_value: 'false'
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Optional network time
|
||
|
|
#
|
||
|
|
# SNTP works only if the lamp can reach an NTP server. In AP-only operation
|
||
|
|
# there is no upstream network, so use the writable "Lamp Clock" control.
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
time:
|
||
|
|
- platform: sntp
|
||
|
|
id: network_time
|
||
|
|
timezone: ${timezone}
|
||
|
|
servers:
|
||
|
|
- 0.pool.ntp.org
|
||
|
|
- 1.pool.ntp.org
|
||
|
|
- 2.pool.ntp.org
|
||
|
|
update_interval: 1h
|
||
|
|
|
||
|
|
on_time_sync:
|
||
|
|
then:
|
||
|
|
- delay: 2s
|
||
|
|
- script.execute: sync_lamp_clock
|
||
|
|
|
||
|
|
on_time:
|
||
|
|
- seconds: 0
|
||
|
|
minutes: 0
|
||
|
|
then:
|
||
|
|
- script.execute: sync_lamp_clock
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Tuya MCU
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
tuya:
|
||
|
|
id: tuya_mcu
|
||
|
|
time_id: network_time
|
||
|
|
|
||
|
|
on_datapoint_update:
|
||
|
|
# DP103: ASCII HHMMSS, for example "173700" = 17:37:00.
|
||
|
|
- sensor_datapoint: 103
|
||
|
|
datapoint_type: string
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
if (x.size() != 6) return;
|
||
|
|
auto d = [](char c) -> int { return (c >= '0' && c <= '9') ? c - '0' : -1; };
|
||
|
|
int h1=d(x[0]), h2=d(x[1]), m1=d(x[2]), m2=d(x[3]), s1=d(x[4]), s2=d(x[5]);
|
||
|
|
if (h1 < 0 || h2 < 0 || m1 < 0 || m2 < 0 || s1 < 0 || s2 < 0) return;
|
||
|
|
uint8_t hh = h1 * 10 + h2;
|
||
|
|
uint8_t mm = m1 * 10 + m2;
|
||
|
|
uint8_t ss = s1 * 10 + s2;
|
||
|
|
if (hh > 23 || mm > 59 || ss > 59) return;
|
||
|
|
id(lamp_clock_hour) = hh;
|
||
|
|
id(lamp_clock_minute) = mm;
|
||
|
|
id(lamp_clock_second) = ss;
|
||
|
|
id(lamp_clock_valid) = true;
|
||
|
|
char buf[16];
|
||
|
|
snprintf(buf, sizeof(buf), "%02u:%02u:%02u", hh, mm, ss);
|
||
|
|
id(clock_time_text).publish_state(buf);
|
||
|
|
|
||
|
|
# DP107: FM station/preset data. Encoding is not decoded yet.
|
||
|
|
- sensor_datapoint: 107
|
||
|
|
datapoint_type: raw
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
id(radio_station_raw).publish_state(format_hex_pretty(x));
|
||
|
|
|
||
|
|
# Keep cached DP127 enable bytes coherent when the dedicated enable DPs move.
|
||
|
|
- sensor_datapoint: 109
|
||
|
|
datapoint_type: bool
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
if (id(alarm_raw_valid)) id(alarm_raw)[0] = x ? 1 : 0;
|
||
|
|
|
||
|
|
- sensor_datapoint: 122
|
||
|
|
datapoint_type: bool
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
if (id(alarm_raw_valid)) id(alarm_raw)[12] = x ? 1 : 0;
|
||
|
|
|
||
|
|
# DP127: alarm configuration. Confirmed 16-byte layout on this unit:
|
||
|
|
# [00] Alarm 1 enabled
|
||
|
|
# [01:02] Alarm 1 time = minutes since midnight, big-endian
|
||
|
|
# [03] Alarm 1 weekday mask (0x7F observed = all days; bit order unknown)
|
||
|
|
# [04] unknown (0x1E observed)
|
||
|
|
# [05] Alarm 1 wake-light enable (0/1)
|
||
|
|
# [06] Alarm 1 sound: 0=off, 1..7=built-in, 8=FM
|
||
|
|
# [07] Alarm 1 volume 1..16
|
||
|
|
# [08] unknown (0x04 observed)
|
||
|
|
# [09] sunrise lead/duration in minutes (10..60 according to manual)
|
||
|
|
# [10] wake-light brightness 0..20
|
||
|
|
# [11] unknown
|
||
|
|
# [12] Alarm 2 enabled
|
||
|
|
# [13:14] Alarm 2 time = minutes since midnight, big-endian
|
||
|
|
# [15] Alarm 2 weekday mask
|
||
|
|
# Alarm 2 sound/volume/light/duration changes did NOT change DP127.
|
||
|
|
- sensor_datapoint: 127
|
||
|
|
datapoint_type: raw
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
id(alarm_settings_raw).publish_state(format_hex_pretty(x));
|
||
|
|
if (x.size() != 16) {
|
||
|
|
ESP_LOGW("alarm", "Unexpected DP127 size: %u", (unsigned) x.size());
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
for (size_t i = 0; i < 16; i++) id(alarm_raw)[i] = x[i];
|
||
|
|
id(alarm_raw_valid) = true;
|
||
|
|
|
||
|
|
uint16_t a1 = (static_cast<uint16_t>(x[1]) << 8) | x[2];
|
||
|
|
uint16_t a2 = (static_cast<uint16_t>(x[13]) << 8) | x[14];
|
||
|
|
unsigned a1_h = a1 / 60, a1_m = a1 % 60;
|
||
|
|
unsigned a2_h = a2 / 60, a2_m = a2 % 60;
|
||
|
|
|
||
|
|
char sound[20];
|
||
|
|
if (x[6] == 0) snprintf(sound, sizeof(sound), "Sound off");
|
||
|
|
else if (x[6] == 8) snprintf(sound, sizeof(sound), "FM");
|
||
|
|
else snprintf(sound, sizeof(sound), "Sound %u", (unsigned) x[6]);
|
||
|
|
|
||
|
|
char buf[256];
|
||
|
|
snprintf(buf, sizeof(buf),
|
||
|
|
"A1 %s %02u:%02u days=0x%02X | %s vol=%u | light=%s %u/20 | sunrise=%u min | A2 %s %02u:%02u days=0x%02X",
|
||
|
|
x[0] ? "ON" : "OFF", a1_h, a1_m, x[3], sound, x[7],
|
||
|
|
x[5] ? "ON" : "OFF", x[10], x[9],
|
||
|
|
x[12] ? "ON" : "OFF", a2_h, a2_m, x[15]);
|
||
|
|
id(alarm_summary).publish_state(buf);
|
||
|
|
|
||
|
|
# DP128: sleep/sunset structure, not fully decoded yet.
|
||
|
|
- sensor_datapoint: 128
|
||
|
|
datapoint_type: raw
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
id(sunset_settings_raw).publish_state(format_hex_pretty(x));
|
||
|
|
|
||
|
|
# DP132 exists in the exact-PID tuya-local definition as ambient color/effect.
|
||
|
|
# Keep it read-only until this hardware revision is mapped directly.
|
||
|
|
- sensor_datapoint: 132
|
||
|
|
datapoint_type: string
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
id(ambient_mode_raw).publish_state(x);
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Helper scripts
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
script:
|
||
|
|
- id: send_alarm_settings
|
||
|
|
mode: restart
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) {
|
||
|
|
ESP_LOGW("alarm", "DP127 has not been received yet; refusing to overwrite it");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
std::vector<uint8_t> data(id(alarm_raw), id(alarm_raw) + 16);
|
||
|
|
ESP_LOGD("alarm", "Writing DP127: %s", format_hex_pretty(data).c_str());
|
||
|
|
id(tuya_mcu).set_raw_datapoint_value(127, data);
|
||
|
|
|
||
|
|
- id: sync_lamp_clock
|
||
|
|
mode: restart
|
||
|
|
then:
|
||
|
|
- lambda: |-
|
||
|
|
auto now = id(network_time).now();
|
||
|
|
if (!now.is_valid()) {
|
||
|
|
ESP_LOGW("clock", "No valid network time; use the Lamp Clock control in the web UI");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
char buf[7];
|
||
|
|
snprintf(buf, sizeof(buf), "%02u%02u%02u", now.hour, now.minute, now.second);
|
||
|
|
ESP_LOGI("clock", "Syncing lamp clock to %s", buf);
|
||
|
|
id(tuya_mcu).set_string_datapoint_value(103, std::string(buf));
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Main lamp
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
light:
|
||
|
|
- platform: tuya
|
||
|
|
id: main_light
|
||
|
|
name: "Main Light"
|
||
|
|
switch_datapoint: 101
|
||
|
|
dimmer_datapoint: 102
|
||
|
|
min_value: 10
|
||
|
|
max_value: 1000
|
||
|
|
gamma_correct: 1.0
|
||
|
|
default_transition_length: 0s
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Writable clock/alarm times
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
datetime:
|
||
|
|
- platform: template
|
||
|
|
id: lamp_clock
|
||
|
|
name: "Lamp Clock"
|
||
|
|
type: time
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(lamp_clock_valid)) return {};
|
||
|
|
ESPTime t{};
|
||
|
|
t.hour = id(lamp_clock_hour);
|
||
|
|
t.minute = id(lamp_clock_minute);
|
||
|
|
t.second = id(lamp_clock_second);
|
||
|
|
return t;
|
||
|
|
set_action:
|
||
|
|
- lambda: |-
|
||
|
|
char buf[7];
|
||
|
|
snprintf(buf, sizeof(buf), "%02u%02u%02u", x.hour, x.minute, x.second);
|
||
|
|
ESP_LOGI("clock", "Setting lamp clock to %s", buf);
|
||
|
|
id(tuya_mcu).set_string_datapoint_value(103, std::string(buf));
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_1_time
|
||
|
|
name: "Alarm 1 Time"
|
||
|
|
type: time
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return {};
|
||
|
|
uint16_t mins = (static_cast<uint16_t>(id(alarm_raw)[1]) << 8) | id(alarm_raw)[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<uint16_t>(x.hour) * 60 + x.minute;
|
||
|
|
id(alarm_raw)[1] = (mins >> 8) & 0xFF;
|
||
|
|
id(alarm_raw)[2] = mins & 0xFF;
|
||
|
|
- script.execute: send_alarm_settings
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_2_time
|
||
|
|
name: "Alarm 2 Time"
|
||
|
|
type: time
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return {};
|
||
|
|
uint16_t mins = (static_cast<uint16_t>(id(alarm_raw)[13]) << 8) | id(alarm_raw)[14];
|
||
|
|
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<uint16_t>(x.hour) * 60 + x.minute;
|
||
|
|
id(alarm_raw)[13] = (mins >> 8) & 0xFF;
|
||
|
|
id(alarm_raw)[14] = mins & 0xFF;
|
||
|
|
- script.execute: send_alarm_settings
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Selects
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
select:
|
||
|
|
- platform: tuya
|
||
|
|
id: clock_display_mode
|
||
|
|
name: "Clock Display"
|
||
|
|
int_datapoint: 104
|
||
|
|
options:
|
||
|
|
0: "Off"
|
||
|
|
1: "Day"
|
||
|
|
2: "Night"
|
||
|
|
3: "Auto"
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_1_sound
|
||
|
|
name: "Alarm 1 Sound"
|
||
|
|
options:
|
||
|
|
- "Off"
|
||
|
|
- "Sound 1"
|
||
|
|
- "Sound 2"
|
||
|
|
- "Sound 3"
|
||
|
|
- "Sound 4"
|
||
|
|
- "Sound 5"
|
||
|
|
- "Sound 6"
|
||
|
|
- "Sound 7"
|
||
|
|
- "FM Radio"
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return {};
|
||
|
|
uint8_t s = id(alarm_raw)[6];
|
||
|
|
if (s == 0) return std::string("Off");
|
||
|
|
if (s == 8) return std::string("FM Radio");
|
||
|
|
if (s >= 1 && s <= 7) return std::string("Sound ") + std::to_string(s);
|
||
|
|
return {};
|
||
|
|
set_action:
|
||
|
|
- lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return;
|
||
|
|
uint8_t value = 0;
|
||
|
|
if (x == "Sound 1") value = 1;
|
||
|
|
else if (x == "Sound 2") value = 2;
|
||
|
|
else if (x == "Sound 3") value = 3;
|
||
|
|
else if (x == "Sound 4") value = 4;
|
||
|
|
else if (x == "Sound 5") value = 5;
|
||
|
|
else if (x == "Sound 6") value = 6;
|
||
|
|
else if (x == "Sound 7") value = 7;
|
||
|
|
else if (x == "FM Radio") value = 8;
|
||
|
|
id(alarm_raw)[6] = value;
|
||
|
|
- script.execute: send_alarm_settings
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Numbers
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
number:
|
||
|
|
- platform: tuya
|
||
|
|
id: radio_volume
|
||
|
|
name: "Radio Volume"
|
||
|
|
number_datapoint: 106
|
||
|
|
min_value: 1
|
||
|
|
max_value: 16
|
||
|
|
step: 1
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_1_volume
|
||
|
|
name: "Alarm 1 Volume"
|
||
|
|
min_value: 1
|
||
|
|
max_value: 16
|
||
|
|
step: 1
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return {};
|
||
|
|
return static_cast<float>(id(alarm_raw)[7]);
|
||
|
|
set_action:
|
||
|
|
- lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return;
|
||
|
|
id(alarm_raw)[7] = static_cast<uint8_t>(x);
|
||
|
|
- script.execute: send_alarm_settings
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_1_wake_brightness
|
||
|
|
name: "Alarm 1 Wake Light"
|
||
|
|
min_value: 0
|
||
|
|
max_value: 20
|
||
|
|
step: 1
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return {};
|
||
|
|
if (id(alarm_raw)[5] == 0) return 0.0f;
|
||
|
|
return static_cast<float>(id(alarm_raw)[10]);
|
||
|
|
set_action:
|
||
|
|
- lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return;
|
||
|
|
uint8_t level = static_cast<uint8_t>(x);
|
||
|
|
if (level == 0) {
|
||
|
|
id(alarm_raw)[5] = 0;
|
||
|
|
id(alarm_raw)[10] = 0;
|
||
|
|
} else {
|
||
|
|
id(alarm_raw)[5] = 1;
|
||
|
|
id(alarm_raw)[10] = level;
|
||
|
|
}
|
||
|
|
- script.execute: send_alarm_settings
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_1_sunrise_duration
|
||
|
|
name: "Alarm 1 Sunrise Duration"
|
||
|
|
unit_of_measurement: "min"
|
||
|
|
min_value: 10
|
||
|
|
max_value: 60
|
||
|
|
step: 10
|
||
|
|
update_interval: 2s
|
||
|
|
lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return {};
|
||
|
|
return static_cast<float>(id(alarm_raw)[9]);
|
||
|
|
set_action:
|
||
|
|
- lambda: |-
|
||
|
|
if (!id(alarm_raw_valid)) return;
|
||
|
|
id(alarm_raw)[9] = static_cast<uint8_t>(x);
|
||
|
|
- script.execute: send_alarm_settings
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Switches
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
switch:
|
||
|
|
- platform: tuya
|
||
|
|
id: fm_radio
|
||
|
|
name: "FM Radio"
|
||
|
|
switch_datapoint: 105
|
||
|
|
|
||
|
|
- platform: tuya
|
||
|
|
id: alarm_1_enable
|
||
|
|
name: "Alarm 1"
|
||
|
|
switch_datapoint: 109
|
||
|
|
|
||
|
|
- platform: tuya
|
||
|
|
id: alarm_2_enable
|
||
|
|
name: "Alarm 2"
|
||
|
|
switch_datapoint: 122
|
||
|
|
|
||
|
|
- platform: tuya
|
||
|
|
id: sunset_mode
|
||
|
|
name: "Sunset / Sleep Mode"
|
||
|
|
switch_datapoint: 121
|
||
|
|
|
||
|
|
- platform: tuya
|
||
|
|
id: ambient_light
|
||
|
|
name: "Ambient Light"
|
||
|
|
switch_datapoint: 129
|
||
|
|
|
||
|
|
- platform: tuya
|
||
|
|
id: clock_24_hour
|
||
|
|
name: "24 Hour Clock"
|
||
|
|
switch_datapoint: 131
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Diagnostics / still-undecoded payloads
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
text_sensor:
|
||
|
|
- platform: template
|
||
|
|
id: clock_time_text
|
||
|
|
name: "Clock Time"
|
||
|
|
update_interval: never
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: radio_station_raw
|
||
|
|
name: "Radio Station Raw"
|
||
|
|
update_interval: never
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_summary
|
||
|
|
name: "Alarm Settings"
|
||
|
|
update_interval: never
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: alarm_settings_raw
|
||
|
|
name: "Alarm Settings Raw"
|
||
|
|
update_interval: never
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: sunset_settings_raw
|
||
|
|
name: "Sunset Settings Raw"
|
||
|
|
update_interval: never
|
||
|
|
|
||
|
|
- platform: template
|
||
|
|
id: ambient_mode_raw
|
||
|
|
name: "Ambient Mode Raw"
|
||
|
|
update_interval: never
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Buttons
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
button:
|
||
|
|
- platform: template
|
||
|
|
name: "Sync Lamp Clock Now"
|
||
|
|
icon: "mdi:clock-sync"
|
||
|
|
on_press:
|
||
|
|
- script.execute: sync_lamp_clock
|
||
|
|
|
||
|
|
- platform: restart
|
||
|
|
name: "Restart Wake Up Light"
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Networking
|
||
|
|
#
|
||
|
|
# Default: permanent standalone AP. Connect to Wake-Up-Light-II and open
|
||
|
|
# http://192.168.4.1/ . No Internet is required for the local web UI.
|
||
|
|
#
|
||
|
|
# To also join a normal 2.4 GHz network (needed for public SNTP), uncomment:
|
||
|
|
# ssid: !secret wifi_ssid
|
||
|
|
# password: !secret wifi_password
|
||
|
|
# The AP below then becomes fallback AP.
|
||
|
|
#
|
||
|
|
# Do NOT add captive_portal if you want the normal control UI at 192.168.4.1;
|
||
|
|
# captive_portal presents the Wi-Fi provisioning/OTA page instead.
|
||
|
|
###############################################################################
|
||
|
|
|
||
|
|
wifi:
|
||
|
|
# ssid: !secret wifi_ssid
|
||
|
|
# password: !secret wifi_password
|
||
|
|
ap:
|
||
|
|
ssid: ${ap_ssid}
|
||
|
|
password: ${ap_password}
|
||
|
|
|
||
|
|
web_server:
|
||
|
|
port: 80
|
||
|
|
version: 2
|
||
|
|
local: true
|
||
|
|
# Recommended on a shared LAN:
|
||
|
|
# auth:
|
||
|
|
# username: admin
|
||
|
|
# password: !secret web_password
|
||
|
|
|
||
|
|
ota:
|
||
|
|
- platform: esphome
|
||
|
|
- platform: web_server
|
||
|
|
|
||
|
|
###############################################################################
|
||
|
|
# Exact-PID tuya-local definition also lists these DPs, but they are not enabled
|
||
|
|
# above until verified on this physical two-alarm hardware revision:
|
||
|
|
# DP116 snooze duration (8..15 min)
|
||
|
|
# DP117 snooze action
|
||
|
|
# DP125 network-time switch
|
||
|
|
# DP126 radio seek/stop
|
||
|
|
# DP130 snooze
|
||
|
|
# DP132 ambient color/effect (currently shown read-only as Ambient Mode Raw)
|
||
|
|
# It also lists DP123/124 as alarm 3/4, but this unit has only two physical
|
||
|
|
# alarms/indications, so they are intentionally not exposed here.
|
||
|
|
###############################################################################
|