Compare commits
6 Commits
review
...
15257ae6f2
| Author | SHA1 | Date | |
|---|---|---|---|
| 15257ae6f2 | |||
|
795eb0ecf3
|
|||
|
558c5b18c2
|
|||
|
fa66dd70d4
|
|||
|
b14bdf7fc3
|
|||
|
427dde8c72
|
@@ -794,6 +794,24 @@ bool parsePosQuery(const String& line) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Answers `CFG?` with speed and acceleration for every gauge.
|
||||||
|
// Emits one `CFG <id> <maxSpeed> <accel>` line per gauge, then replies `OK`.
|
||||||
|
bool parseCfgQuery(const String& line) {
|
||||||
|
if (line == "CFG?") {
|
||||||
|
for (uint8_t i = 0; i < GAUGE_COUNT; i++) {
|
||||||
|
CMD_PORT.print("CFG ");
|
||||||
|
CMD_PORT.print(i);
|
||||||
|
CMD_PORT.print(' ');
|
||||||
|
CMD_PORT.print((int)gauges[i].maxSpeed);
|
||||||
|
CMD_PORT.print(' ');
|
||||||
|
CMD_PORT.println((int)gauges[i].accel);
|
||||||
|
}
|
||||||
|
sendReply("OK");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Answers the mandatory life question: are you there?
|
// Answers the mandatory life question: are you there?
|
||||||
// Reply: `PONG`.
|
// Reply: `PONG`.
|
||||||
bool parsePing(const String& line) {
|
bool parsePing(const String& line) {
|
||||||
@@ -1058,6 +1076,7 @@ void processLine(const String& line) {
|
|||||||
if (parseHome(line)) return;
|
if (parseHome(line)) return;
|
||||||
if (parseSweep(line)) return;
|
if (parseSweep(line)) return;
|
||||||
if (parsePosQuery(line)) return;
|
if (parsePosQuery(line)) return;
|
||||||
|
if (parseCfgQuery(line)) return;
|
||||||
if (parseLedQuery(line)) return;
|
if (parseLedQuery(line)) return;
|
||||||
if (parseLed(line)) return;
|
if (parseLed(line)) return;
|
||||||
if (parseBlink(line)) return;
|
if (parseBlink(line)) return;
|
||||||
|
|||||||
64
boot.py
64
boot.py
@@ -1,64 +0,0 @@
|
|||||||
"""
|
|
||||||
boot.py — runs before main.py on every ESP32 boot
|
|
||||||
|
|
||||||
Connects WiFi, runs OTA update, then hands off to main.py.
|
|
||||||
Keep this file as simple as possible — it is never OTA-updated itself
|
|
||||||
(it lives outside the repo folder) so bugs here require USB to fix.
|
|
||||||
"""
|
|
||||||
import gauge
|
|
||||||
import network
|
|
||||||
import gc
|
|
||||||
import utime
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import ota
|
|
||||||
|
|
||||||
ota.load_config()
|
|
||||||
WIFI_SSID, WIFI_PASSWORD = ota.WIFI_SSID, ota.WIFI_PASSWORD
|
|
||||||
|
|
||||||
def _connect_wifi(timeout_s=20):
|
|
||||||
sta = network.WLAN(network.STA_IF)
|
|
||||||
sta.active(True)
|
|
||||||
sta.config(txpower=15)
|
|
||||||
if sta.isconnected():
|
|
||||||
return True
|
|
||||||
sta.connect(WIFI_SSID, WIFI_PASSWORD)
|
|
||||||
deadline = utime.time() + timeout_s
|
|
||||||
while not sta.isconnected():
|
|
||||||
if utime.time() > deadline:
|
|
||||||
return False
|
|
||||||
utime.sleep_ms(300)
|
|
||||||
return True
|
|
||||||
|
|
||||||
if WIFI_SSID is None:
|
|
||||||
print("[boot] No WiFi credentials — cannot connect, skipping OTA")
|
|
||||||
elif _connect_wifi():
|
|
||||||
ip = network.WLAN(network.STA_IF).ifconfig()[0]
|
|
||||||
print(f"[boot] WiFi connected — {ip}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
ota.update()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[boot] OTA error: {e} — continuing with existing files")
|
|
||||||
sys.print_exception(e)
|
|
||||||
utime.sleep_ms(5000)
|
|
||||||
ota._fetch_commit_sha = None
|
|
||||||
ota._fetch_manifest = None
|
|
||||||
ota._fetch_dir = None
|
|
||||||
ota._api_get = None
|
|
||||||
ota._download = None
|
|
||||||
ota.urequests = None
|
|
||||||
del ota.urequests
|
|
||||||
del ota
|
|
||||||
gc.collect()
|
|
||||||
del sys.modules["ota"]
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("[boot] WiFi failed — skipping OTA, booting with existing files")
|
|
||||||
|
|
||||||
# main.py runs automatically after boot.py
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2469
esp-home-rewrite.yaml
Normal file
2469
esp-home-rewrite.yaml
Normal file
File diff suppressed because it is too large
Load Diff
15
gauge.py
15
gauge.py
@@ -930,6 +930,19 @@ _last_discovery_ms = 0
|
|||||||
_DISCOVERY_INTERVAL_MS = 350
|
_DISCOVERY_INTERVAL_MS = 350
|
||||||
|
|
||||||
|
|
||||||
|
def _compact_discovery_payload(payload):
|
||||||
|
"""Trim optional HA discovery fields when RAM is tight."""
|
||||||
|
compact = dict(payload)
|
||||||
|
|
||||||
|
# Light entities are the largest payloads because they repeat effect metadata.
|
||||||
|
# Keep core functionality, but omit optional effect declarations to reduce heap use.
|
||||||
|
if compact.get("schema") == "json":
|
||||||
|
compact.pop("effect", None)
|
||||||
|
compact.pop("effect_list", None)
|
||||||
|
|
||||||
|
return compact
|
||||||
|
|
||||||
|
|
||||||
def check_mqtt():
|
def check_mqtt():
|
||||||
global client_ref, _mqtt_connected, _last_mqtt_check
|
global client_ref, _mqtt_connected, _last_mqtt_check
|
||||||
now = utime.ticks_ms()
|
now = utime.ticks_ms()
|
||||||
@@ -984,7 +997,7 @@ def check_mqtt():
|
|||||||
|
|
||||||
def _publish_discovery_entity(client, topic, payload, log_msg):
|
def _publish_discovery_entity(client, topic, payload, log_msg):
|
||||||
gc.collect()
|
gc.collect()
|
||||||
client.publish(topic, ujson.dumps(payload), retain=True)
|
client.publish(topic, ujson.dumps(_compact_discovery_payload(payload)), retain=True)
|
||||||
info(log_msg)
|
info(log_msg)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user