Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugwise_usb/connection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ async def send(
return await self._queue.submit(request)
try:
return await self._queue.submit(request)
except (NodeError, StickError):
except NodeError, StickError:
return None
Comment thread
coderabbitai[bot] marked this conversation as resolved.

def _reset_states(self) -> None:
Expand Down
26 changes: 19 additions & 7 deletions plugwise_usb/messages/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
CirclePlusRealTimeClockResponse,
CirclePlusScanResponse,
CirclePowerUsageResponse,
CircleRelayInitStateResponse,
EnergyCalibrationResponse,
NodeAckResponse,
NodeFeaturesResponse,
Expand Down Expand Up @@ -60,6 +61,7 @@ class PlugwiseRequest(PlugwiseMessage):
"""Base class for request messages to be sent from by USB-Stick."""

_reply_identifier: bytes | None = b"0000"
_reply_identifier_2: bytes | None = None

def __init__(
self,
Expand Down Expand Up @@ -157,7 +159,7 @@ async def subscribe_to_response(
[
Callable[[PlugwiseResponse], Coroutine[Any, Any, bool]],
bytes | None,
tuple[bytes | None, ...] | None,
tuple[bytes, ...] | None,
bytes | None,
],
Coroutine[Any, Any, Callable[[], None]],
Expand All @@ -171,10 +173,18 @@ async def subscribe_to_response(
self._unsubscribe_stick_response = await stick_subscription_fn(
self._process_stick_response, self._seq_id, None
)
reply_identifiers = (
tuple(
reply_id
for reply_id in (self._reply_identifier, self._reply_identifier_2)
if reply_id is not None
)
or None
)
self._unsubscribe_node_response = await node_subscription_fn(
self.process_node_response,
self._mac,
(self._reply_identifier,),
reply_identifiers,
self._seq_id,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
)

Expand Down Expand Up @@ -1510,11 +1520,13 @@ class CircleRelayInitStateRequest(PlugwiseRequest):
"""Get or set initial relay state after power-up of Circle.

Supported protocols : 2.6
Response message : NodeAckResponse # CircleInitRelayStateResponse
Response message : NodeAckResponse for set
: CircleInitRelayStateResponse for get
Comment thread
bouwew marked this conversation as resolved.
Outdated
"""

_identifier = b"0138" # PWCircleGetSetInitialRelaisStateRequestV2_6
_reply_identifier = b"0100" # b"0139" # PWCircleGetSetInitialRelaisStateReplyV2_6
_reply_identifier = b"0139" # CircleRelayInitStateResponse
_reply_identifier_2 = b"0100" # NodeAckResponse

def __init__(
self,
Expand All @@ -1530,13 +1542,13 @@ def __init__(
self.relay = Int(1 if relay_state else 0, length=2)
self._args += [self.set_or_get, self.relay]

async def send(self) -> NodeAckResponse | None:
async def send(self) -> CircleRelayInitStateResponse | NodeAckResponse | None:
"""Send request."""
result = await self._send_request()
if isinstance(result, NodeAckResponse):
if isinstance(result, CircleRelayInitStateResponse | NodeAckResponse):
return result
if result is None:
return None
raise MessageError(
f"Invalid response message. Received {result.__class__.__name__}, expected NodeAckResponse"
f"Invalid response message. Received {result.__class__.__name__}, expected CircleRelayInitStateResponse or NodeAckResponse"
)
8 changes: 5 additions & 3 deletions plugwise_usb/messages/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,21 @@ class NodeResponseType(bytes, Enum):
CIRCLE_PLUS = b"00DD" # ack for CirclePlusAllowJoiningRequest with state false - HN_ALLOWNEWNODESTOJOIN_ACK_0
RELAY_SWITCHED_OFF = b"00DE" # HN_SETRELAISPOSITION_OFF
REAL_TIME_CLOCK_ACCEPTED = b"00DF" # HN_SETRTCDATA_ACK
RELAY_SWITCH_FAILED = b"00E2" # HN_SETRELAISPOSITION_DENIED
RELAY_SWITCH_FAILED = b"00E2" # HN_SETRELAISPOSITION_DENIED
REAL_TIME_CLOCK_FAILED = b"00E7" # HN_SETRTCDATA_NACK
NODE_RESET_ACK = b"00F2" # HN_REPLYROLECHANGED_OK
NODE_RESET_FAIL = b"00F3" # HN_REPLYROLECHANGED_NOT_OK
SED_CONFIG_ACCEPTED = b"00F6" # HN_ACKSETSLEEPBEHAVIOR
SED_CONFIG_FAILED = b"00F7" # HN_ACKREQUESTSELFREMOVALFROMNETWORK
POWER_LOG_INTERVAL_ACCEPTED = b"00F8" # ack for CircleMeasureIntervalRequest - HN_ACKSETPOWERRECORDING
POWER_LOG_INTERVAL_ACCEPTED = (
b"00F8" # ack for CircleMeasureIntervalRequest - HN_ACKSETPOWERRECORDING
)


class NodeAckResponseType(bytes, Enum):
"""Response types of a 'NodeAckResponse' reply message."""

DEFAULT_ACK= b"00A0" # HN_DEFAULT_ACK
DEFAULT_ACK = b"00A0" # HN_DEFAULT_ACK
DEFAULT_FAIL = b"00A1" # HN_DEFAULT_NACK
SENSE_INTERVAL_ACCEPTED = b"00B3" # HN_ACKSETSENSEINTERVAL_ACK
SENSE_INTERVAL_FAILED = b"00B4" # HN_ACKSETSENSEINTERVAL_NACK
Expand Down
57 changes: 43 additions & 14 deletions plugwise_usb/nodes/circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@
CircleMeasureIntervalRequest,
CirclePowerUsageRequest,
CircleRelayInitStateRequest,
CircleRelayInitStateResponse,
CircleRelaySwitchRequest,
EnergyCalibrationRequest,
NodeInfoRequest,
)
from ..messages.responses import NodeInfoResponse, NodeResponseType
from ..messages.responses import NodeAckResponseType, NodeInfoResponse, NodeResponseType
from .helpers import EnergyCalibration, raise_not_loaded
from .helpers.counter import EnergyCounters
from .helpers.firmware import CIRCLE_FIRMWARE_SUPPORT
Expand Down Expand Up @@ -1140,28 +1141,56 @@
"Retrieval of initial state of relay is not "
+ f"supported for device {self.name}"
)
request = CircleRelayInitStateRequest(
self._send, self._mac_in_bytes, False, False
)
if (response := await request.send()) is not None:

try:
request = CircleRelayInitStateRequest(
self._send, self._mac_in_bytes, False, False
)
except MessageError as err:
raise NodeError(f"{self._mac_in_str} error: {err}")
Comment thread
bouwew marked this conversation as resolved.
Outdated

if (response := await request.send()) is None:
_LOGGER.warning(
"No response from %s to get relay init setting", self._mac_in_str
)
return

if isinstance(response, CircleRelayInitStateResponse):
_LOGGER.debug("Successful get of relay init state for %s", self._mac_in_str)
await self._relay_init_update_state(response.relay.value == 1)
return self._relay_config.init_state
return None

async def _relay_init_set(self, state: bool) -> bool | None:
return

Check warning on line 1162 in plugwise_usb/nodes/circle.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this redundant return.

See more on https://sonarcloud.io/project/issues?id=plugwise_python-plugwise-usb&issues=AZzXk_NAAhZglXSHRtfn&open=AZzXk_NAAhZglXSHRtfn&pullRequest=425

async def _relay_init_set(self, state: bool) -> None:
"""Configure relay init state."""
if NodeFeature.RELAY_INIT not in self._features:
raise NodeError(
"Configuring of initial state of relay is not"
+ f"supported for device {self.name}"
)
request = CircleRelayInitStateRequest(
self._send, self._mac_in_bytes, True, state
)
if (response := await request.send()) is not None:

try:
request = CircleRelayInitStateRequest(
self._send, self._mac_in_bytes, True, state
)
except MessageError as err:
raise NodeError(f"{self._mac_in_str} error: {err}")

if (response := await request.send()) is None:
_LOGGER.warning(
"No response from %s to configure relay init setting", self._mac_in_str
)
return None

if response.node_ack_type == NodeAckResponseType.DEFAULT_FAIL:
_LOGGER.warning("Failed to set relay init state for %s", self._mac_in_str)
return None

if response.node_ack_type == NodeAckResponseType.DEFAULT_ACK:
_LOGGER.debug("Successful set relay init state for %s", self._mac_in_str)
await self._relay_init_update_state(response.relay.value == 1)
return self._relay_config.init_state
return None

return

Check warning on line 1193 in plugwise_usb/nodes/circle.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this redundant return.

See more on https://sonarcloud.io/project/issues?id=plugwise_python-plugwise-usb&issues=AZzXk_NAAhZglXSHRtfo&open=AZzXk_NAAhZglXSHRtfo&pullRequest=425

async def _relay_init_load_from_cache(self) -> bool:
"""Load relay init state from cache. Returns True if retrieval was successful."""
Expand Down
Loading