A nightstand noise generator based on M5Stack Atom Echo and integrating with Home Assistant
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 130 lines 5.4 kB view raw
1# Firmware build entry points. 2# 3# Wraps cargo with the env tweaks needed on hosts where libxml2 has bumped 4# past .so.2 (Ubuntu Questing 25.10+ ships .so.16). The .lib/libxml2.so.2 5# symlink in this directory points at the system library so esp-clang loads. 6# 7# Cargo handles its own incremental rebuilds, so these are all phony. 8 9LIB_DIR := $(CURDIR)/.lib 10LIBXML2_COMPAT := $(LIB_DIR)/libxml2.so.2 11SYSTEM_LIBXML2 := $(firstword $(wildcard /usr/lib/x86_64-linux-gnu/libxml2.so.16 /usr/lib/libxml2.so.16)) 12 13export LD_LIBRARY_PATH := $(LIB_DIR):$(LD_LIBRARY_PATH) 14 15# Inject the absolute path to partitions.csv via a generated overlay file. 16# ESP-IDF resolves relative CONFIG_PARTITION_TABLE_FILENAME against an 17# internal CMake source dir under target/, not against this directory, so 18# baking a relative path into the committed sdkconfig.defaults would fail. 19# Generating the overlay here keeps the committed config portable. 20GEN_DIR := $(CURDIR)/target/gen 21GEN_PARTITIONS_SDKCONFIG := $(GEN_DIR)/sdkconfig.defaults.partitions 22PARTITIONS_CSV := $(CURDIR)/partitions.csv 23 24# esp-idf-sys reads ESP_IDF_SDKCONFIG_DEFAULTS as the list of project sdkconfig 25# defaults files (it then internally builds its own SDKCONFIG_DEFAULTS env var 26# for cmake by prepending its generated defaults). 27export ESP_IDF_SDKCONFIG_DEFAULTS := $(CURDIR)/sdkconfig.defaults;$(GEN_PARTITIONS_SDKCONFIG) 28 29CARGO ?= cargo 30BIN := target/xtensa-esp32-espidf/release/sound-machine 31BOOTLOADER_BIN := target/xtensa-esp32-espidf/release/bootloader.bin 32# First /dev/ttyUSB* / /dev/ttyACM* found, used for headless flashing. 33# Override on the command line: `make flash PORT=/dev/ttyUSB1` 34PORT ?= $(firstword $(wildcard /dev/ttyUSB* /dev/ttyACM*)) 35 36# Firmware version, parsed from Cargo.toml. Used for the OTA filename and 37# the latest_version MQTT publish. 38VERSION := $(shell sed -nE '0,/^version *= *"([^"]+)"/{s//\1/p}' Cargo.toml) 39OTA_BIN := sound-machine-$(VERSION).bin 40 41.PHONY: build check flash flash-monitor monitor clean help ota-publish $(LIBXML2_COMPAT) 42 43build: $(LIBXML2_COMPAT) $(GEN_PARTITIONS_SDKCONFIG) 44 $(CARGO) build --release 45 46check: $(LIBXML2_COMPAT) $(GEN_PARTITIONS_SDKCONFIG) 47 $(CARGO) check 48 49# Headless flash — builds, then writes to the device with no interactive 50# monitor. Safe to run from any shell, including non-TTY contexts. Auto- 51# detects the first ttyUSB*/ttyACM*; override with PORT=/dev/... 52flash: build 53 @if [ -z "$(PORT)" ]; then \ 54 echo "no serial port found (looked for /dev/ttyUSB* and /dev/ttyACM*)"; \ 55 exit 1; \ 56 fi 57 espflash flash --port $(PORT) \ 58 --bootloader $(BOOTLOADER_BIN) \ 59 --partition-table $(PARTITIONS_CSV) \ 60 --erase-parts otadata \ 61 $(BIN) 62 63# Interactive flash + monitor — builds, flashes, attaches the serial monitor. 64# Needs a TTY (the monitor writes to terminal and reads keyboard input). 65flash-monitor: $(LIBXML2_COMPAT) $(GEN_PARTITIONS_SDKCONFIG) 66 $(CARGO) run --release 67 68monitor: 69 espflash monitor 70 71# Publish a new firmware version. Reads OTA_LOCAL_DIR / OTA_URL_BASE / MQTT_URL 72# from the environment (sourced via direnv from .envrc.private). Builds the 73# release binary, generates the flat .bin via espflash save-image, copies it 74# into the static-HTTP serve directory, then publishes the new latest_version 75# retained to the shared MQTT topic. Both nightstands' HA update cards light 76# up the moment the publish lands. 77ota-publish: build 78 @if [ -z "$(OTA_LOCAL_DIR)" ]; then \ 79 echo "OTA_LOCAL_DIR is not set (see .envrc.private.example)"; exit 1; \ 80 fi 81 @if [ -z "$(OTA_URL_BASE)" ]; then \ 82 echo "OTA_URL_BASE is not set (see .envrc.private.example)"; exit 1; \ 83 fi 84 @if [ -z "$(MQTT_URL)" ]; then \ 85 echo "MQTT_URL is not set (see .envrc.private.example)"; exit 1; \ 86 fi 87 @if [ -z "$(VERSION)" ]; then \ 88 echo "could not parse version from Cargo.toml"; exit 1; \ 89 fi 90 @echo "publishing v$(VERSION)$(OTA_URL_BASE)/$(OTA_BIN)" 91 espflash save-image --chip esp32 --flash-size 4mb $(BIN) $(OTA_LOCAL_DIR)/$(OTA_BIN) 92 mosquitto_pub \ 93 -L "$(MQTT_URL)/sound-machine/firmware/latest" \ 94 -r \ 95 -m "$(VERSION)" 96 @echo "done. devices will see the update in HA within a few seconds." 97 98clean: 99 $(CARGO) clean 100 101# The compat symlink. Created on demand if the system has libxml2.so.16. 102# Skipped silently if it already exists or the system has a newer libxml2. 103$(LIBXML2_COMPAT): 104 @if [ ! -e "$@" ]; then \ 105 if [ -n "$(SYSTEM_LIBXML2)" ]; then \ 106 mkdir -p $(LIB_DIR); \ 107 ln -sf $(SYSTEM_LIBXML2) $@; \ 108 echo "linked $@ -> $(SYSTEM_LIBXML2)"; \ 109 else \ 110 echo "warning: no system libxml2.so.16 found; esp-clang may fail to load"; \ 111 fi; \ 112 fi 113 114# Generated sdkconfig overlay carrying the absolute path to partitions.csv. 115# Regenerated whenever the CSV or this Makefile changes. 116$(GEN_PARTITIONS_SDKCONFIG): $(PARTITIONS_CSV) $(MAKEFILE_LIST) 117 @mkdir -p $(GEN_DIR) 118 @printf 'CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="%s"\nCONFIG_PARTITION_TABLE_FILENAME="%s"\n' \ 119 '$(PARTITIONS_CSV)' '$(PARTITIONS_CSV)' > $@ 120 @echo "generated $@" 121 122help: 123 @echo "firmware targets:" 124 @echo " build cargo build --release (default)" 125 @echo " check cargo check" 126 @echo " flash headless: build + flash, no monitor (works in any shell)" 127 @echo " flash-monitor interactive: build + flash + serial monitor (needs a TTY)" 128 @echo " monitor espflash monitor only" 129 @echo " ota-publish save .bin to \$$OTA_LOCAL_DIR + publish latest_version to MQTT" 130 @echo " clean cargo clean"