Builds a circuit-hash index from the combined catalog before refreshing descriptors, so dynamic and removed circuits cannot trigger per-circuit fallback scans while the counter lock is held. Clarifies the module documentation and fixes the Spanish parent-node wording.
Live circuits now follow renames and re-parenting because descriptors refresh from the catalog on each snapshot, while circuits removed from configuration keep their last-known descriptor and continue contributing to their last known parent. Documents the tracker-side lock constraint, releases the throughput table lock before the counter merge, adds a first-miss descriptor recovery test, and applies rustfmt to the new hunk.
Reuses ParentNodeLookup so node attribution follows the same id, name, and attachment-alias precedence as the rest of the runtime, and prefers the published effective parent when capturing circuit identity. Adds an alias-resolution test and clarifies the snapshot lock-order comment.
Captures circuit identity and parent when a counter first receives traffic, so circuits removed from configuration keep contributing to their last known parent instead of dropping out of node totals. Resolves parent nodes by stable id before name, fills descriptors at read time, skips zero-byte deltas, and documents the counter lock ordering. Expands tests for the absent config section, disabled snapshots, root-attached circuits, id-preferred node resolution, and stable circuit ordering.
Documents the optional [byte_counters] section, counter reset semantics, subtree-inclusive node totals, and the GET /byte_counters endpoint in English and Spanish.
When [byte_counters] enabled = true, the one-second throughput tracker batches each circuit's actual-byte deltas into a cumulative counter map. Node totals are rolled up through the runtime network tree when the bus is queried, so node values include descendants. Counters are in-memory and reset when lqosd restarts.
Adds GetByteCounters with cumulative per-node and per-circuit byte counter payloads. The request is read-only, so it fails fast on timeout and needs no daemon-side mutation.
Adds a [byte_counters] section that is absent by default, so existing configuration files keep working unchanged. The section will gate cumulative per-circuit and per-node byte counter collection in lqosd.
findBandwidthMins() reused one minDownload/minUpload counter for both each node's own minimum and the running sibling total, so every sibling after the first inherited the circuit minimums of the siblings before it. Those inflated minimums are written to queuingStructure.json and become HTB rates, which can guarantee child nodes more bandwidth than their parent supplies.
Reset the counters per node and keep a separate running total for the parent. Also fix the no-minimum-key fallback, which used minUpload for the download minimum.
The function is hoisted to module level so the behavior can be unit tested, with regression coverage for sibling accumulation and order, nested roll-up, and the download fallback.
Consolidate the atomic writer into src/atomic_io.py and route the
remaining runtime/generated writes through it so an interrupted write
cannot leave a truncated file. Preserve destination ownership and
permissions across the rename, and treat an unreadable or non-object
network.json as a validation failure instead of crashing the scheduler.
The Powercode preseem API returns customer and equipment ids as ints
while service ids come back as strings, so the service lookup in
createShaper() never matched and zero customers were imported. All ids
are now normalized to strings before use.
The integration now also pulls the list_sites endpoint and builds the
network hierarchy from it: sites are added as site nodes, site
infrastructure equipment that has subscribers attached (APs, routers,
backhauls) becomes AP nodes, and customers are parented onto the AP
their equipment references, falling back to a sibling device's AP and
then to the root. Display names are trimmed and de-duplicated so the
topology compiler's exact-match parent name validation passes.
Keep queued Bakery commands intact while lqosd checks local .keys state, releasing the gate for both successful and non-fatal cache outcomes without tying startup to Insight network availability.