span-panel-api-schema-1 1.2.1b1__tar.gz → 1.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/CHANGELOG.md +25 -17
  2. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/PKG-INFO +2 -2
  3. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/pyproject.toml +5 -3
  4. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/adapter.py +9 -2
  5. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/circuits.py +2 -2
  6. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/.gitignore +0 -0
  7. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/README.md +0 -0
  8. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/breaker.json +0 -0
  9. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/charge-limit.json +0 -0
  10. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/connection.json +0 -0
  11. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/door.json +0 -0
  12. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/grid-forming.json +0 -0
  13. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/grid.json +0 -0
  14. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/info.json +0 -0
  15. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/load-shed.json +0 -0
  16. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/meter.json +0 -0
  17. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/pcs.json +0 -0
  18. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/power-flows.json +0 -0
  19. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/shed-forecast.json +0 -0
  20. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/shed.json +0 -0
  21. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/soc.json +0 -0
  22. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/status.json +0 -0
  23. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/catalogs/switch.json +0 -0
  24. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/spec/registries/device-types.md +0 -0
  25. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/__init__.py +0 -0
  26. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/adoption.py +0 -0
  27. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/catalog.py +0 -0
  28. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/charge_limit.py +0 -0
  29. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/const.py +0 -0
  30. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/description.py +0 -0
  31. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/devices.py +0 -0
  32. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/extension.py +0 -0
  33. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/field_metadata.py +0 -0
  34. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/firmware.py +0 -0
  35. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/panel.py +0 -0
  36. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/py.typed +0 -0
  37. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/reference/parent_child_tree.json +0 -0
  38. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/snapshot.py +0 -0
  39. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/spec_lock.json +0 -0
  40. {span_panel_api_schema_1-1.2.1b1 → span_panel_api_schema_1-1.2.2}/src/span_panel_api_schema_1/transport.py +0 -0
@@ -9,38 +9,46 @@ number. A release here means this parser changed, never that the panel did.
9
9
 
10
10
  Pre-releases are not listed separately. A beta is a step towards the next public version, so its changes are folded into that version's entry as they land and are described against the last public release, never against the beta before it.
11
11
 
12
- ## [1.2.1b1]
12
+ ## [1.2.2]
13
13
 
14
- No inverter is primary any more. Requires `span-panel-api` **3.6.1 or newer**. 1.2.0 was withdrawn from PyPI; this release carries its changes, listed under 1.2.0 below, except how `pv` is chosen, which this release replaces.
14
+ Requires `span-panel-api` **3.6.2 or newer**, which waits on this parser's missing labels after a reconnect as well as on connect.
15
15
 
16
- ### Changed
16
+ ### Fixed
17
17
 
18
- - **`pv` describes the inverters together when a panel commissions more than one**, with their shared vendor and model, the sum of their installed DC sizes and a link that is down if any is down, rather than the one on the lowest breaker space.
18
+ - **`circuit_nodes_missing_names()` gives an inverter that appears after another inverter's feed link has arrived, within the same wait, a full grace for its own**, rather than reporting nothing missing the moment it appears and so letting it be keyed by
19
+ its device id.
19
20
 
20
- ### Removed
21
+ ## [1.2.1]
21
22
 
22
- - **`snapshot.primary_pv` and `TreeRoles.pv`**, which singled out one inverter as `pv`.
23
+ Every PV inverter a panel commissions is read, and the battery's power keeps its sign on firmware r202639. Requires `span-panel-api` **3.6.1 or newer**.
23
24
 
24
- ## [1.2.0] [YANKED]
25
+ ### Added
25
26
 
26
- Every PV inverter a panel commissions is read, and the battery's power keeps its sign on firmware r202639. Requires `span-panel-api` **3.6.0 or newer**.
27
+ - **Every PV inverter is read, not only the first**, each landing in `pv_inverters` with its serial number when published, its device id and its key.
28
+ - **`pv.serial_number` is read from `info/serial-number`**, so that property no longer appears as a discovery row.
29
+ - **`TreeRoles.pvs` and `devices.pv_inverter_key`** list every inverter and give an inverter's key.
30
+ - **`span_panel_api_schema_1.firmware.release_build`** reads the six-digit release build number out of a firmware version string, or returns `None` when it has none.
31
+ - **`build_battery` takes keyword-only `firmware_version` and `power_flow_battery`** to pick the BESS meter's wire frame, and `SchemaOneAdapter` a keyword-only `clock` for the wait on feeding circuits, and both behave as before without them.
32
+
33
+ ### Changed
34
+
35
+ - **`pv` describes the inverters together when a panel commissions more than one**, with their shared vendor and model, the sum of their installed DC sizes and a link that is down if any is down, rather than whichever came first in the device tree.
36
+
37
+ ### Removed
38
+
39
+ - **`TreeRoles.pv`**, which held only the first inverter, replaced by `TreeRoles.pvs`.
27
40
 
28
41
  ### Fixed
29
42
 
30
- - **A second inverter's feeding circuit is labeled `device_type="pv"`**, so its power no longer reads as a load with the opposite sign.
31
- - **A PV inverter wired through two breakers now reports its power and link status consistently**, with both circuits labeled `pv` and its feed and link status read from the one with the lowest circuit id.
32
- - **`pv` is the inverter on the lowest breaker space when more than one is commissioned**, rather than whichever came first in the device tree.
43
+ - **Every inverter's feeding circuit is labeled `device_type="pv"`**, so a second inverter's power no longer reads as a load with the opposite sign.
44
+ - **A PV inverter or charger wired through two breakers reports its power and link status consistently**, with both circuits labeled for it and its feed and link status read from the one with the lowest circuit id.
33
45
  - **Each inverter's extension properties are filed under that inverter**, with its `pv_inverters` key as the `instance_key` when more than one is commissioned.
34
46
  - **The first snapshot waits briefly for the circuits that feed an inverter**, so an inverter's key and its circuit's label do not change just after connecting.
35
47
  - **`battery.power_w` is discharge-positive on firmware r202639 and later, from the first snapshot on**, where a charging battery read positive.
36
48
 
37
- ### Added
49
+ ## [1.2.0] [YANKED]
38
50
 
39
- - **`span_panel_api_schema_1.firmware.release_build`** reads the six-digit release build number out of a firmware version string, or returns `None` when it has none.
40
- - **`build_battery` takes keyword-only `firmware_version` and `power_flow_battery`** to pick the BESS meter's wire frame, and behaves as before without them.
41
- - **Every PV inverter is read, not only the first**, each landing in `pv_inverters` with its serial number when published, its device id and its key.
42
- - **`TreeRoles.pvs` lists every inverter**, and `snapshot.primary_pv`, `devices.pv_inverter_key` and `circuits.circuit_tabs` choose the one `pv` describes, give an inverter's key, and read a circuit's breaker spaces.
43
- - **`pv.serial_number` is read from `info/serial-number`**, so that property no longer appears as a discovery row.
51
+ Withdrawn from PyPI; 1.2.1 replaces it.
44
52
 
45
53
  ## [1.1.4]
46
54
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: span-panel-api-schema-1
3
- Version: 1.2.1b1
3
+ Version: 1.2.2
4
4
  Summary: Parent/child schema (data-model-version 1.x) parser for span-panel-api
5
5
  Project-URL: Homepage, https://github.com/SpanPanel/span-panel-api
6
6
  Project-URL: Issues, https://github.com/SpanPanel/span-panel-api/issues
@@ -8,7 +8,7 @@ Author: SpanPanel
8
8
  License-Expression: MIT
9
9
  Requires-Python: <4.0,>=3.14
10
10
  Requires-Dist: ebus-sdk<0.24,>=0.19.0
11
- Requires-Dist: span-panel-api<4.0,>=3.6.1b1
11
+ Requires-Dist: span-panel-api<4.0,>=3.6.2
12
12
  Description-Content-Type: text/markdown
13
13
 
14
14
  # span-panel-api-schema-1
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "span-panel-api-schema-1"
3
- version = "1.2.1b1"
3
+ version = "1.2.2"
4
4
  description = "Parent/child schema (data-model-version 1.x) parser for span-panel-api"
5
5
  authors = [
6
6
  {name = "SpanPanel"}
@@ -25,8 +25,10 @@ dependencies = [
25
25
  # and the inverter's `serial_number`, `device_id` and `node_id`, which this
26
26
  # parser fills. Against an earlier one, building a snapshot fails on those
27
27
  # arguments.
28
- # Raised to 3.6.1b1, whose SpanPanelSnapshot.pv documents what this parser builds.
29
- "span-panel-api>=3.6.1b1,<4.0",
28
+ # Raised to 3.6.1, whose SpanPanelSnapshot.pv documents what this parser builds.
29
+ # Raised to 3.6.2, which waits on this parser's missing labels after a bridge
30
+ # rebuild as well as on connect; the fix spans both, so the pair moves together.
31
+ "span-panel-api>=3.6.2,<4.0",
30
32
  # Only this distribution depends on the eBus SDK. The bootstrap and
31
33
  # schema-0 stay clean, so a flat-panel install never pulls it in — which is
32
34
  # what bounds the release coupling this dependency introduces to panels on
@@ -230,7 +230,9 @@ class SchemaOneAdapter:
230
230
  unvalued after the grace is taken as absent. The inverter is then keyed
231
231
  by its device id, reported once at INFO rather than the transport
232
232
  warning after the full name timeout. The grace restarts whenever
233
- anything else is missing again.
233
+ anything else is missing again, and once every inverter is placed, so
234
+ an inverter that appears after another's feed has arrived, within the
235
+ same wait, gets a whole grace of its own.
234
236
  """
235
237
  roles = TreeRoles(self._children())
236
238
  missing = [circuit.device_id for circuit in roles.circuits if not circuit.get_property(NODE_INFO, PROP_NAME)]
@@ -257,8 +259,13 @@ class SchemaOneAdapter:
257
259
  )
258
260
  self._feed_wait_reported = True
259
261
  feeds = []
260
- elif missing:
262
+ else:
263
+ # No feed is being waited out on its own: something else is still
264
+ # missing, or every inverter is placed. Either way a later feed wait
265
+ # is a new one and gets the whole grace.
261
266
  self._feed_wait_since = None
267
+ if not feeds:
268
+ self._feed_wait_reported = False
262
269
  missing.extend(feeds)
263
270
  return missing
264
271
 
@@ -116,7 +116,7 @@ def _optional_integer(device: DiscoveredDevice, node: str, prop: str) -> int | N
116
116
  return None if raw is None else int(raw)
117
117
 
118
118
 
119
- def circuit_tabs(device: DiscoveredDevice) -> list[int]:
119
+ def _tabs(device: DiscoveredDevice) -> list[int]:
120
120
  """Breaker spaces from ``info/spaces``.
121
121
 
122
122
  v1.0 publishes the occupied spaces literally (``"36,38"``), where the flat
@@ -254,7 +254,7 @@ def build_circuit(
254
254
  # circuit's.
255
255
  produced_energy_wh=_number(device, NODE_METER, PROP_IMPORTED_ENERGY),
256
256
  consumed_energy_wh=_number(device, NODE_METER, PROP_EXPORTED_ENERGY),
257
- tabs=circuit_tabs(device),
257
+ tabs=_tabs(device),
258
258
  priority=priority,
259
259
  # `always-on` is `not relay-controllable`, and the flat schema derived
260
260
  # user-controllability from `always-on` — so this is the same answer by