77from typing import Any
88
99from ..api import StickEvent
10+ from ..constants import UTF8
1011from ..exceptions import NodeError , StickError
11- from ..messages .requests import PlugwiseRequest , StickInitRequest
12- from ..messages .responses import PlugwiseResponse , StickInitResponse
12+ from ..helpers .util import version_to_model
13+ from ..messages .requests import (
14+ NodeInfoRequest ,
15+ NodePingRequest ,
16+ PlugwiseRequest ,
17+ StickInitRequest ,
18+ )
19+ from ..messages .responses import (
20+ NodeInfoResponse ,
21+ NodePingResponse ,
22+ PlugwiseResponse ,
23+ StickInitResponse ,
24+ )
1325from .manager import StickConnectionManager
1426from .queue import StickQueue
1527
@@ -26,10 +38,13 @@ def __init__(self) -> None:
2638 self ._unsubscribe_stick_event : Callable [[], None ] | None = None
2739 self ._init_sequence_id : bytes | None = None
2840 self ._is_initialized = False
41+ self ._fw_stick : str | None = None
42+ self ._hw_stick : str | None = None
2943 self ._mac_stick : str | None = None
3044 self ._mac_nc : str | None = None
3145 self ._network_id : int | None = None
3246 self ._network_online = False
47+ self .stick_name : str | None = None
3348
3449 @property
3550 def is_initialized (self ) -> bool :
@@ -43,6 +58,16 @@ def is_connected(self) -> bool:
4358 """Return connection state from connection manager."""
4459 return self ._manager .is_connected
4560
61+ @property
62+ def firmware_stick (self ) -> str | None :
63+ """Firmware version of the Stick."""
64+ return self ._fw_stick
65+
66+ @property
67+ def hardware_stick (self ) -> str | None :
68+ """Hardware version of the Stick."""
69+ return self ._hw_stick
70+
4671 @property
4772 def mac_stick (self ) -> str :
4873 """MAC address of USB-Stick. Raises StickError when not connected."""
@@ -160,16 +185,50 @@ async def initialize_stick(self) -> None:
160185 + f"' { self ._manager .serial_path } '"
161186 )
162187 self ._mac_stick = init_response .mac_decoded
188+ self .stick_name = f"Stick { self ._mac_stick [- 5 :]} "
163189 self ._network_online = init_response .network_online
164190
165191 # Replace first 2 characters by 00 for mac of circle+ node
166192 self ._mac_nc = init_response .mac_network_controller
167193 self ._network_id = init_response .network_id
168194 self ._is_initialized = True
169195
196+ # Add Stick NodeInfoRequest
197+ node_info , _ = await self .get_node_details (self ._mac_stick , ping_first = False )
198+ if node_info is not None :
199+ self ._fw_stick = node_info .firmware
200+ hardware , _ = version_to_model (node_info .hardware )
201+ self ._hw_stick = hardware
202+
170203 if not self ._network_online :
171204 raise StickError ("Zigbee network connection to Circle+ is down." )
172205
206+ async def get_node_details (
207+ self , mac : str , ping_first : bool
208+ ) -> tuple [NodeInfoResponse | None , NodePingResponse | None ]:
209+ """Return node discovery type."""
210+ ping_response : NodePingResponse | None = None
211+ if ping_first :
212+ # Define ping request with one retry
213+ ping_request = NodePingRequest (
214+ self .send , bytes (mac , UTF8 ), retries = 1
215+ )
216+ try :
217+ ping_response = await ping_request .send (suppress_node_errors = True )
218+ except StickError :
219+ return (None , None )
220+ if ping_response is None :
221+ return (None , None )
222+
223+ info_request = NodeInfoRequest (
224+ self .send , bytes (mac , UTF8 ), retries = 1
225+ )
226+ try :
227+ info_response = await info_request .send ()
228+ except StickError :
229+ return (None , None )
230+ return (info_response , ping_response )
231+
173232 async def send (
174233 self , request : PlugwiseRequest , suppress_node_errors : bool = True
175234 ) -> PlugwiseResponse | None :
0 commit comments