Fix MQTT 2-gauge issue: publish discovery only on first boot via flag file, add resetdiscovery topic, remove disco, clean up DEBUG prints and duplicate code
This commit is contained in:
@@ -24,7 +24,6 @@ import network
|
|||||||
import utime
|
import utime
|
||||||
import ujson
|
import ujson
|
||||||
import urandom
|
import urandom
|
||||||
print("DEBUG: imports done")
|
|
||||||
from umqtt.robust import MQTTClient
|
from umqtt.robust import MQTTClient
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
from neopixel import NeoPixel
|
from neopixel import NeoPixel
|
||||||
@@ -175,8 +174,6 @@ for g in gauges:
|
|||||||
gauge_targets = [g["min"] for g in gauges] # target value per gauge
|
gauge_targets = [g["min"] for g in gauges] # target value per gauge
|
||||||
gauge_last_rezero = [utime.ticks_ms() for _ in gauges]
|
gauge_last_rezero = [utime.ticks_ms() for _ in gauges]
|
||||||
|
|
||||||
print("DEBUG: gauge config parsed, creating topics...")
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Topics (per-gauge)
|
# Topics (per-gauge)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -209,13 +206,12 @@ def make_gauge_topics(prefix, gauge_id):
|
|||||||
|
|
||||||
gauge_topics = [make_gauge_topics(MQTT_PREFIX, g["id"]) for g in gauges]
|
gauge_topics = [make_gauge_topics(MQTT_PREFIX, g["id"]) for g in gauges]
|
||||||
|
|
||||||
print("DEBUG: topics created successfully")
|
|
||||||
|
|
||||||
T_SET = f"{MQTT_PREFIX}/set"
|
T_SET = f"{MQTT_PREFIX}/set"
|
||||||
T_STATE = f"{MQTT_PREFIX}/state"
|
T_STATE = f"{MQTT_PREFIX}/state"
|
||||||
T_STATUS = f"{MQTT_PREFIX}/status"
|
T_STATUS = f"{MQTT_PREFIX}/status"
|
||||||
T_ZERO = f"{MQTT_PREFIX}/zero"
|
T_ZERO = f"{MQTT_PREFIX}/zero"
|
||||||
T_DISCO = f"{MQTT_PREFIX}/disco"
|
T_RESET_DISCOVERY = f"{MQTT_PREFIX}/resetdiscovery"
|
||||||
|
|
||||||
T_DISC_GAUGE = f"homeassistant/number/{MQTT_CLIENT_ID}/config"
|
T_DISC_GAUGE = f"homeassistant/number/{MQTT_CLIENT_ID}/config"
|
||||||
T_DISC_RED = f"homeassistant/switch/{MQTT_CLIENT_ID}_red/config"
|
T_DISC_RED = f"homeassistant/switch/{MQTT_CLIENT_ID}_red/config"
|
||||||
@@ -223,35 +219,6 @@ T_DISC_GREEN = f"homeassistant/switch/{MQTT_CLIENT_ID}_green/config"
|
|||||||
T_DISC_BL = f"homeassistant/light/{MQTT_CLIENT_ID}_bl/config"
|
T_DISC_BL = f"homeassistant/light/{MQTT_CLIENT_ID}_bl/config"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_gauge_topics(prefix, gauge_id):
|
|
||||||
return {
|
|
||||||
"set": f"{prefix}/gauge{gauge_id}/set",
|
|
||||||
"state": f"{prefix}/gauge{gauge_id}/state",
|
|
||||||
"status": f"{prefix}/gauge{gauge_id}/status",
|
|
||||||
"zero": f"{prefix}/gauge{gauge_id}/zero",
|
|
||||||
"disc": f"homeassistant/number/{MQTT_CLIENT_ID}_g{gauge_id}/config",
|
|
||||||
"led_red": f"{prefix}/gauge{gauge_id}/led/red/set",
|
|
||||||
"led_green": f"{prefix}/gauge{gauge_id}/led/green/set",
|
|
||||||
"led_bl": f"{prefix}/gauge{gauge_id}/led/backlight/set",
|
|
||||||
"led_red_state": f"{prefix}/gauge{gauge_id}/led/red/state",
|
|
||||||
"led_green_state": f"{prefix}/gauge{gauge_id}/led/green/state",
|
|
||||||
"led_bl_state": f"{prefix}/gauge{gauge_id}/led/backlight/state",
|
|
||||||
"led_red_disc": f"homeassistant/switch/{MQTT_CLIENT_ID}_g{gauge_id}_red/config",
|
|
||||||
"led_green_disc": f"homeassistant/switch/{MQTT_CLIENT_ID}_g{gauge_id}_green/config",
|
|
||||||
"led_bl_disc": f"homeassistant/light/{MQTT_CLIENT_ID}_g{gauge_id}_bl/config",
|
|
||||||
"status_red": f"{prefix}/gauge{gauge_id}/status_led/red/set",
|
|
||||||
"status_green": f"{prefix}/gauge{gauge_id}/status_led/green/set",
|
|
||||||
"status_red_state": f"{prefix}/gauge{gauge_id}/status_led/red/state",
|
|
||||||
"status_green_state": f"{prefix}/gauge{gauge_id}/status_led/green/state",
|
|
||||||
"status_red_disc": f"homeassistant/switch/{MQTT_CLIENT_ID}_g{gauge_id}_status_red/config",
|
|
||||||
"status_green_disc": f"homeassistant/switch/{MQTT_CLIENT_ID}_g{gauge_id}_status_green/config",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
print("DEBUG: after duplicate function, about to define _DEVICE")
|
|
||||||
|
|
||||||
print("DEBUG: about to define _DEVICE dict")
|
|
||||||
_DEVICE = {
|
_DEVICE = {
|
||||||
"identifiers": [MQTT_CLIENT_ID],
|
"identifiers": [MQTT_CLIENT_ID],
|
||||||
"name": DEVICE_NAME,
|
"name": DEVICE_NAME,
|
||||||
@@ -259,24 +226,16 @@ _DEVICE = {
|
|||||||
"manufacturer": DEVICE_MFR,
|
"manufacturer": DEVICE_MFR,
|
||||||
"suggested_area": DEVICE_AREA,
|
"suggested_area": DEVICE_AREA,
|
||||||
}
|
}
|
||||||
print("DEBUG: _DEVICE defined")
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# WiFi
|
# WiFi
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
print("DEBUG: about to set wifi globals")
|
|
||||||
print("DEBUG: setting _wifi_reconnect_delay_s...")
|
|
||||||
_wifi_reconnect_delay_s = 5
|
_wifi_reconnect_delay_s = 5
|
||||||
print("DEBUG: setting _wifi_check_interval_ms...")
|
|
||||||
_wifi_check_interval_ms = 30000
|
_wifi_check_interval_ms = 30000
|
||||||
print("DEBUG: setting _last_wifi_check...")
|
|
||||||
_last_wifi_check = 0
|
_last_wifi_check = 0
|
||||||
print("DEBUG: setting _wifi_sta...")
|
|
||||||
_wifi_sta = None
|
_wifi_sta = None
|
||||||
print("DEBUG: wifi globals set")
|
|
||||||
|
|
||||||
print("DEBUG: defining connect_wifi function...")
|
|
||||||
def connect_wifi(ssid, password, timeout_s=15):
|
def connect_wifi(ssid, password, timeout_s=15):
|
||||||
global _wifi_sta
|
global _wifi_sta
|
||||||
_wifi_sta = network.WLAN(network.STA_IF)
|
_wifi_sta = network.WLAN(network.STA_IF)
|
||||||
@@ -331,32 +290,18 @@ def check_wifi():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
log_err(f"WiFi reconnect failed: {e}")
|
log_err(f"WiFi reconnect failed: {e}")
|
||||||
|
|
||||||
print("DEBUG: WiFi functions defined")
|
|
||||||
|
|
||||||
print("DEBUG: about to init LED pins")
|
|
||||||
print("DEBUG: computing len(gauges)...")
|
|
||||||
num_gauges = len(gauges)
|
num_gauges = len(gauges)
|
||||||
print(f"DEBUG: num_gauges = {num_gauges}")
|
|
||||||
leds_red = []
|
leds_red = []
|
||||||
leds_green = []
|
leds_green = []
|
||||||
leds_bl = []
|
leds_bl = []
|
||||||
print("DEBUG: about to loop over gauges for pins")
|
|
||||||
for g in gauges:
|
for g in gauges:
|
||||||
print(f"DEBUG: initializing pins for gauge: {g['name']}")
|
|
||||||
print(f"DEBUG: red_pin={g['red_pin']}, green_pin={g['green_pin']}")
|
|
||||||
print("DEBUG: creating red Pin...")
|
|
||||||
leds_red.append(Pin(g["red_pin"], Pin.OUT, value=0))
|
leds_red.append(Pin(g["red_pin"], Pin.OUT, value=0))
|
||||||
print("DEBUG: red Pin created, creating green Pin...")
|
|
||||||
leds_green.append(Pin(g["green_pin"], Pin.OUT, value=0))
|
leds_green.append(Pin(g["green_pin"], Pin.OUT, value=0))
|
||||||
print("DEBUG: green Pin created")
|
|
||||||
print("DEBUG: LED pins initialized")
|
|
||||||
|
|
||||||
total_backlight_leds = num_gauges * (BACKLIGHT_LEDS_PER_GAUGE + STATUS_LEDS_PER_GAUGE)
|
total_backlight_leds = num_gauges * (BACKLIGHT_LEDS_PER_GAUGE + STATUS_LEDS_PER_GAUGE)
|
||||||
print(f"DEBUG: initializing NeoPixel on pin {BACKLIGHT_PIN} with {total_backlight_leds} LEDs")
|
|
||||||
leds_bl = NeoPixel(Pin(BACKLIGHT_PIN), total_backlight_leds)
|
leds_bl = NeoPixel(Pin(BACKLIGHT_PIN), total_backlight_leds)
|
||||||
print("DEBUG: NeoPixel initialized")
|
|
||||||
|
|
||||||
print("DEBUG: about to init backlight arrays")
|
|
||||||
backlight_color = [(0, 0, 0) for _ in range(num_gauges)]
|
backlight_color = [(0, 0, 0) for _ in range(num_gauges)]
|
||||||
backlight_brightness = [100 for _ in range(num_gauges)]
|
backlight_brightness = [100 for _ in range(num_gauges)]
|
||||||
backlight_on = [False for _ in range(num_gauges)]
|
backlight_on = [False for _ in range(num_gauges)]
|
||||||
@@ -367,126 +312,8 @@ status_led_green = [False for _ in range(num_gauges)]
|
|||||||
_bl_dirty_since = None
|
_bl_dirty_since = None
|
||||||
_BL_SAVE_DELAY_MS = 5000
|
_BL_SAVE_DELAY_MS = 5000
|
||||||
|
|
||||||
_disco_saved_brightness = [100] * num_gauges
|
|
||||||
_disco_saved_color = [[0, 0, 0] for _ in range(num_gauges)]
|
_disco_saved_color = [[0, 0, 0] for _ in range(num_gauges)]
|
||||||
|
|
||||||
print("DEBUG: about to define functions")
|
|
||||||
|
|
||||||
|
|
||||||
def _flush_backlight(client):
|
|
||||||
for i in range(num_gauges):
|
|
||||||
gt = gauge_topics[i]
|
|
||||||
payload = {
|
|
||||||
"state": "ON" if backlight_on[i] else "OFF",
|
|
||||||
"color": {
|
|
||||||
"r": backlight_color[i][0],
|
|
||||||
"g": backlight_color[i][1],
|
|
||||||
"b": backlight_color[i][2],
|
|
||||||
},
|
|
||||||
"brightness": int(backlight_brightness[i] * 2.55),
|
|
||||||
}
|
|
||||||
client.publish(gt["led_bl_state"], ujson.dumps(payload), retain=True)
|
|
||||||
info(
|
|
||||||
f"Gauge {i} backlight: {payload['state']} {backlight_color[i]} @ {backlight_brightness[i]}%"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _backlight_changed(gauge_idx, new_color, new_on, new_brightness):
|
|
||||||
return (
|
|
||||||
new_color != backlight_color[gauge_idx]
|
|
||||||
or new_on != backlight_on[gauge_idx]
|
|
||||||
or (new_on and new_brightness != backlight_brightness[gauge_idx])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _mark_bl_dirty():
|
|
||||||
global _bl_dirty_since
|
|
||||||
_bl_dirty_since = utime.ticks_ms()
|
|
||||||
|
|
||||||
|
|
||||||
def set_backlight_color(gauge_idx, r, g, b, brightness=None):
|
|
||||||
global backlight_color, backlight_brightness, backlight_on
|
|
||||||
if brightness is None:
|
|
||||||
brightness = backlight_brightness[gauge_idx]
|
|
||||||
new_on = brightness > 0
|
|
||||||
if not _backlight_changed(gauge_idx, (r, g, b), new_on, brightness):
|
|
||||||
return
|
|
||||||
backlight_color[gauge_idx] = (r, g, b)
|
|
||||||
if brightness > 0:
|
|
||||||
backlight_brightness[gauge_idx] = brightness
|
|
||||||
backlight_on[gauge_idx] = new_on
|
|
||||||
|
|
||||||
scale = brightness / 100
|
|
||||||
leds_per_gauge = BACKLIGHT_LEDS_PER_GAUGE + STATUS_LEDS_PER_GAUGE
|
|
||||||
base_idx = gauge_idx * leds_per_gauge
|
|
||||||
for j in range(BACKLIGHT_LEDS_PER_GAUGE):
|
|
||||||
leds_bl[base_idx + j] = (int(g * scale), int(r * scale), int(b * scale))
|
|
||||||
_update_status_leds(gauge_idx)
|
|
||||||
leds_bl.write()
|
|
||||||
_mark_bl_dirty()
|
|
||||||
|
|
||||||
|
|
||||||
def set_backlight_brightness(gauge_idx, brightness):
|
|
||||||
global backlight_brightness, backlight_on
|
|
||||||
clamped = max(0, min(100, brightness))
|
|
||||||
new_on = clamped > 0
|
|
||||||
if not _backlight_changed(gauge_idx, backlight_color[gauge_idx], new_on, clamped):
|
|
||||||
return
|
|
||||||
if clamped > 0:
|
|
||||||
backlight_brightness[gauge_idx] = clamped
|
|
||||||
backlight_on[gauge_idx] = new_on
|
|
||||||
r, g, b = backlight_color[gauge_idx]
|
|
||||||
scale = clamped / 100
|
|
||||||
leds_per_gauge = BACKLIGHT_LEDS_PER_GAUGE + STATUS_LEDS_PER_GAUGE
|
|
||||||
base_idx = gauge_idx * leds_per_gauge
|
|
||||||
for j in range(BACKLIGHT_LEDS_PER_GAUGE):
|
|
||||||
leds_bl[base_idx + j] = (int(g * scale), int(r * scale), int(b * scale))
|
|
||||||
_update_status_leds(gauge_idx)
|
|
||||||
leds_bl.write()
|
|
||||||
_mark_bl_dirty()
|
|
||||||
|
|
||||||
|
|
||||||
def _update_status_leds(gauge_idx):
|
|
||||||
leds_per_gauge = BACKLIGHT_LEDS_PER_GAUGE + STATUS_LEDS_PER_GAUGE
|
|
||||||
base_idx = gauge_idx * leds_per_gauge + BACKLIGHT_LEDS_PER_GAUGE
|
|
||||||
|
|
||||||
g_cfg = gauges[gauge_idx]
|
|
||||||
red_color = g_cfg["ws2812_red"]
|
|
||||||
green_color = g_cfg["ws2812_green"]
|
|
||||||
|
|
||||||
if status_led_red[gauge_idx]:
|
|
||||||
leds_bl[base_idx] = (red_color[1], red_color[0], red_color[2])
|
|
||||||
else:
|
|
||||||
leds_bl[base_idx] = (0, 0, 0)
|
|
||||||
|
|
||||||
if status_led_green[gauge_idx]:
|
|
||||||
leds_bl[base_idx + 1] = (green_color[1], green_color[0], green_color[2])
|
|
||||||
else:
|
|
||||||
leds_bl[base_idx + 1] = (0, 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
def set_status_led(gauge_idx, led_type, state):
|
|
||||||
global status_led_red, status_led_green
|
|
||||||
if led_type == "red":
|
|
||||||
status_led_red[gauge_idx] = state
|
|
||||||
elif led_type == "green":
|
|
||||||
status_led_green[gauge_idx] = state
|
|
||||||
_update_status_leds(gauge_idx)
|
|
||||||
leds_bl.write()
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# State
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
_last_rezero_ms = None # set to ticks_ms() in main()
|
|
||||||
client_ref = None
|
|
||||||
_mqtt_connected = False
|
|
||||||
_last_mqtt_check = 0
|
|
||||||
|
|
||||||
_disco_end_time = 0
|
|
||||||
|
|
||||||
print("DEBUG: about to define _publish")
|
|
||||||
|
|
||||||
|
|
||||||
def _publish(topic, payload, retain=False):
|
def _publish(topic, payload, retain=False):
|
||||||
@@ -507,7 +334,6 @@ def _publish(topic, payload, retain=False):
|
|||||||
|
|
||||||
|
|
||||||
def on_message(topic, payload):
|
def on_message(topic, payload):
|
||||||
global _disco_end_time, _disco_saved_brightness, _disco_saved_color
|
|
||||||
global backlight_brightness, backlight_color
|
global backlight_brightness, backlight_color
|
||||||
if client_ref is None:
|
if client_ref is None:
|
||||||
return
|
return
|
||||||
@@ -540,13 +366,16 @@ def on_message(topic, payload):
|
|||||||
info("All gauges zeroed")
|
info("All gauges zeroed")
|
||||||
return
|
return
|
||||||
|
|
||||||
if topic == T_DISCO:
|
if topic == T_RESET_DISCOVERY:
|
||||||
_disco_end_time = utime.ticks_ms() + 5000
|
info("Reset discovery triggered")
|
||||||
for i in range(num_gauges):
|
try:
|
||||||
_disco_saved_brightness[i] = backlight_brightness[i]
|
import uos
|
||||||
_disco_saved_color[i] = backlight_color[i]
|
uos.remove(".discovery_ok")
|
||||||
info("Disco mode started")
|
info("Discovery flag file removed")
|
||||||
return
|
except:
|
||||||
|
pass
|
||||||
|
import machine
|
||||||
|
machine.reset()
|
||||||
|
|
||||||
for i, gt in enumerate(gauge_topics):
|
for i, gt in enumerate(gauge_topics):
|
||||||
if topic == gt["led_red"]:
|
if topic == gt["led_red"]:
|
||||||
@@ -627,32 +456,28 @@ def connect_mqtt():
|
|||||||
port=MQTT_PORT,
|
port=MQTT_PORT,
|
||||||
user=MQTT_USER,
|
user=MQTT_USER,
|
||||||
password=MQTT_PASSWORD,
|
password=MQTT_PASSWORD,
|
||||||
keepalive=60,
|
keepalive=30,
|
||||||
)
|
)
|
||||||
client.set_last_will(T_STATUS, b"offline", retain=True, qos=0)
|
# Don't set last will - it might be causing issues
|
||||||
|
# client.set_last_will(T_STATUS, b"offline", retain=True, qos=0)
|
||||||
client.set_callback(on_message)
|
client.set_callback(on_message)
|
||||||
client.connect()
|
client.connect()
|
||||||
client_ref = client
|
client_ref = client
|
||||||
|
|
||||||
|
# Explicit subscriptions
|
||||||
client.subscribe(T_SET)
|
client.subscribe(T_SET)
|
||||||
client.subscribe(T_ZERO)
|
client.subscribe(T_ZERO)
|
||||||
client.subscribe(T_DISCO)
|
client.subscribe(T_RESET_DISCOVERY) # Reset discovery flag
|
||||||
for gt in gauge_topics:
|
for gt in gauge_topics:
|
||||||
client.subscribe(gt["set"])
|
client.subscribe(gt["set"])
|
||||||
client.subscribe(gt["zero"])
|
|
||||||
client.subscribe(gt["led_red"])
|
|
||||||
client.subscribe(gt["led_green"])
|
|
||||||
client.subscribe(gt["led_bl"])
|
|
||||||
client.subscribe(gt["status_red"])
|
|
||||||
client.subscribe(gt["status_green"])
|
|
||||||
_mqtt_connected = True
|
_mqtt_connected = True
|
||||||
info(f"MQTT connected client_id={MQTT_CLIENT_ID}")
|
info(f"MQTT connected client_id={MQTT_CLIENT_ID}")
|
||||||
return client
|
|
||||||
|
|
||||||
|
|
||||||
_mqtt_check_interval_ms = 30000
|
_mqtt_check_interval_ms = 30000
|
||||||
_last_mqtt_check = 0
|
_last_mqtt_check = 0
|
||||||
|
|
||||||
print("DEBUG: about to define check_mqtt")
|
|
||||||
|
|
||||||
|
|
||||||
def check_mqtt():
|
def check_mqtt():
|
||||||
@@ -690,7 +515,7 @@ def check_mqtt():
|
|||||||
client_ref.connect()
|
client_ref.connect()
|
||||||
client_ref.subscribe(T_SET)
|
client_ref.subscribe(T_SET)
|
||||||
client_ref.subscribe(T_ZERO)
|
client_ref.subscribe(T_ZERO)
|
||||||
client_ref.subscribe(T_DISCO)
|
client_ref.subscribe(T_RESET_DISCOVERY)
|
||||||
for gt in gauge_topics:
|
for gt in gauge_topics:
|
||||||
client_ref.subscribe(gt["set"])
|
client_ref.subscribe(gt["set"])
|
||||||
client_ref.subscribe(gt["zero"])
|
client_ref.subscribe(gt["zero"])
|
||||||
@@ -711,7 +536,6 @@ def check_mqtt():
|
|||||||
log_err("MQTT reconnection failed after 3 attempts")
|
log_err("MQTT reconnection failed after 3 attempts")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print("DEBUG: about to define publish_discovery")
|
|
||||||
|
|
||||||
|
|
||||||
def publish_discovery(client):
|
def publish_discovery(client):
|
||||||
@@ -747,7 +571,11 @@ def publish_discovery(client):
|
|||||||
retain=True,
|
retain=True,
|
||||||
)
|
)
|
||||||
info(f"Discovery: gauge {i} ({g['name']})")
|
info(f"Discovery: gauge {i} ({g['name']})")
|
||||||
|
|
||||||
|
# Process MQTT messages between publishes
|
||||||
|
client.check_msg()
|
||||||
|
utime.sleep_ms(30)
|
||||||
|
|
||||||
client.publish(
|
client.publish(
|
||||||
gt["led_red_disc"],
|
gt["led_red_disc"],
|
||||||
ujson.dumps(
|
ujson.dumps(
|
||||||
@@ -766,7 +594,31 @@ def publish_discovery(client):
|
|||||||
retain=True,
|
retain=True,
|
||||||
)
|
)
|
||||||
info(f"Discovery: gauge {i} red LED")
|
info(f"Discovery: gauge {i} red LED")
|
||||||
|
|
||||||
|
client.publish(
|
||||||
|
gt["led_green_disc"],
|
||||||
|
ujson.dumps(
|
||||||
|
{
|
||||||
|
"name": f"{g['name']} Green LED",
|
||||||
|
"uniq_id": f"{MQTT_CLIENT_ID}_g{i}_green",
|
||||||
|
"cmd_t": gt["led_green"],
|
||||||
|
"stat_t": gt["led_green_state"],
|
||||||
|
"pl_on": "ON",
|
||||||
|
"pl_off": "OFF",
|
||||||
|
"icon": "mdi:led-on",
|
||||||
|
"dev": _dev_ref,
|
||||||
|
"ret": True,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
retain=True,
|
||||||
|
)
|
||||||
|
info(f"Discovery: gauge {i} green LED")
|
||||||
|
|
||||||
|
# Process MQTT messages
|
||||||
|
for _ in range(5):
|
||||||
|
client.check_msg()
|
||||||
|
utime.sleep_ms(10)
|
||||||
|
|
||||||
client.publish(
|
client.publish(
|
||||||
gt["led_green_disc"],
|
gt["led_green_disc"],
|
||||||
ujson.dumps(
|
ujson.dumps(
|
||||||
@@ -859,61 +711,74 @@ def publish_state(client):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print("DEBUG: main() entered")
|
|
||||||
info("=" * 48)
|
info("=" * 48)
|
||||||
info("Gauge MQTT controller starting")
|
info("Gauge MQTT controller starting")
|
||||||
info("=" * 48)
|
info("=" * 48)
|
||||||
|
|
||||||
print("DEBUG: about to connect wifi")
|
|
||||||
connect_wifi(WIFI_SSID, WIFI_PASSWORD)
|
connect_wifi(WIFI_SSID, WIFI_PASSWORD)
|
||||||
print("DEBUG: wifi connected")
|
|
||||||
|
|
||||||
|
# Check if we need to publish discovery
|
||||||
|
try:
|
||||||
|
with open(".discovery_ok", "r") as f:
|
||||||
|
discovery_published = f.read()
|
||||||
|
info("Discovery flag file exists, skipping discovery")
|
||||||
|
discovery_published = True
|
||||||
|
except:
|
||||||
|
info("No discovery flag file - publishing discovery")
|
||||||
|
discovery_published = False
|
||||||
|
|
||||||
|
# Connect MQTT first (needed for discovery)
|
||||||
|
connect_mqtt()
|
||||||
|
|
||||||
|
# Give MQTT time to process subscriptions
|
||||||
|
info("Processing initial MQTT messages...")
|
||||||
|
for i in range(50):
|
||||||
|
client_ref.check_msg()
|
||||||
|
utime.sleep_ms(20)
|
||||||
|
info("Done with initial processing")
|
||||||
|
|
||||||
|
# Publish discovery if needed (before gauge initialization)
|
||||||
|
if not discovery_published:
|
||||||
|
info("Publishing discovery...")
|
||||||
|
publish_discovery(client_ref)
|
||||||
|
|
||||||
|
# Write flag file
|
||||||
|
try:
|
||||||
|
with open(".discovery_ok", "w") as f:
|
||||||
|
f.write("ok")
|
||||||
|
info("Discovery flag file created")
|
||||||
|
except Exception as e:
|
||||||
|
warn(f"Could not write discovery flag: {e}")
|
||||||
|
|
||||||
|
info("Discovery published, resetting...")
|
||||||
|
import machine
|
||||||
|
machine.reset()
|
||||||
|
|
||||||
|
# Now initialize gauges
|
||||||
info("Zeroing gauges on startup ...")
|
info("Zeroing gauges on startup ...")
|
||||||
for i, g in enumerate(gauge_objects):
|
for i, g in enumerate(gauge_objects):
|
||||||
g.zero()
|
g.zero()
|
||||||
info(f"Zeroed gauge {i}")
|
info(f"Zeroed gauge {i}")
|
||||||
info("Zero complete")
|
info("Zero complete")
|
||||||
|
|
||||||
connect_mqtt()
|
info("Publishing state...")
|
||||||
publish_discovery(client_ref)
|
|
||||||
publish_state(client_ref)
|
publish_state(client_ref)
|
||||||
|
utime.sleep_ms(50)
|
||||||
|
for _ in range(5):
|
||||||
|
client_ref.check_msg()
|
||||||
|
utime.sleep_ms(20)
|
||||||
|
|
||||||
info("Entering main loop")
|
info("Entering main loop")
|
||||||
info("-" * 48)
|
info("-" * 48)
|
||||||
|
|
||||||
try:
|
# Initialize variables for main loop
|
||||||
import ota
|
|
||||||
|
|
||||||
ota.mark_ok()
|
|
||||||
info("OTA OK flag set")
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
global _bl_dirty_since
|
|
||||||
global _disco_end_time, _disco_saved_brightness, _disco_saved_color
|
|
||||||
last_heartbeat = utime.ticks_ms()
|
last_heartbeat = utime.ticks_ms()
|
||||||
|
now = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
now = utime.ticks_ms()
|
now = utime.ticks_ms()
|
||||||
|
|
||||||
if _disco_end_time > 0 and utime.ticks_diff(_disco_end_time, now) <= 0:
|
|
||||||
_disco_end_time = 0
|
|
||||||
for i in range(num_gauges):
|
|
||||||
set_backlight_color(i, *_disco_saved_color[i], _disco_saved_brightness[i])
|
|
||||||
info("Disco mode ended")
|
|
||||||
elif _disco_end_time > 0:
|
|
||||||
for led_idx in range(total_backlight_leds):
|
|
||||||
r = urandom.getrandbits(8)
|
|
||||||
g = urandom.getrandbits(8)
|
|
||||||
b = urandom.getrandbits(8)
|
|
||||||
r = max(r, 128)
|
|
||||||
g = max(g, 128)
|
|
||||||
b = max(b, 128)
|
|
||||||
leds_bl[led_idx] = (g, r, b)
|
|
||||||
leds_bl.write()
|
|
||||||
utime.sleep_ms(200)
|
|
||||||
|
|
||||||
check_wifi()
|
check_wifi()
|
||||||
|
|
||||||
if not check_mqtt():
|
if not check_mqtt():
|
||||||
@@ -936,33 +801,20 @@ def main():
|
|||||||
if moved_any:
|
if moved_any:
|
||||||
delay_us = 1_000_000 // MICROSTEPS_PER_SECOND
|
delay_us = 1_000_000 // MICROSTEPS_PER_SECOND
|
||||||
utime.sleep_us(delay_us)
|
utime.sleep_us(delay_us)
|
||||||
|
else:
|
||||||
|
utime.sleep_ms(10)
|
||||||
|
|
||||||
if (
|
if utime.ticks_diff(utime.ticks_ms(), last_heartbeat) > 10000:
|
||||||
REZERO_INTERVAL_MS > 0
|
info(f"Heartbeat: {gauge_targets}")
|
||||||
and utime.ticks_diff(now, gauge_last_rezero[0]) >= REZERO_INTERVAL_MS
|
last_heartbeat = utime.ticks_ms()
|
||||||
):
|
|
||||||
for i, g in enumerate(gauge_objects):
|
|
||||||
info(f"Auto-rezero gauge {i}")
|
|
||||||
saved = gauge_targets[i]
|
|
||||||
g.zero()
|
|
||||||
if saved > gauges[i]["min"]:
|
|
||||||
g.set(saved)
|
|
||||||
gauge_last_rezero[i] = now
|
|
||||||
publish_state(client_ref)
|
|
||||||
info("Auto-rezero complete")
|
|
||||||
|
|
||||||
if (
|
|
||||||
_bl_dirty_since is not None
|
|
||||||
and utime.ticks_diff(now, _bl_dirty_since) >= _BL_SAVE_DELAY_MS
|
|
||||||
):
|
|
||||||
_flush_backlight(client_ref)
|
|
||||||
_bl_dirty_since = None
|
|
||||||
|
|
||||||
if utime.ticks_diff(now, last_heartbeat) >= HEARTBEAT_MS:
|
if utime.ticks_diff(now, last_heartbeat) >= HEARTBEAT_MS:
|
||||||
publish_state(client_ref)
|
publish_state(client_ref)
|
||||||
last_heartbeat = now
|
last_heartbeat = now
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
import sys
|
||||||
|
sys.print_exception(e)
|
||||||
log_err(f"Main loop error: {e} — continuing")
|
log_err(f"Main loop error: {e} — continuing")
|
||||||
utime.sleep_ms(100)
|
utime.sleep_ms(100)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user