Compare commits
15 Commits
109f97caa0
...
debug2
| Author | SHA1 | Date | |
|---|---|---|---|
| 84449e5235 | |||
| ad50fd2ee5 | |||
| ae6d72b292 | |||
| 2ea19b14f8 | |||
| 1f8ba45685 | |||
| 5a98a3c63b | |||
| afe70da24d | |||
| 0d7ae5cedc | |||
| b3e2ef0f81 | |||
| 6068628d13 | |||
| 64b0aa482f | |||
| 2e5e410897 | |||
| 4045da8964 | |||
| 81099d9887 | |||
| 355faadc31 |
@@ -258,7 +258,7 @@ struct Gauge {
|
|||||||
long homingBackoffSteps = 3800; // Deliberately a touch past full reverse travel.
|
long homingBackoffSteps = 3800; // Deliberately a touch past full reverse travel.
|
||||||
|
|
||||||
float velocity = 0.0f;
|
float velocity = 0.0f;
|
||||||
float maxSpeed = 5000.0f;
|
float maxSpeed = 4000.0f;
|
||||||
float accel = 6000.0f;
|
float accel = 6000.0f;
|
||||||
float homingSpeed = 500.0f;
|
float homingSpeed = 500.0f;
|
||||||
|
|
||||||
|
|||||||
174
gauge.py
174
gauge.py
@@ -28,6 +28,16 @@ import gc
|
|||||||
from umqtt.robust import MQTTClient
|
from umqtt.robust import MQTTClient
|
||||||
from machine import UART
|
from machine import UART
|
||||||
|
|
||||||
|
# Activate WiFi driver before any heavy heap allocation so it can claim its
|
||||||
|
# contiguous DRAM block before the Python heap fragments the address space.
|
||||||
|
# Only activate if not already running (e.g. boot.py may have started it).
|
||||||
|
gc.collect()
|
||||||
|
_early_wlan = network.WLAN(network.STA_IF)
|
||||||
|
if not _early_wlan.active():
|
||||||
|
_early_wlan.active(True)
|
||||||
|
del _early_wlan
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Logging
|
# Logging
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -524,32 +534,56 @@ _DEVICE = {
|
|||||||
_wifi_check_interval_ms = 30000
|
_wifi_check_interval_ms = 30000
|
||||||
_last_wifi_check = 0
|
_last_wifi_check = 0
|
||||||
_wifi_sta = None
|
_wifi_sta = None
|
||||||
|
_WIFI_CONNECT_ATTEMPTS = 3
|
||||||
|
|
||||||
|
|
||||||
def connect_wifi(ssid, password, timeout_s=15):
|
def _reset_wifi_interface():
|
||||||
global _wifi_sta
|
global _wifi_sta
|
||||||
_wifi_sta = network.WLAN(network.STA_IF)
|
_wifi_sta = network.WLAN(network.STA_IF)
|
||||||
|
if _wifi_sta.active():
|
||||||
|
_wifi_sta.active(False)
|
||||||
|
utime.sleep_ms(200)
|
||||||
_wifi_sta.active(True)
|
_wifi_sta.active(True)
|
||||||
if _wifi_sta.isconnected():
|
utime.sleep_ms(500)
|
||||||
|
|
||||||
|
|
||||||
|
def connect_wifi(ssid, password, timeout_s=15, force_reconnect=False):
|
||||||
|
global _wifi_sta
|
||||||
|
_wifi_sta = network.WLAN(network.STA_IF)
|
||||||
|
|
||||||
|
if _wifi_sta.isconnected() and not force_reconnect:
|
||||||
ip, mask, gw, dns = _wifi_sta.ifconfig()
|
ip, mask, gw, dns = _wifi_sta.ifconfig()
|
||||||
info("WiFi already connected")
|
info("WiFi already connected")
|
||||||
info(f" IP:{ip} mask:{mask} gw:{gw} dns:{dns}")
|
info(f" IP:{ip} mask:{mask} gw:{gw} dns:{dns}")
|
||||||
|
utime.sleep_ms(250)
|
||||||
return ip
|
return ip
|
||||||
info(f"WiFi connecting to '{ssid}' ...")
|
|
||||||
_wifi_sta.connect(ssid, password)
|
last_error = None
|
||||||
deadline = utime.time() + timeout_s
|
for attempt in range(_WIFI_CONNECT_ATTEMPTS):
|
||||||
while not _wifi_sta.isconnected():
|
info(f"WiFi connecting to '{ssid}' (attempt {attempt + 1}/{_WIFI_CONNECT_ATTEMPTS}) ...")
|
||||||
if utime.time() > deadline:
|
_reset_wifi_interface()
|
||||||
log_err(f"WiFi connect timeout after {timeout_s}s")
|
try:
|
||||||
raise OSError("WiFi connect timeout")
|
_wifi_sta.connect(ssid, password)
|
||||||
utime.sleep_ms(200)
|
deadline = utime.time() + timeout_s
|
||||||
ip, mask, gw, dns = _wifi_sta.ifconfig()
|
while not _wifi_sta.isconnected():
|
||||||
mac = ":".join(f"{b:02x}" for b in _wifi_sta.config("mac"))
|
if utime.time() > deadline:
|
||||||
info("WiFi connected!")
|
raise OSError("WiFi connect timeout")
|
||||||
info(f" SSID : {ssid}")
|
utime.sleep_ms(250)
|
||||||
info(f" MAC : {mac}")
|
|
||||||
info(f" IP : {ip} mask:{mask} gw:{gw} dns:{dns}")
|
ip, mask, gw, dns = _wifi_sta.ifconfig()
|
||||||
return ip
|
mac = ":".join(f"{b:02x}" for b in _wifi_sta.config("mac"))
|
||||||
|
info("WiFi connected!")
|
||||||
|
info(f" SSID : {ssid}")
|
||||||
|
info(f" MAC : {mac}")
|
||||||
|
info(f" IP : {ip} mask:{mask} gw:{gw} dns:{dns}")
|
||||||
|
utime.sleep_ms(500)
|
||||||
|
return ip
|
||||||
|
except Exception as e:
|
||||||
|
last_error = e
|
||||||
|
log_err(f"WiFi connect attempt {attempt + 1} failed: {e}")
|
||||||
|
utime.sleep_ms(1000)
|
||||||
|
|
||||||
|
raise last_error
|
||||||
|
|
||||||
|
|
||||||
def check_wifi():
|
def check_wifi():
|
||||||
@@ -567,15 +601,7 @@ def check_wifi():
|
|||||||
|
|
||||||
log_err("WiFi lost connection — attempting reconnect...")
|
log_err("WiFi lost connection — attempting reconnect...")
|
||||||
try:
|
try:
|
||||||
_wifi_sta.active(True)
|
ip = connect_wifi(WIFI_SSID, WIFI_PASSWORD, timeout_s=15, force_reconnect=True)
|
||||||
_wifi_sta.connect(WIFI_SSID, WIFI_PASSWORD)
|
|
||||||
deadline = utime.time() + 15
|
|
||||||
while not _wifi_sta.isconnected():
|
|
||||||
if utime.time() > deadline:
|
|
||||||
log_err("WiFi reconnect timeout")
|
|
||||||
return
|
|
||||||
utime.sleep_ms(200)
|
|
||||||
ip, mask, gw, dns = _wifi_sta.ifconfig()
|
|
||||||
info(f"WiFi reconnected! IP:{ip}")
|
info(f"WiFi reconnected! IP:{ip}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log_err(f"WiFi reconnect failed: {e}")
|
log_err(f"WiFi reconnect failed: {e}")
|
||||||
@@ -858,19 +884,42 @@ def _subscribe_all(c):
|
|||||||
def connect_mqtt():
|
def connect_mqtt():
|
||||||
global client_ref, _mqtt_connected
|
global client_ref, _mqtt_connected
|
||||||
info(f"Connecting to MQTT broker {MQTT_BROKER}:{MQTT_PORT} ...")
|
info(f"Connecting to MQTT broker {MQTT_BROKER}:{MQTT_PORT} ...")
|
||||||
client = MQTTClient(
|
last_error = None
|
||||||
client_id=MQTT_CLIENT_ID,
|
for attempt in range(3):
|
||||||
server=MQTT_BROKER,
|
gc.collect()
|
||||||
port=MQTT_PORT,
|
try:
|
||||||
user=MQTT_USER,
|
if client_ref is not None:
|
||||||
password=MQTT_PASSWORD,
|
try:
|
||||||
keepalive=30,
|
client_ref.disconnect()
|
||||||
)
|
except Exception:
|
||||||
client.set_callback(on_message)
|
pass
|
||||||
client.connect()
|
|
||||||
client_ref = client
|
client = MQTTClient(
|
||||||
_mqtt_connected = True
|
client_id=MQTT_CLIENT_ID,
|
||||||
info(f"MQTT connected client_id={MQTT_CLIENT_ID}")
|
server=MQTT_BROKER,
|
||||||
|
port=MQTT_PORT,
|
||||||
|
user=MQTT_USER,
|
||||||
|
password=MQTT_PASSWORD,
|
||||||
|
keepalive=30,
|
||||||
|
)
|
||||||
|
client.set_callback(on_message)
|
||||||
|
client.connect()
|
||||||
|
client_ref = client
|
||||||
|
_mqtt_connected = True
|
||||||
|
info(f"MQTT connected client_id={MQTT_CLIENT_ID}")
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
last_error = e
|
||||||
|
log_err(f"MQTT connect attempt {attempt + 1} failed: {type(e).__name__}: {e}")
|
||||||
|
try:
|
||||||
|
client.sock.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
gc.collect()
|
||||||
|
utime.sleep_ms(1000)
|
||||||
|
|
||||||
|
_mqtt_connected = False
|
||||||
|
raise last_error
|
||||||
|
|
||||||
|
|
||||||
_mqtt_check_interval_ms = 30000
|
_mqtt_check_interval_ms = 30000
|
||||||
@@ -878,7 +927,7 @@ _last_mqtt_check = 0
|
|||||||
_discovery_queue = []
|
_discovery_queue = []
|
||||||
_discovery_idx = 0
|
_discovery_idx = 0
|
||||||
_last_discovery_ms = 0
|
_last_discovery_ms = 0
|
||||||
_DISCOVERY_INTERVAL_MS = 200
|
_DISCOVERY_INTERVAL_MS = 350
|
||||||
|
|
||||||
|
|
||||||
def check_mqtt():
|
def check_mqtt():
|
||||||
@@ -922,6 +971,11 @@ def check_mqtt():
|
|||||||
return True
|
return True
|
||||||
except Exception as e2:
|
except Exception as e2:
|
||||||
log_err(f"MQTT reconnect attempt {attempt + 1} failed: {e2}")
|
log_err(f"MQTT reconnect attempt {attempt + 1} failed: {e2}")
|
||||||
|
try:
|
||||||
|
client_ref.sock.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
gc.collect()
|
||||||
utime.sleep_ms(2000)
|
utime.sleep_ms(2000)
|
||||||
|
|
||||||
log_err("MQTT reconnection failed after 3 attempts")
|
log_err("MQTT reconnection failed after 3 attempts")
|
||||||
@@ -929,6 +983,7 @@ def check_mqtt():
|
|||||||
|
|
||||||
|
|
||||||
def _publish_discovery_entity(client, topic, payload, log_msg):
|
def _publish_discovery_entity(client, topic, payload, log_msg):
|
||||||
|
gc.collect()
|
||||||
client.publish(topic, ujson.dumps(payload), retain=True)
|
client.publish(topic, ujson.dumps(payload), retain=True)
|
||||||
info(log_msg)
|
info(log_msg)
|
||||||
|
|
||||||
@@ -1124,10 +1179,7 @@ def _append_vfd_discovery(entries, dev_ref):
|
|||||||
"cmd_t": vfd_topics["set"],
|
"cmd_t": vfd_topics["set"],
|
||||||
"stat_t": vfd_topics["state"],
|
"stat_t": vfd_topics["state"],
|
||||||
"avty_t": gauge_topics[0]["status"],
|
"avty_t": gauge_topics[0]["status"],
|
||||||
"max": 4,
|
|
||||||
"mode": "text",
|
|
||||||
"icon": "mdi:alpha-box",
|
"icon": "mdi:alpha-box",
|
||||||
"pattern": "^[0-9A-Fa-f-]{0,4}$",
|
|
||||||
"dev": dev_ref,
|
"dev": dev_ref,
|
||||||
},
|
},
|
||||||
"Discovery: VFD text",
|
"Discovery: VFD text",
|
||||||
@@ -1205,15 +1257,18 @@ def service_discovery():
|
|||||||
if _last_discovery_ms and utime.ticks_diff(now, _last_discovery_ms) < _DISCOVERY_INTERVAL_MS:
|
if _last_discovery_ms and utime.ticks_diff(now, _last_discovery_ms) < _DISCOVERY_INTERVAL_MS:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
gc.collect()
|
||||||
topic, payload, log_msg = _discovery_queue[_discovery_idx]
|
topic, payload, log_msg = _discovery_queue[_discovery_idx]
|
||||||
if isinstance(payload, bytes):
|
try:
|
||||||
client_ref.publish(topic, payload, retain=True)
|
if isinstance(payload, bytes):
|
||||||
else:
|
client_ref.publish(topic, payload, retain=True)
|
||||||
_publish_discovery_entity(client_ref, topic, payload, log_msg)
|
else:
|
||||||
|
_publish_discovery_entity(client_ref, topic, payload, log_msg)
|
||||||
|
except Exception as e:
|
||||||
|
log_err(f"Discovery publish failed for {topic}: {e}")
|
||||||
_discovery_idx += 1
|
_discovery_idx += 1
|
||||||
_last_discovery_ms = utime.ticks_ms()
|
_last_discovery_ms = utime.ticks_ms()
|
||||||
if (_discovery_idx & 3) == 0:
|
gc.collect()
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
|
|
||||||
def publish_online(client):
|
def publish_online(client):
|
||||||
@@ -1243,13 +1298,30 @@ def apply_motion_defaults():
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
gc.collect()
|
||||||
info("=" * 48)
|
info("=" * 48)
|
||||||
info("Gauge MQTT controller starting")
|
info("Gauge MQTT controller starting")
|
||||||
|
info(f"Heap free: {gc.mem_free()} bytes")
|
||||||
info("=" * 48)
|
info("=" * 48)
|
||||||
|
|
||||||
connect_wifi(WIFI_SSID, WIFI_PASSWORD)
|
gc.collect()
|
||||||
|
connect_wifi(WIFI_SSID, WIFI_PASSWORD, force_reconnect=True)
|
||||||
|
|
||||||
connect_mqtt()
|
mqtt_attempts = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
connect_mqtt()
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
mqtt_attempts += 1
|
||||||
|
log_err(f"MQTT connect failed: {e} (attempt {mqtt_attempts})")
|
||||||
|
if mqtt_attempts % 3 == 0:
|
||||||
|
log_err("WiFi may be stale — forcing reconnect...")
|
||||||
|
try:
|
||||||
|
connect_wifi(WIFI_SSID, WIFI_PASSWORD, force_reconnect=True)
|
||||||
|
except Exception as we:
|
||||||
|
log_err(f"WiFi reconnect failed: {we}")
|
||||||
|
utime.sleep_ms(5000)
|
||||||
_subscribe_all(client_ref)
|
_subscribe_all(client_ref)
|
||||||
schedule_discovery()
|
schedule_discovery()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user