From c8a610c30f3ec2691c5a9192fb96b174e4ae92e2 Mon Sep 17 00:00:00 2001 From: thdfw Date: Tue, 31 Dec 2024 16:38:36 +0100 Subject: [PATCH 1/4] Adding (De)EnergizedState attributes to RelayActorConfig --- src/gwproto/named_types/relay_actor_config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gwproto/named_types/relay_actor_config.py b/src/gwproto/named_types/relay_actor_config.py index 24c7cb6c..d17acb47 100644 --- a/src/gwproto/named_types/relay_actor_config.py +++ b/src/gwproto/named_types/relay_actor_config.py @@ -18,5 +18,7 @@ class RelayActorConfig(ChannelConfig): EventType: str DeEnergizingEvent: str EnergizingEvent: str + DeEnergizedState: str + EnergizedState: str TypeName: Literal["relay.actor.config"] = "relay.actor.config" - Version: Literal["001"] = "001" + Version: Literal["002"] = "002" From 127b59afa12817343432abfb17e177c92e9c43d9 Mon Sep 17 00:00:00 2001 From: Jessica Millar Date: Tue, 31 Dec 2024 10:42:14 -0500 Subject: [PATCH 2/4] update version of relay component --- .../named_types/i2c_multichannel_dt_relay_component_gt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gwproto/named_types/i2c_multichannel_dt_relay_component_gt.py b/src/gwproto/named_types/i2c_multichannel_dt_relay_component_gt.py index f1c4d5bf..0b6b3b26 100644 --- a/src/gwproto/named_types/i2c_multichannel_dt_relay_component_gt.py +++ b/src/gwproto/named_types/i2c_multichannel_dt_relay_component_gt.py @@ -15,7 +15,7 @@ class I2cMultichannelDtRelayComponentGt(ComponentGt): TypeName: Literal["i2c.multichannel.dt.relay.component.gt"] = ( "i2c.multichannel.dt.relay.component.gt" ) - Version: Literal["001"] = "001" + Version: Literal["002"] = "002" model_config = ConfigDict(extra="allow", use_enum_values=True) From ccb2f62b3f5ab268dbcaf416d36c07ea28170e7f Mon Sep 17 00:00:00 2001 From: Jessica Millar Date: Wed, 1 Jan 2025 02:04:32 -0500 Subject: [PATCH 3/4] RelayActorConfig has StateType and also some axioms - not enforced yet but axioms to ensure consistency between events and states - also updated tests and made sure code gen was idempotent - and corrected version of TelemetryName (004 with addition of StorageLayer) --- src/gwproto/enums/__init__.py | 2 +- src/gwproto/enums/telemetry_name.py | 3 +- src/gwproto/named_types/relay_actor_config.py | 45 ++++++++++++++++++- tests/enums/telemetry_name_test.py | 4 +- ..._i2c_multichannel_dt_relay_component_gt.py | 17 +++++-- tests/named_types/test_relay_actor_config.py | 5 ++- 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/gwproto/enums/__init__.py b/src/gwproto/enums/__init__.py index 1602f931..9d02e9c2 100644 --- a/src/gwproto/enums/__init__.py +++ b/src/gwproto/enums/__init__.py @@ -94,7 +94,7 @@ "RelayWiringConfig", # [relay.wiring.config.000](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#relaywiringconfig) "StoreFlowRelay", # [store.flow.relay.000](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#storeflowrelay) "Strategy", # [spaceheat.strategy.000](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#spaceheatstrategy) - "TelemetryName", # [spaceheat.telemetry.name.003](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#spaceheattelemetryname) + "TelemetryName", # [spaceheat.telemetry.name.004](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#spaceheattelemetryname) "TempCalcMethod", # [temp.calc.method.000](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#tempcalcmethod) "ThermistorDataMethod", # [thermistor.data.method.000](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#thermistordatamethod) "Unit", # [spaceheat.unit.001](https://gridworks-type-registry.readthedocs.io/en/latest/enums.html#spaceheatunit) diff --git a/src/gwproto/enums/telemetry_name.py b/src/gwproto/enums/telemetry_name.py index 6caae1e4..d381790a 100644 --- a/src/gwproto/enums/telemetry_name.py +++ b/src/gwproto/enums/telemetry_name.py @@ -33,6 +33,7 @@ class TelemetryName(GwStrEnum): - MicroVolts: Microvolts RMS - VoltsTimesTen - WattHours + - StorageLayer For more information: - [ASLs](https://gridworks-type-registry.readthedocs.io/en/latest/) @@ -73,4 +74,4 @@ def enum_name(cls) -> str: @classmethod def enum_version(cls) -> str: - return "003" + return "004" diff --git a/src/gwproto/named_types/relay_actor_config.py b/src/gwproto/named_types/relay_actor_config.py index d17acb47..2a68f978 100644 --- a/src/gwproto/named_types/relay_actor_config.py +++ b/src/gwproto/named_types/relay_actor_config.py @@ -1,8 +1,9 @@ -"""Type relay.actor.config, version 001""" +"""Type relay.actor.config, version 002""" from typing import Literal -from pydantic import PositiveInt +from pydantic import PositiveInt, model_validator +from typing_extensions import Self from gwproto.enums import RelayWiringConfig from gwproto.named_types import ChannelConfig @@ -12,13 +13,53 @@ class RelayActorConfig(ChannelConfig): + """ + Relay Actor Config. + + Used to associate individual relays on a multi-channel relay board to specific SpaceheatNode + actors. Each actor managed by the Spaceheat SCADA has an associated SpaceheatNode. That + Node will be associated to a relay board component with multiple relays. Th relay board + will have a list of relay actor configs so that the actor can identify which relay it has + purview over. Has DeEnergizedState and EnergizedState + + [More info](https://gridworks-protocol.readthedocs.io/en/latest/spaceheat-actor.html) + """ + RelayIdx: PositiveInt ActorName: SpaceheatName WiringConfig: RelayWiringConfig EventType: str DeEnergizingEvent: str EnergizingEvent: str + StateType: str DeEnergizedState: str EnergizedState: str TypeName: Literal["relay.actor.config"] = "relay.actor.config" Version: Literal["002"] = "002" + + @model_validator(mode="after") + def check_axiom_1(self) -> Self: + """ + Axiom 1: EventType, DeEnergizingEvent/EnergizingEvent consistency. + If the event type is the name of a known enum, then the DeEnergizingEvent, EnergizingEvent pair are the values of that enum. + """ + # Implement check for axiom 1" + return self + + @model_validator(mode="after") + def check_axiom_2(self) -> Self: + """ + Axiom 2: StateType, EnergizedState/DeEnergizedState consistency. + If the state type is the name of a known enum, then the DeEnergizedState, EnergizedState pair are the values of that enum. + """ + # Implement check for axiom 2" + return self + + @model_validator(mode="after") + def check_axiom_3(self) -> Self: + """ + Axiom 3: Events and States match. . + E.g. if RelayOpen is the EnergizedState then the EnergizingEvent is OpenRelay. + """ + # Implement check for axiom 3" + return self diff --git a/tests/enums/telemetry_name_test.py b/tests/enums/telemetry_name_test.py index 59b1ee5a..8d9b61f2 100644 --- a/tests/enums/telemetry_name_test.py +++ b/tests/enums/telemetry_name_test.py @@ -1,5 +1,5 @@ """ -Tests for enum spaceheat.telemetry.name.003 from the GridWorks Type Registry. +Tests for enum spaceheat.telemetry.name.004 from the GridWorks Type Registry. """ from gwproto.enums import TelemetryName @@ -29,4 +29,4 @@ def test_telemetry_name() -> None: assert TelemetryName.default() == TelemetryName.Unknown assert TelemetryName.enum_name() == "spaceheat.telemetry.name" - assert TelemetryName.enum_version() == "003" + assert TelemetryName.enum_version() == "004" diff --git a/tests/named_types/test_i2c_multichannel_dt_relay_component_gt.py b/tests/named_types/test_i2c_multichannel_dt_relay_component_gt.py index 4c101113..e1265c44 100644 --- a/tests/named_types/test_i2c_multichannel_dt_relay_component_gt.py +++ b/tests/named_types/test_i2c_multichannel_dt_relay_component_gt.py @@ -17,13 +17,16 @@ def test_i2c_multichannel_dt_relay_component_gt_generated() -> None: "ChannelName": "vdc-relay1", "DeEnergizingEvent": "CloseRelay", "EnergizingEvent": "OpenRelay", + "DeEnergizedState": "RelayClosed", + "EnergizedState": "RelayOpen", "EventType": "change.relay.state", + "StateType": "relay.closed.or.open", "Exponent": 0, "PollPeriodMs": 200, "RelayIdx": 1, "TypeName": "relay.actor.config", "Unit": "Unitless", - "Version": "001", + "Version": "002", "WiringConfig": "NormallyClosed", }, { @@ -33,13 +36,16 @@ def test_i2c_multichannel_dt_relay_component_gt_generated() -> None: "ChannelName": "tstat-common-relay2", "DeEnergizingEvent": "CloseRelay", "EnergizingEvent": "OpenRelay", + "DeEnergizedState": "RelayClosed", + "EnergizedState": "RelayOpen", "EventType": "change.relay.state", + "StateType": "relay.closed.or.open", "Exponent": 0, "PollPeriodMs": 200, "RelayIdx": 2, "TypeName": "relay.actor.config", "Unit": "Unitless", - "Version": "001", + "Version": "002", "WiringConfig": "NormallyClosed", }, { @@ -49,20 +55,23 @@ def test_i2c_multichannel_dt_relay_component_gt_generated() -> None: "ChannelName": "charge-discharge-relay3", "DeEnergizingEvent": "DischargeStore", "EnergizingEvent": "ChargeStore", + "DeEnergizedState": "DischargingStore", + "EnergizedState": "ChargingStore", "EventType": "change.store.flow.relay", + "StateType": "store.flow.relay", "Exponent": 0, "PollPeriodMs": 200, "RelayIdx": 3, "TypeName": "relay.actor.config", "Unit": "Unitless", - "Version": "001", + "Version": "002", "WiringConfig": "NormallyOpen", }, ], "DisplayName": "i2c krida relay boards", "I2cAddressList": [32, 33], "TypeName": "i2c.multichannel.dt.relay.component.gt", - "Version": "001", + "Version": "002", } d2 = I2cMultichannelDtRelayComponentGt.model_validate(d).model_dump( diff --git a/tests/named_types/test_relay_actor_config.py b/tests/named_types/test_relay_actor_config.py index 0bc1c93e..9da6102d 100644 --- a/tests/named_types/test_relay_actor_config.py +++ b/tests/named_types/test_relay_actor_config.py @@ -19,10 +19,13 @@ def test_relay_actor_config_generated() -> None: "ActorName": "zone1-ctrl-relay", "WiringConfig": "NormallyOpen", "EventType": "change.relay.state", + "StateType": "relay.open.or.closed", "DeEnergizingEvent": "OpenRelay", "EnergizingEvent": "CloseRelay", + "DeEnergizedState": "RelayOpen", + "EnergizedState": "RelayClosed", "TypeName": "relay.actor.config", - "Version": "001", + "Version": "002", } t = RelayActorConfig.model_validate(d).model_dump_json(exclude_none=True) From 0a3314085d8ba1da1a2af00593b3ffcdf554f5ca Mon Sep 17 00:00:00 2001 From: Jessica Millar Date: Wed, 1 Jan 2025 02:17:49 -0500 Subject: [PATCH 4/4] v1.2.1: Updated relay.actor.config --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dc4669f1..cb462793 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gridworks-protocol" -version = "1.2.0" +version = "1.2.1" description = "Gridworks Protocol" authors = ["Jessica Millar "] license = "MIT"