Files
esphome-wake-up-light-ii/CLAUDE.md
T
mangavalkandClaude Opus 5.5 e6f004e811 Correct alarm data findings from byte tests
The alarm station byte is shared and follows the current radio station, so
remove the per-alarm control. Remove the FM sound option, as writing it just
turns on the radio mode. Record how the MCU treats each DP127 byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 17:38:23 +01:00

5.4 KiB

Wake Up Light II notes

ESPHome firmware for a Moes Wake Up Light II (Tuya PID ya39qahrcdhvxowz), running fully local. This repo is public, so never commit secrets, Wi-Fi details or device keys.

Layout

  • wake-up-light-ii.yaml: main config.
  • alarm_block.yaml: controls for one alarm, included 4 times.
  • alarm_day.yaml: one weekday switch, included 7 times per alarm.
  • components/uart: ESPHome 2026.10.2's UART component with patches/wbr3-pa13-pa14-uart.patch applied. Recheck it when ESPHome updates.
  • server-example.yaml: the short YAML that goes on an ESPHome server.
  • secrets.yaml: local only, ignored by git. Needs wifi_ssid, wifi_password, ap_password, api_encryption_key.

Releasing

  1. Set the ref in wake-up-light-ii.yaml's external_components to the new tag, then commit and tag that commit.
  2. Push the branch and the tag. On the owner's PC the first push can fail authentication, and a second try works.
  3. Update ref in the server's YAML, then press Install. OTA works, and the lamp restarts by itself.

Build from a short folder path: Windows path limits break the libsodium build otherwise.

Hardware

  • WBR3 module (RTL8720CF, 2 MiB flash), talking TuyaMCU at 9600 8N1 on PA13 (RX) and PA14 (TX).
  • Knock sensor: a switch between 3.3V and PA18, using the internal pull-down.
  • UART flashing needs the module desoldered, because PA00 is on the underside. Adapter TX to PA15, RX to PA16, plus GND and a solid 3.3V. Hold PA00 at 3.3V, then tap CEN to GND. PA13 must not be pulled low.
  • Serial reads with ltchiptool run at about 3 KB/s, so a full 2 MiB backup takes about 16 minutes.
  • If the serial port says "access denied", another app has it. On the owner's PC that was SignalRGB.

Data model

From Tuya's definition for a sibling product (tuya-local issue #3821). See the README's corrections section for the byte layouts of DP127, DP128 and DP107.

DP Meaning
101, 102 Main light, brightness 10-1000
103 Clock, ASCII HHMMSS
104 Display: 0 off, 1 day, 2 night, 3 auto
105, 106 Radio on, volume 1-16
107 Stations found, current station
109, 122, 123, 124 Alarms 1 to 4 on
116, 117 Snooze minutes 8-15, snooze action enum
121, 128 Sunset on, sunset settings
125 Online time sync
126 Radio scan
127 Alarm settings, 48 bytes on this unit
129, 132 Ambient light on, colour enum
130 Snooze
131 24-hour clock

Observed behaviour

  • A raw UART capture of a ring, radio, scan and sunset showed only heartbeats and normal datapoint frames. No other message types, and no datapoints beyond these 22.
  • There is no "ringing" datapoint. A ring starts with DP101, 105, 121, 129 and 130 all OFF in one burst (3 of 3 rings). Arming an alarm inside its sunrise window sends only DP101, 121 and 129.
  • The stop and volume buttons send nothing to the chip, and neither did the window where a ring should have stopped by itself. So a hand-stopped alarm can't be detected without extra hardware.
  • A knock during a ring snoozes it. DP130 then stays ON. Outside an alarm it returns to OFF at once.
  • DP127 writes are ignored while an alarm is snoozed.
  • A mode without light sets brightness to 0, and a light mode with brightness 0 falls back to no light, so the firmware sets a level when choosing a light mode.
  • Byte tests on DP127 with Alarm 4 off: time, days, ring duration, volume, sunrise and (in light modes) brightness are stored as written, with no range check, so the controls must limit them. The time's high byte keeps only its low 4 bits.
  • Byte 5 is bits: 0 = light, 1 = radio. Above 3 is ignored.
  • Byte 6: writing 8 or more turns on the radio bit and sets the sound to 1. It's locked at 1 in radio modes.
  • Byte 8 isn't per alarm. Every DP127 write sets all 4 to the current radio station, so there's no per-alarm station control.
  • Byte 10 is forced to 0 without the light bit, and writing 0 clears the light bit.
  • Byte 11: above 1 becomes 1.
  • What byte 4 actually does to ring length isn't confirmed. A test ring wasn't observed stopping.
  • Radio Volume and station writes are ignored with the radio off. With it on, both work, and the station stays selected after turning it off.
  • Keep default_transition_length at 0. A transition sends about 50 MCU writes a second.
  • LibreTiny before v1.14.0 can hang after a software restart or OTA until powered off for about 30 seconds (LibreTiny issue #396). The config pins v1.14.0. Drop the pin once ESPHome defaults to it or newer.
  • "Last Restart Reason" reports Power-On even after software restarts.

Status

Verified:

  • Alarm and sunset settings are echoed by the MCU.
  • Wednesday-only rang on a Wednesday, which fits bit 0 = Monday. A Tuesday-only silent test was skipped.
  • Sunset starts and stops. Its sound was heard, and a glow was seen but not clearly caused by it.
  • A manual scan found 2 stations, while a scan started from the firmware found 0.
  • Next/Previous Station and Radio Station change the MCU's station, with wrap-around. Audio on them wasn't confirmed: the owner heard no radio signal.
  • Home Assistant is used as the time source when connected, with public NTP as the fallback.

Not tested:

  • Radio alarms.
  • Running without internet, or without Home Assistant.
  • Bedtime Fade and double knock on the real light.
  • Whether Ambient Color and Snooze Action labels match what the lamp does.

Decided against for now: an Alarm Ringing sensor, and a web UI password.