1+ import asyncio
2+ import logging
13import time
24from typing import Any
35
46from bleak .backends .device import BLEDevice
57from cryptography .hazmat .primitives .ciphers import Cipher , algorithms , modes
68
79from ..const import SwitchbotModel
8- from .device import SwitchbotSequenceDevice
10+ from ..models import SwitchBotAdvertisement
11+ from .device import SwitchbotDevice
12+
13+ _LOGGER = logging .getLogger (__name__ )
914
1015COMMAND_HEADER = "57"
1116COMMAND_GET_CK_IV = f"{ COMMAND_HEADER } 0f2103"
1217COMMAND_TURN_OFF = f"{ COMMAND_HEADER } 0f70010000"
1318COMMAND_TURN_ON = f"{ COMMAND_HEADER } 0f70010100"
1419COMMAND_TOGGLE = f"{ COMMAND_HEADER } 0f70010200"
1520COMMAND_GET_VOLTAGE_AND_CURRENT = f"{ COMMAND_HEADER } 0f7106000000"
16- PASSIVE_POLL_INTERVAL = 1 * 60
21+ PASSIVE_POLL_INTERVAL = 10 * 60
1722
1823
19- class SwitchbotRelaySwitch (SwitchbotSequenceDevice ):
24+ class SwitchbotRelaySwitch (SwitchbotDevice ):
2025 """Representation of a Switchbot relay switch 1pm."""
2126
2227 def __init__ (
@@ -41,8 +46,30 @@ def __init__(
4146 self ._key_id = key_id
4247 self ._encryption_key = bytearray .fromhex (encryption_key )
4348 self ._model : SwitchbotModel = model
49+ self ._force_next_update = False
4450 super ().__init__ (device , None , interface , ** kwargs )
4551
52+ def update_from_advertisement (self , advertisement : SwitchBotAdvertisement ) -> None :
53+ """Update device data from advertisement."""
54+ # Obtain voltage and current through command.
55+ adv_data = advertisement .data ["data" ]
56+ if previous_voltage := self ._get_adv_value ("voltage" ):
57+ adv_data ["voltage" ] = previous_voltage
58+ if previous_current := self ._get_adv_value ("current" ):
59+ adv_data ["current" ] = previous_current
60+ current_state = self ._get_adv_value ("sequence_number" )
61+ super ().update_from_advertisement (advertisement )
62+ new_state = self ._get_adv_value ("sequence_number" )
63+ _LOGGER .debug (
64+ "%s: update advertisement: %s (seq before: %s) (seq after: %s)" ,
65+ self .name ,
66+ advertisement ,
67+ current_state ,
68+ new_state ,
69+ )
70+ if current_state != new_state :
71+ self ._force_next_update = True
72+
4673 async def update (self , interface : int | None = None ) -> None :
4774 """Update state of device."""
4875 if info := await self .get_voltage_and_current ():
@@ -56,13 +83,16 @@ async def get_voltage_and_current(self) -> dict[str, Any] | None:
5683 ok = self ._check_command_result (result , 0 , {1 })
5784 if ok :
5885 return {
59- "voltage" : (result [9 ] << 8 ) + result [10 ],
86+ "voltage" : (( result [9 ] << 8 ) + result [10 ]) / 10 ,
6087 "current" : (result [11 ] << 8 ) + result [12 ],
6188 }
6289 return None
6390
6491 def poll_needed (self , seconds_since_last_poll : float | None ) -> bool :
6592 """Return if device needs polling."""
93+ if self ._force_next_update :
94+ self ._force_next_update = False
95+ return True
6696 if (
6797 seconds_since_last_poll is not None
6898 and seconds_since_last_poll < PASSIVE_POLL_INTERVAL
0 commit comments