feat(content): v0.5.8-state_511_atis -- central_normalizer with Photon nearest_town + composer bypass + SB->S route normalization

First per-adapter content formatter in the meshai-side central_normalizer library (per Central response to schema-divergence + nearest-town reports). state_511_atis (94% of Idaho 511 work-zone traffic) now produces clean wire strings like "🚧 SH-55, near McCall: both directions, emergency repairs" instead of the previous "🚧 ROADS: Work Zone, US-ID. routine -- roadwork".

Implementation: nearest_town(lat, lon) calls Photon directly at 100.64.0.24:2322/reverse with osm_tag=place + client-side filter for city/town/village/hamlet (Navi passthrough route documented in Central response does not exist on current Navi instance). H3-cell-7 LRU cache. Town fallback chain: _enriched.geocoder.city -> nearest_town(coords) -> drop segment. Composer bypass via event.data["_meshai_precomposed"] flag -- renderer owns full wire string for normalized events. SB->S route normalization. distance<1mi -> "near X".

Tests: 535 passed (was 511, +24 net). Synthetic probe over 25 bucket-B + 8 fixture envelopes confirmed 23/25 + 8/8 produce clean output; 2/25 fell back to None (drop segment) on Photon index gaps near Boise/Cascade. Matt eyeballed and approved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Johnson 2026-06-04 21:38:40 +00:00
commit 7751a40c6c
15 changed files with 1801 additions and 0 deletions

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33902",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-28T14:54:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33902",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-28T14:54:00Z",
"expires": "2026-05-29T15:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-112.358931947559,
43.2045296484166
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "I-15",
"description": "Road construction on I-15 Southbound from MM (93) to MM (89). 1 Right lane closed. 5/29/2026 10:00 AM to 5/29/2026 3:00 PM Fri: 10:00 AM - 3:00 PM Width Restriction: 19ft Speed Restriction: 65mph Activities: Mandatory Speed Limit in Force, Use Caution.<div class='cellSpacer'><i><b>Comments:</b></i> Pile Driving on North West side of the Interstate for bridge foundations. South Bound right lane closed.</div>",
"event_sub_type": "roadConstruction",
"direction": "South",
"location_description": "I-15-BL | I-15-BL",
"county": "Bingham",
"state": "Idaho",
"start_date": "5/29/26, 10:00 AM",
"last_updated": "5/28/26, 2:54 PM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 43.2045296484166,
"longitude": -112.358931947559,
"_enriched": {
"geocoder": {
"name": "Jensen Grove Disc Golf Park",
"city": "Blackfoot",
"county": "Bingham",
"state": "Idaho",
"country": "United States",
"postal_code": "83221",
"timezone": "America/Boise",
"landclass": null,
"elevation_m": 1366.6015625
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33202",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-21T10:40:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33202",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-21T10:40:00Z",
"expires": "2026-06-05T16:30:00Z",
"severity": 1,
"geo": {
"centroid": [
-111.622569529543,
42.3143070666171
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "SH-36",
"description": "Paving Operations on SH-36 from MM (17) to MM (18). 6/1/2026 6:00 AM to 6/5/2026 4:30 PM Mon, Tue, Wed, Thu, Fri: Active all day Width Restriction: 10ft Activities: Pilot Car in Operation, Reduced to Single Lane, Alternating Direction of Travel, Use Caution, Warning.",
"event_sub_type": "pavingOperations",
"direction": "Unknown",
"location_description": "NF-441 | NF-444",
"county": "Franklin",
"state": "Idaho",
"start_date": "6/1/26, 6:00 AM",
"last_updated": "5/21/26, 10:40 AM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 42.3143070666171,
"longitude": -111.622569529543,
"_enriched": {
"geocoder": {
"name": "Cache Nf Road 444",
"city": null,
"county": "Franklin",
"state": "Idaho",
"country": "United States",
"postal_code": null,
"timezone": "America/Boise",
"landclass": "Cache National Forest",
"elevation_m": 2035.1875
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33281",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-29T08:03:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33281",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-29T08:03:00Z",
"expires": "2026-06-03T17:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-112.388532253628,
43.1524044098836
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "I-15",
"description": "Bridge construction on I-15 Northbound from MM (89) to MM (93). 1 Right lane closed. 6/1/2026 7:00 AM to 6/3/2026 5:00 PM Mon: Paused all day, Tue, Wed: 7:00 AM - 5:00 PM Speed Restriction: 65mph Activities: Mandatory Speed Limit in Force, Use Caution.<div class='cellSpacer'><i><b>Comments:</b></i> North Bound right lane closed with speed reduction to 65 mph.\n</div>",
"event_sub_type": "bridgeConstruction",
"direction": "North",
"location_description": "I-15-BL | Snake River",
"county": "Bingham",
"state": "Idaho",
"start_date": "6/1/26, 7:00 AM",
"last_updated": "5/29/26, 8:03 AM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 43.1524044098836,
"longitude": -112.388532253628,
"_enriched": {
"geocoder": {
"name": "North Treaty Highway",
"city": null,
"county": "Bingham",
"state": "Idaho",
"country": "United States",
"postal_code": null,
"timezone": "America/Boise",
"landclass": "Fort Hall Reservation",
"elevation_m": 1367.98828125
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33897",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-28T14:38:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33897",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-28T14:38:00Z",
"expires": "2026-06-02T17:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-116.411904551719,
48.5439764820932
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "US-95",
"description": "Utility work on US-95 Southbound near MM (495). 6/2/2026 9:00 AM to 6/2/2026 5:00 PM Tue: Active all day Activities: Use Caution.",
"event_sub_type": "utilityWork",
"direction": "South",
"location_description": "Dusty Ln",
"county": "Boundary",
"state": "Idaho",
"start_date": "6/2/26, 9:00 AM",
"last_updated": "5/28/26, 2:38 PM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 48.5439764820932,
"longitude": -116.411904551719,
"_enriched": {
"geocoder": {
"name": null,
"city": "Naples",
"county": "Boundary",
"state": "ID",
"country": "United States",
"postal_code": "83847",
"timezone": "America/Los_Angeles",
"landclass": null,
"elevation_m": 659.62890625
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33908",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-28T15:37:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33908",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-28T15:37:00Z",
"expires": "2026-06-13T18:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-116.804061047849,
47.74449
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "W Prairie Ave",
"description": "Minor Paving Operations on W Prairie Ave Both Directions from N Ramsey Rd to N Government Way. Lanes Alternating. 5/28/2026 7:00 AM to 6/13/2026 6:00 PM Mon, Tue, Wed, Thu, Fri: Active all day, Sat, Sun: Paused all day<div class='cellSpacer'><i><b>Comments:</b></i> Lakes Highway District is performing paving operations. US-95 will have the left turn lanes reduced to one left turn lane in both directions, and there will be alternating lane closures on Prairie Ave. reducing to one lane in both directions. Reduce your speed and lookout for workers on the roadway.</div>",
"event_sub_type": "pavingOperations",
"direction": "Both",
"location_description": "N Ramsey Rd | N Government Way",
"county": "Kootenai",
"state": "Idaho",
"start_date": "5/28/26, 7:00 AM",
"last_updated": "5/28/26, 3:37 PM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 47.74449,
"longitude": -116.804061047849,
"_enriched": {
"geocoder": {
"name": "Sandpiper Way",
"city": "Hayden",
"county": "Kootenai",
"state": "Idaho",
"country": "United States",
"postal_code": "83835",
"timezone": "America/Los_Angeles",
"landclass": null,
"elevation_m": 695.83984375
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33930",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-28T17:22:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33930",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-28T17:22:00Z",
"expires": "2026-05-29T08:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-116.09759,
44.9065083834611
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "SH-55",
"description": "Emergency repairs on SH-55 Both Directions near Washington St. 5/28/2026 5:00 PM to 5/29/2026 8:00 AM Thu, Fri: Active all day<div class='cellSpacer'><i><b>Comments:</b></i> Emergency fiber repair</div>",
"event_sub_type": "emergencyRepairs",
"direction": "Both",
"location_description": "Washington St",
"county": "Valley",
"state": "Idaho",
"start_date": "5/28/26, 5:00 PM",
"last_updated": "5/28/26, 5:22 PM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 44.9065083834611,
"longitude": -116.09759,
"_enriched": {
"geocoder": {
"name": "Shell",
"city": "McCall",
"county": "Valley",
"state": "ID",
"country": "United States",
"postal_code": "83638",
"timezone": "America/Boise",
"landclass": null,
"elevation_m": 1537.4609375
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:32196",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-11T15:13:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:32196",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-11T15:13:00Z",
"expires": "2026-06-02T16:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-116.89192200007,
48.1805200000001
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "US-2",
"description": "Minor Road construction on US-2 Eastbound from Keyser Ln to N Riley Creek Rd. 6/1/2026 6:30 AM to 6/2/2026 4:00 PM Mon: 5:00 AM - 3:00 PM, Tue: 5:30 AM - 3:00 PM Activities: Reduced to Single Lane, Alternating Direction of Travel. Expect Delays: Under 15 minutes<div class='cellSpacer'><i><b>Comments:</b></i> road work flaggers in area</div>",
"event_sub_type": "roadConstruction",
"direction": "East",
"location_description": "Keyser Ln | N Riley Creek Rd",
"county": "Bonner",
"state": "Idaho",
"start_date": "6/1/26, 6:30 AM",
"last_updated": "5/11/26, 3:13 PM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 48.1805200000001,
"longitude": -116.89192200007,
"_enriched": {
"geocoder": {
"name": "Priest River Park",
"city": null,
"county": "Bonner",
"state": "Idaho",
"country": "United States",
"postal_code": null,
"timezone": "America/Los_Angeles",
"landclass": null,
"elevation_m": 633.83984375
}
}
}
}
}

View file

@ -0,0 +1,60 @@
{
"id": "ID:Construction:33655",
"source": "central.echo6.co",
"type": "central.work_zone.state_511_atis.v1",
"time": "2026-05-26T07:32:00+00:00",
"datacontenttype": "application/json",
"centralschemaversion": "1.0",
"centralcategory": "work_zone.state_511_atis",
"centralseverity": 1,
"specversion": "1.0",
"data": {
"id": "ID:Construction:33655",
"adapter": "state_511_atis",
"category": "work_zone.state_511_atis",
"time": "2026-05-26T07:32:00Z",
"expires": "2026-06-01T18:00:00Z",
"severity": 1,
"geo": {
"centroid": [
-116.893994470776,
47.8013806004727
],
"bbox": null,
"regions": [
"US-ID"
],
"primary_region": "US-ID",
"geometry": null
},
"data": {
"roadway_name": "SH-41",
"description": "Minor Utility work on SH-41 Southbound near W Boekel Rd. Lane Shift Left. 6/1/2026 7:00 AM to 6/1/2026 6:00 PM Mon: Active all day<div class='cellSpacer'><i><b>Comments:</b></i> Southbound traffic will be shifted to accommodate for Avista to work on power poles. Reduce your speed and lookout for workers on the roadway.</div>",
"event_sub_type": "utilityWork",
"direction": "South",
"location_description": "W Boekel Rd",
"county": "Kootenai",
"state": "Idaho",
"start_date": "6/1/26, 7:00 AM",
"last_updated": "5/26/26, 7:32 AM",
"is_full_closure": false,
"layer": "Construction",
"state_code": "ID",
"latitude": 47.8013806004727,
"longitude": -116.893994470776,
"_enriched": {
"geocoder": {
"name": "American Eagle Automotive",
"city": "Rathdrum",
"county": "Kootenai",
"state": "Idaho",
"country": "United States",
"postal_code": "83858",
"timezone": "America/Los_Angeles",
"landclass": null,
"elevation_m": 673.84765625
}
}
}
}
}

View file

@ -0,0 +1,394 @@
"""Tests for meshai/central_normalizer.py — adapter-specific envelope
normalization. First adapter wired: state_511_atis."""
import json
from datetime import datetime
from pathlib import Path
import pytest
from meshai.central_normalizer import normalize
FIXTURES = Path(__file__).parent / "fixtures" / "central_envelopes"
def _load(name: str) -> dict:
return json.loads((FIXTURES / name).read_text())
def _norm_fixture(name: str) -> dict:
n = normalize(_load(name))
assert n is not None, f"normalize({name}) returned None"
return n
# ---------- adapter dispatch -----------------------------------------------
def test_normalize_returns_none_for_unknown_adapter():
env = {"data": {"adapter": "totally_made_up", "data": {}}}
assert normalize(env) is None
def test_normalize_returns_none_for_non_envelope():
assert normalize(None) is None
assert normalize("not-a-dict") is None
assert normalize([]) is None
# ---------- state_511_atis: MM-range fixture (I-15 SB 93→89) --------------
def test_mm_range_extracted_high_to_low():
n = _norm_fixture("state_511_atis_01_I-15.json")
assert n["source"] == "state_511_atis"
assert n["road"] == "I-15"
assert n["direction"] == "southbound"
assert n["mile_start"] == 93
assert n["mile_end"] == 89 # decreasing range is valid for SB I-15
assert n["impact"] == "partial"
assert n["sub_type"] == "road construction"
assert isinstance(n["description"], str) and "MM (93)" in n["description"]
def test_mm_range_extracted_low_to_high():
n = _norm_fixture("state_511_atis_03_I-15.json")
assert n["road"] == "I-15"
assert n["direction"] == "northbound"
assert n["mile_start"] == 89
assert n["mile_end"] == 93
assert n["sub_type"] == "bridge construction"
# ---------- state_511_atis: MM-near (single mile post) --------------------
def test_mm_near_single_mile_post():
n = _norm_fixture("state_511_atis_04_US-95.json")
assert n["road"] == "US-95"
assert n["direction"] == "southbound"
assert n["mile_start"] == 495
assert n["mile_end"] is None
assert n["sub_type"] == "utility work"
# ---------- state_511_atis: no MM (cross-street / landmark) ---------------
def test_no_mm_in_description_yields_none_mile_posts():
n = _norm_fixture("state_511_atis_05_W_Prairie_Ave.json")
assert n["mile_start"] is None
assert n["mile_end"] is None
assert n["road"] == "W Prairie Ave"
assert n["direction"] == "both"
def test_no_mm_emergency_repairs_landmark():
n = _norm_fixture("state_511_atis_06_SH-55.json")
assert n["mile_start"] is None
assert n["road"] == "SH-55"
assert n["direction"] == "both"
assert n["sub_type"] == "emergency repairs"
# ---------- impact (full_closure vs partial) ------------------------------
def test_partial_impact_for_lane_restriction():
n = _norm_fixture("state_511_atis_01_I-15.json")
assert n["impact"] == "partial"
def test_full_closure_impact():
# Synthetic — we didn't capture a full closure in the 60-sample probe,
# so build one inline to exercise the branch.
env = {
"data": {
"adapter": "state_511_atis",
"category": "closure.state_511_atis",
"data": {
"roadway_name": "I-15",
"direction": "South",
"description": "Road construction on I-15 Southbound near Northgate Pkwy. "
"All lanes closed. 6/1/2026 7:00 AM to 6/10/2026 5:00 PM.",
"event_sub_type": "roadConstruction",
"is_full_closure": True,
"county": "Bannock",
"latitude": 42.8713,
"longitude": -112.4455,
},
},
}
n = normalize(env)
assert n["impact"] == "full_closure"
# ---------- direction normalization ---------------------------------------
@pytest.mark.parametrize("raw,expected", [
("North", "northbound"),
("south", "southbound"),
("Both", "both"),
("East", "eastbound"),
("West", "westbound"),
("Unknown", "unknown"),
("", "unknown"),
("NB", "northbound"),
(None, None),
])
def test_direction_normalization(raw, expected):
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "X", "direction": raw, "description": ""}}}
n = normalize(env)
assert n["direction"] == expected
# ---------- ends_at parsing -----------------------------------------------
def test_ends_at_parsed_from_description():
n = _norm_fixture("state_511_atis_04_US-95.json")
assert isinstance(n["ends_at"], datetime)
assert n["ends_at"].month == 6 and n["ends_at"].day == 2
assert n["ends_at"].hour == 17 # 5 PM
def test_ends_at_missing_when_no_date_range():
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "X", "direction": "Both",
"description": "Just some text with no date."}}}
n = normalize(env)
assert n["ends_at"] is None
# ---------- _enriched geocoder + town -------------------------------------
def test_town_from_geocoder_city():
# Use a fixture and check town came from geocoder city/name.
n = _norm_fixture("state_511_atis_01_I-15.json")
assert isinstance(n["town"], str) and n["town"]
def test_town_missing_when_no_enriched():
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "X", "direction": "Both", "description": ""}}}
n = normalize(env)
assert n["town"] is None
assert n["distance_mi"] is None
assert n["bearing"] is None
def test_distance_bearing_when_town_in_lookup():
# A known town (Idaho Falls) at known coords; event placed 8 mi north.
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "US-20", "direction": "Both",
"description": "Test event",
"_enriched": {"geocoder": {"city": "Idaho Falls"}},
"latitude": 43.4666 + 8.0 / 69.0, # ~8 mi north
"longitude": -112.0340}}}
n = normalize(env)
assert n["town"] == "Idaho Falls"
assert n["distance_mi"] is not None
assert 7 <= n["distance_mi"] <= 9 # ~8 mi
assert n["bearing"] == "N"
def test_distance_none_when_town_not_in_lookup():
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "X", "direction": "Both",
"description": "Test event",
"_enriched": {"geocoder": {"city": "Unknownsville"}},
"latitude": 43.0, "longitude": -116.0}}}
n = normalize(env)
assert n["town"] == "Unknownsville"
assert n["distance_mi"] is None
assert n["bearing"] is None
# ---------- v0.5.8 normalize_road_name (SB/NB/EB/WB → S/N/E/W) ------------
from meshai.central_normalizer import normalize_road_name, nearest_town
@pytest.mark.parametrize("raw,expected", [
("I-15 SB Off Ramp", "I-15 S Off Ramp"),
("I-15 NB Off Ramp", "I-15 N Off Ramp"),
("US-95 NB", "US-95 N"),
("SH-55 EB", "SH-55 E"),
("Exit 80 WB On Ramp", "Exit 80 W On Ramp"),
("I-86-BL", "I-86-BL"), # no SB/NB token; untouched
("I-15", "I-15"),
("", None),
(None, None),
])
def test_normalize_road_name(raw, expected):
assert normalize_road_name(raw) == expected
# ---------- v0.5.8 nearest_town: Photon + H3 cache ------------------------
# Photon /reverse?osm_tag=place returns features like:
_PHOTON_STANLEY = {
"features": [
{"geometry": {"coordinates": [-114.9378523, 44.2161414]},
"properties": {"name": "Stanley", "osm_key": "place", "osm_value": "city"}},
],
}
_PHOTON_MULTI = {
"features": [
# Closer but a "natural" feature -- must NOT be picked (not a place).
{"geometry": {"coordinates": [-114.93, 44.2155]},
"properties": {"name": "Mountain Village Restaurant", "osm_key": "amenity", "osm_value": "restaurant"}},
# Town (~1km away).
{"geometry": {"coordinates": [-114.9378523, 44.2161414]},
"properties": {"name": "Stanley", "osm_key": "place", "osm_value": "city"}},
# Town further out.
{"geometry": {"coordinates": [-115.0588585, 44.2436215]},
"properties": {"name": "Lake Town", "osm_key": "place", "osm_value": "village"}},
],
}
def _clear_h3_cache():
from meshai.central_normalizer import _h3_cache
_h3_cache.clear()
def test_nearest_town_returns_dict_for_known_coord(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places",
lambda lat, lon: _PHOTON_STANLEY["features"])
n = nearest_town(44.2160, -114.9311)
assert n is not None
assert n["name"] == "Stanley"
assert n["distance_mi"] >= 0 and n["distance_mi"] <= 1
assert n["bearing"] in {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}
def test_nearest_town_filters_non_place_osm_values(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
# Only the restaurant; no place tag at all.
monkeypatch.setattr(cn, "_photon_reverse_places",
lambda lat, lon: [
{"geometry": {"coordinates": [-114.93, 44.2155]},
"properties": {"name": "Restaurant",
"osm_key": "amenity", "osm_value": "restaurant"}},
])
assert nearest_town(44.2160, -114.9311) is None
def test_nearest_town_picks_closest_place(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places",
lambda lat, lon: _PHOTON_MULTI["features"])
n = nearest_town(44.2160, -114.9311)
assert n is not None
assert n["name"] == "Stanley" # closer than Lake Town
def test_nearest_town_returns_none_beyond_max_distance(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places",
lambda lat, lon: _PHOTON_STANLEY["features"])
# Event 200 mi from Stanley; max_distance_mi=50 by default.
far_lat = 44.2160 + 200 / 69.0
n = nearest_town(far_lat, -114.9311)
assert n is None
def test_nearest_town_returns_none_on_photon_failure(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places", lambda lat, lon: [])
assert nearest_town(44.2160, -114.9311) is None
def test_nearest_town_caches_via_h3(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
calls = []
def stub(lat, lon):
calls.append((lat, lon))
return _PHOTON_STANLEY["features"]
monkeypatch.setattr(cn, "_photon_reverse_places", stub)
# Two calls at the same coord → only one Photon hit.
nearest_town(44.2160, -114.9311)
nearest_town(44.2160, -114.9311)
assert len(calls) == 1
def test_nearest_town_handles_none_inputs():
_clear_h3_cache()
assert nearest_town(None, -114.9311) is None
assert nearest_town(44.2160, None) is None
# ---------- v0.5.8 town fallback chain in _parse_state_511_atis ------------
def test_town_uses_geocoder_city_when_present(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
photon_calls = []
monkeypatch.setattr(cn, "_photon_reverse_places",
lambda lat, lon: photon_calls.append("called") or [])
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "I-15", "direction": "South",
"description": "construction",
"_enriched": {"geocoder": {"city": "Idaho Falls"}},
"latitude": 43.4666, "longitude": -112.0340}}}
n = normalize(env)
assert n["town"] == "Idaho Falls"
# When city is present, nearest_town should NOT be called.
assert photon_calls == []
def test_town_falls_back_to_nearest_town_when_city_null(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places",
lambda lat, lon: _PHOTON_STANLEY["features"])
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "ID 21", "direction": "Both",
"description": "construction",
"_enriched": {"geocoder": {"city": None, "name": "Some Trail"}},
"latitude": 44.2160, "longitude": -114.9311}}}
n = normalize(env)
assert n["town"] == "Stanley"
def test_town_is_none_when_city_and_photon_both_fail(monkeypatch):
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places", lambda lat, lon: [])
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "X", "direction": "Both",
"description": "x",
"_enriched": {"geocoder": {"city": None, "name": "Old Road"}},
"latitude": 44.2160, "longitude": -114.9311}}}
n = normalize(env)
assert n["town"] is None
assert n["distance_mi"] is None
assert n["bearing"] is None
def test_geocoder_name_is_never_used_as_town_fallback(monkeypatch):
"""Per Matt's locked plan: geocoder.name is forbidden as a town fallback.
Only geocoder.city (PRIMARY) or nearest_town() (SECONDARY) populate it."""
_clear_h3_cache()
from meshai import central_normalizer as cn
monkeypatch.setattr(cn, "_photon_reverse_places", lambda lat, lon: [])
env = {"data": {"adapter": "state_511_atis", "category": "work_zone.state_511_atis",
"data": {"roadway_name": "SH-3", "direction": "Both",
"description": "x",
"_enriched": {"geocoder": {"city": None,
"name": "Cache Nf Road 444"}},
"latitude": 42.2, "longitude": -113.7}}}
n = normalize(env)
# Must NOT pick up "Cache Nf Road 444" from geocoder.name.
assert n["town"] is None

View file

@ -0,0 +1,207 @@
"""Tests for the work_zone mesh renderer."""
from datetime import datetime, timedelta
import pytest
from meshai.notifications.renderers.work_zone import format_work_zone_mesh
def _bytelen(s: str) -> int:
return len(s.encode("utf-8"))
# ---------- canonical / fully-populated case ------------------------------
def test_all_fields_present_produces_canonical_format():
n = {
"source": "state_511_atis", "road": "SH-3", "direction": "both",
"mile_start": 60, "mile_end": None, "description": "...",
"sub_type": "construction work", "impact": "partial",
"ends_at": datetime(2026, 6, 2, 17, 0),
"town": "Plummer", "distance_mi": 8, "bearing": "N",
}
out = format_work_zone_mesh(n, now=datetime(2026, 6, 1, 14, 0))
assert out.startswith("🚧 SH-3 @ mile 60")
assert "8 mi N of Plummer" in out
assert "both directions" in out
assert "construction work" in out
assert _bytelen(out) <= 80
# ---------- segment-drop progression --------------------------------------
def test_no_mile_drops_at_mile_segment():
n = {"source": "state_511_atis", "road": "W Prairie Ave", "direction": "both",
"mile_start": None, "mile_end": None, "sub_type": "paving",
"impact": "partial", "town": "Coeur d'Alene", "distance_mi": 5, "bearing": "E",
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert "@ mile" not in out
assert "W Prairie Ave" in out
assert "5 mi E of Coeur d'Alene" in out
def test_no_town_drops_distance_segment():
n = {"source": "state_511_atis", "road": "SH-55", "direction": "both",
"mile_start": 17, "mile_end": 18, "sub_type": "paving",
"impact": "partial", "town": None, "distance_mi": None, "bearing": None,
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert " mi " not in out
assert " of " not in out
assert "@ mile 1718" in out
def test_no_ends_drops_ends_suffix():
n = {"source": "state_511_atis", "road": "I-86", "direction": "both",
"mile_start": 58, "mile_end": 59, "sub_type": "bridge maintenance",
"impact": "partial", "town": "Pocatello", "distance_mi": 15, "bearing": "W",
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert ", ends" not in out
def test_unknown_direction_drops_direction_phrase():
n = {"source": "state_511_atis", "road": "SH-36", "direction": "unknown",
"mile_start": 17, "mile_end": 18, "sub_type": "paving",
"impact": "partial", "town": None, "distance_mi": None, "bearing": None,
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert "unknown" not in out.lower().split(":")[-1] # no 'unknown' in tail
def test_full_closure_promoted():
n = {"source": "state_511_atis", "road": "I-15", "direction": "southbound",
"mile_start": None, "mile_end": None, "sub_type": "road construction",
"impact": "full_closure", "town": None, "distance_mi": None, "bearing": None,
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert "all lanes closed" in out
# ---------- byte budget ---------------------------------------------------
def test_byte_length_under_80_for_canonical():
n = {"source": "state_511_atis", "road": "SH-3", "direction": "both",
"mile_start": 60, "mile_end": None, "sub_type": "construction work",
"impact": "partial", "town": "Plummer", "distance_mi": 8, "bearing": "N",
"ends_at": datetime(2026, 6, 2, 17, 0), "description": ""}
out = format_work_zone_mesh(n, now=datetime(2026, 6, 1, 14, 0))
assert _bytelen(out) <= 80
def test_byte_length_under_80_with_long_road_name():
n = {"source": "state_511_atis",
"road": "SCIENCE CENTER DR / E ANDERSON ST / N THIRD WAY",
"direction": "both",
"mile_start": 100, "mile_end": 200, "sub_type": "construction work",
"impact": "partial", "town": "Idaho Falls", "distance_mi": 12, "bearing": "SE",
"ends_at": datetime(2026, 9, 16, 1, 0), "description": ""}
out = format_work_zone_mesh(n, now=datetime(2026, 6, 1, 14, 0))
assert _bytelen(out) <= 80, f"over budget: {len(out.encode('utf-8'))} = {out!r}"
def test_emoji_counts_as_4_bytes():
# 🚧 is U+1F6A7 → 4 bytes in UTF-8.
assert _bytelen("🚧") == 4
def test_extreme_road_name_truncated():
# Force the renderer into the truncate-road last-resort branch.
long_road = "VERY-LONG-ROAD-NAME-" * 10
n = {"source": "state_511_atis", "road": long_road, "direction": None,
"mile_start": None, "mile_end": None, "sub_type": None,
"impact": "partial", "town": None, "distance_mi": None, "bearing": None,
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert _bytelen(out) <= 80
assert out.startswith("🚧 ")
assert "" in out or _bytelen(long_road) <= 80 # truncated with ellipsis
# ---------- ends_at relative-time formatting ------------------------------
def test_ends_today_format():
now = datetime(2026, 6, 1, 9, 0)
ends = datetime(2026, 6, 1, 18, 0)
n = {"source": "state_511_atis", "road": "X", "direction": None,
"mile_start": None, "mile_end": None, "sub_type": None, "impact": "partial",
"town": None, "distance_mi": None, "bearing": None,
"ends_at": ends, "description": ""}
out = format_work_zone_mesh(n, now=now)
assert "today" in out and "6pm" in out
def test_ends_within_week_uses_weekday():
now = datetime(2026, 6, 1, 9, 0) # Monday
ends = datetime(2026, 6, 5, 16, 30)
n = {"source": "state_511_atis", "road": "X", "direction": None,
"mile_start": None, "mile_end": None, "sub_type": None, "impact": "partial",
"town": None, "distance_mi": None, "bearing": None,
"ends_at": ends, "description": ""}
out = format_work_zone_mesh(n, now=now)
assert "Fri" in out
assert "4:30pm" in out
def test_ends_past_drops_segment():
now = datetime(2026, 6, 10, 9, 0)
ends = datetime(2026, 5, 5, 17, 0) # already past
n = {"source": "state_511_atis", "road": "X", "direction": None,
"mile_start": None, "mile_end": None, "sub_type": None, "impact": "partial",
"town": None, "distance_mi": None, "bearing": None,
"ends_at": ends, "description": ""}
out = format_work_zone_mesh(n, now=now)
assert ", ends" not in out
# ---------- v0.5.8 distance < 1 mi → "near X" -----------------------------
def test_distance_zero_drops_to_near_only():
n = {"source": "state_511_atis", "road": "SH-55", "direction": "both",
"mile_start": None, "mile_end": None, "sub_type": "emergency repairs",
"impact": "partial", "town": "McCall", "distance_mi": 0, "bearing": "S",
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert "near McCall" in out
assert "0 mi" not in out
assert "S of McCall" not in out
def test_distance_one_keeps_bearing_segment():
n = {"source": "state_511_atis", "road": "SH-41", "direction": "southbound",
"mile_start": None, "mile_end": None, "sub_type": "utility work",
"impact": "partial", "town": "Rathdrum", "distance_mi": 1, "bearing": "S",
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
assert "1 mi S of Rathdrum" in out
# ---------- v0.5.8 no-road fallback (leads with town) ---------------------
def test_no_road_leads_with_town_distance():
n = {"source": "state_511_atis", "road": None, "direction": "southbound",
"mile_start": None, "mile_end": None, "sub_type": "ramp work",
"impact": "partial", "town": "Stanley", "distance_mi": 3, "bearing": "NE",
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
# Head is the distance/town form, not a placeholder.
assert out.startswith("🚧 3 mi NE of Stanley")
assert "Road event" not in out
def test_no_road_no_town_falls_back_to_placeholder():
n = {"source": "state_511_atis", "road": None, "direction": "both",
"mile_start": None, "mile_end": None, "sub_type": None,
"impact": "partial", "town": None, "distance_mi": None, "bearing": None,
"ends_at": None, "description": ""}
out = format_work_zone_mesh(n)
# Placeholder is acceptable when we have literally nothing.
assert out.startswith("🚧 ")