2727from ..constants import (
2828 DAY_IN_HOURS ,
2929 DEFAULT_CONS_INTERVAL ,
30+ LOGADDR_MAX ,
3031 MAX_TIME_DRIFT ,
3132 MINIMAL_POWER_UPDATE ,
3233 NO_PRODUCTION_INTERVAL ,
@@ -1030,26 +1031,11 @@ async def node_info_update(
10301031 node_info = await node_request .send ()
10311032
10321033 if node_info is None :
1034+ _LOGGER .debug ("No response for node_info_update() for %s" , self .mac )
1035+ await self ._available_update_state (False )
10331036 return None
10341037
10351038 await super ().node_info_update (node_info )
1036- await self ._relay_update_state (
1037- node_info .relay_state , timestamp = node_info .timestamp
1038- )
1039- if self ._current_log_address is not None and (
1040- self ._current_log_address > node_info .current_logaddress_pointer
1041- or self ._current_log_address == 1
1042- ):
1043- # Rollover of log address
1044- _LOGGER .debug (
1045- "Rollover log address from %s into %s for node %s" ,
1046- self ._current_log_address ,
1047- node_info .current_logaddress_pointer ,
1048- self ._mac_in_str ,
1049- )
1050-
1051- if self ._current_log_address != node_info .current_logaddress_pointer :
1052- self ._current_log_address = node_info .current_logaddress_pointer
10531039
10541040 return self ._node_info
10551041
@@ -1059,14 +1045,29 @@ async def update_node_details(
10591045 ) -> bool :
10601046 """Process new node info and return true if all fields are updated."""
10611047 if node_info .relay_state is not None :
1062- self ._relay_state = replace (
1063- self ._relay_state ,
1064- state = node_info .relay_state ,
1065- timestamp = node_info .timestamp ,
1048+ await self ._relay_update_state (
1049+ node_info .relay_state , timestamp = node_info .timestamp
1050+ )
1051+
1052+ if (
1053+ node_info .current_logaddress_pointer is not None
1054+ and self ._current_log_address is not None
1055+ and (
1056+ self ._current_log_address < node_info .current_logaddress_pointer
1057+ or self ._current_log_address == 1
1058+ )
1059+ ):
1060+ # Rollover of log address
1061+ _LOGGER .debug (
1062+ "Rollover log address from %s into %s for node %s" ,
1063+ self ._current_log_address ,
1064+ node_info .current_logaddress_pointer ,
1065+ self ._mac_in_str ,
10661066 )
10671067
10681068 if node_info .current_logaddress_pointer is not None :
10691069 self ._current_log_address = node_info .current_logaddress_pointer
1070+ self ._energy_counters .set_current_logaddres (self ._current_log_address )
10701071
10711072 return await super ().update_node_details (node_info )
10721073
@@ -1363,3 +1364,71 @@ async def energy_reset_request(self) -> None:
13631364 "Node info update after energy-reset successful for %s" ,
13641365 self ._mac_in_str ,
13651366 )
1367+
1368+ async def energy_logaddr_setrequest (self , logaddr : int ) -> None :
1369+ """Set the logaddress to a specific value."""
1370+ if self ._node_protocols is None :
1371+ raise NodeError ("Unable to energy-reset when protocol version is unknown" )
1372+
1373+ if logaddr < 1 or logaddr >= LOGADDR_MAX :
1374+ raise ValueError ("Set logaddress out of range for {self._mac_in_str}" )
1375+ request = CircleClockSetRequest (
1376+ self ._send ,
1377+ self ._mac_in_bytes ,
1378+ datetime .now (tz = UTC ),
1379+ self ._node_protocols .max ,
1380+ logaddr ,
1381+ )
1382+ if (response := await request .send ()) is None :
1383+ raise NodeError (f"Logaddress set for { self ._mac_in_str } failed" )
1384+
1385+ if response .ack_id != NodeResponseType .CLOCK_ACCEPTED :
1386+ raise MessageError (
1387+ f"Unexpected NodeResponseType { response .ack_id !r} received as response to CircleClockSetRequest"
1388+ )
1389+
1390+ _LOGGER .warning ("Logaddress set for Node %s successful" , self ._mac_in_str )
1391+
1392+ # Follow up by an energy-intervals (re)set
1393+ interval_request = CircleMeasureIntervalRequest (
1394+ self ._send ,
1395+ self ._mac_in_bytes ,
1396+ DEFAULT_CONS_INTERVAL ,
1397+ NO_PRODUCTION_INTERVAL ,
1398+ )
1399+ if (interval_response := await interval_request .send ()) is None :
1400+ raise NodeError ("No response for CircleMeasureIntervalRequest" )
1401+
1402+ if (
1403+ interval_response .response_type
1404+ != NodeResponseType .POWER_LOG_INTERVAL_ACCEPTED
1405+ ):
1406+ raise MessageError (
1407+ f"Unknown NodeResponseType '{ interval_response .response_type .name } ' received"
1408+ )
1409+ _LOGGER .warning ("Resetting energy intervals to default (= consumption only)" )
1410+
1411+ # Clear the cached energy_collection
1412+ if self ._cache_enabled :
1413+ self ._set_cache (CACHE_ENERGY_COLLECTION , "" )
1414+ _LOGGER .warning (
1415+ "Energy-collection cache cleared successfully, updating cache for %s" ,
1416+ self ._mac_in_str ,
1417+ )
1418+ await self .save_cache ()
1419+
1420+ # Clear PulseCollection._logs
1421+ self ._energy_counters .reset_pulse_collection ()
1422+ _LOGGER .warning ("Resetting pulse-collection" )
1423+
1424+ # Request a NodeInfo update
1425+ if await self .node_info_update () is None :
1426+ _LOGGER .warning (
1427+ "Node info update failed after energy-reset for %s" ,
1428+ self ._mac_in_str ,
1429+ )
1430+ else :
1431+ _LOGGER .warning (
1432+ "Node info update after energy-reset successful for %s" ,
1433+ self ._mac_in_str ,
1434+ )
0 commit comments