fix(mqtt_weather): don't render 0°C as -0.0

Rounding a reading just below freezing (31.95°F) gives -0.0, which printed as "-0.0°C".
This commit is contained in:
agessaman committed 2026-11-04 16:46:27 -08:00
1 parent 4b871089b9
commit 3ecdf1fb8d
3 files changed
+12 -3

No files matched your search

+2 -2
View File
@@ -51,9 +51,9 @@ semantic versioning.
### Fixed
- MQTT weather sources (`wx custom.mqtt_weather.*`) in `json_template` mode no longer put a long Celsius value on air: the default template rendered `61.3°F (16.27777777777778°C)`. I now round `{temperature_c}` to one decimal, matching the precision of the °F reading, so it reads `16.3°C`. Format specs such as `{temperature_c:.0f}` still work, and a missing reading still renders as empty rather than failing the template.
- MQTT weather sources (`wx custom.mqtt_weather.*`) in `json_template` mode no longer put a long Celsius value on air: the default template rendered `61.3°F (16.27777777777778°C)`. I now round `{temperature_c}` to one decimal, matching the precision of the °F reading, so it reads `16.3°C` (and 31.95°F reads `0.0°C`, not `-0.0°C`). Format specs such as `{temperature_c:.0f}` still work, and a missing reading still renders as empty rather than failing the template.
- The Nix flake builds again on current nixpkgs. The locked meshcore-cli (1.3.11) caps `bleak` below 2.0 and nixpkgs now ships 3.0.2, so its runtime dependency check failed; the flake relaxes that one pin ([#352](https://github.com/agessaman/meshcore-bot/issues/352)).
- The weather service's Blitzortung lightning feed backs off when the broker keeps dropping it: 5 seconds after a drop, doubling to 5 minutes, and back to 5 seconds after a connection that lasts a minute. It used to reconnect every second, logging two lines each time ([#362](https://github.com/agessaman/meshcore-bot/issues/362)). It only logs "Connected" once the broker accepts the session, says why it is reconnecting, and gives each connection its own client ID. Strikes inside `blitz_area_*` also reach the lightning handler now. They arrive on the MQTT library's own thread, where scheduling the handler failed and was logged only at debug level, so they were dropped.
- The weather service's Blitzortung lightning feed backs off when the broker keeps dropping it: 5 seconds after a drop, doubling to 5 minutes, and back to 5 seconds after a connection that lasts a minute. It used to reconnect every second, logging two lines each time ([#362](https://github.com/agessaman/meshcore-bot/issues/362)). It only logs "Connected" once the broker accepts the session, says why it is reconnecting, and gives each connection its own client ID. Strikes inside `blitz_area_*` also reach the lightning handler now. They arrive on the MQTT library's own thread, where scheduling the handler failed and was logged only at debug level, so they were dropped. Strikes that arrive while an alert is being sent are kept for the next count instead of being cleared with the batch.
- The web viewer's Email & Notifications panel has an "Allow a local or private-network SMTP server" checkbox. `allow_local_smtp` is stored in the bot database, not `config.ini`, and no control set it, so a local relay such as Postfix could not be used for the nightly email or radio alerts ([#361](https://github.com/agessaman/meshcore-bot/issues/361)).
- A repeater heard twice in a row no longer posts two "new repeater" messages to Discord and Telegram. The prefix-collision service decided to announce a key and only recorded that key after the posts returned, so a second NEW_CONTACT while the first post was still in flight sent again (and the same gap double-posted a prefix-collision alert onto the mesh, which the bridges delivered twice). It now records the key before it sends.
- The greeter's warmup (`rollout_days`) runs once, the first time the greeter starts. A restart more than a day after the previous warmup ended used to open another one, and anyone who spoke during it was marked greeted and never welcomed. Ending a warmup, or it expiring, no longer starts a new one on the next boot.
+2 -1
View File
@@ -370,7 +370,8 @@ def format_mqtt_weather_payload(
if temp_f is not None:
# Rounded to one decimal (the usual precision of the °F reading) so the bare
# {temperature_c} placeholder renders e.g. 16.3 rather than 16.27777777777778.
temp_c = round((temp_f - 32.0) * 5.0 / 9.0, 1)
# Adding 0.0 turns -0.0 (31.95°F) into 0.0 so it doesn't print as "-0.0".
temp_c = round((temp_f - 32.0) * 5.0 / 9.0, 1) + 0.0
uptime_i = _coerce_nonnegative_int(data.get("uptime_s"))
+8
View File
@@ -269,3 +269,11 @@ def test_mqtt_weather_display_no_cache() -> None:
text2, err2 = mqtt_weather_display_for_topic("missing", None, fmt)
assert text2 is None
assert err2 == "no_cache"
def test_celsius_just_below_freezing_is_not_negative_zero() -> None:
fmt = _default_json_template_fmt()
raw = json.dumps({"time": "12:00", "temperature_F": 31.95, "humidity": 70}).encode()
text, err = format_mqtt_weather_payload(raw, fmt)
assert err is None
assert text == "12:00 | 31.95°F (0.0°C) | RH 70.0%"