99import logging
1010from typing import Any , Final
1111
12- from ..api import MotionConfig , MotionSensitivity , MotionState , NodeEvent , NodeFeature
12+ from ..api import (
13+ MotionConfig ,
14+ MotionSensitivity ,
15+ MotionState ,
16+ NodeEvent ,
17+ NodeFeature ,
18+ NodeType ,
19+ )
1320from ..connection import StickController
1421from ..constants import MAX_UINT_2
1522from ..exceptions import MessageError , NodeError , NodeTimeout
4855# Light override
4956SCAN_DEFAULT_DAYLIGHT_MODE : Final = False
5057
58+ # Default firmware if not known
59+ DEFAULT_FIRMWARE : Final = datetime (2010 , 11 , 4 , 16 , 58 , 46 , tzinfo = UTC )
60+
5161# Sensitivity values for motion sensor configuration
5262SENSITIVITY_HIGH_VALUE = 20 # 0x14
5363SENSITIVITY_MEDIUM_VALUE = 30 # 0x1E
5464SENSITIVITY_OFF_VALUE = 255 # 0xFF
5565
66+ # Scan Features
67+ SCAN_FEATURES : Final = (
68+ NodeFeature .MOTION ,
69+ NodeFeature .MOTION_CONFIG ,
70+ )
71+
5672# endregion
5773
5874
@@ -63,11 +79,12 @@ def __init__(
6379 self ,
6480 mac : str ,
6581 address : int ,
82+ node_type : NodeType ,
6683 controller : StickController ,
6784 loaded_callback : Callable [[NodeEvent , str ], Awaitable [None ]],
6885 ):
6986 """Initialize Scan Device."""
70- super ().__init__ (mac , address , controller , loaded_callback )
87+ super ().__init__ (mac , address , node_type , controller , loaded_callback )
7188 self ._unsubscribe_switch_group : Callable [[], None ] | None = None
7289 self ._reset_timer_motion_on : datetime | None = None
7390 self ._scan_subscription : Callable [[], None ] | None = None
@@ -89,26 +106,17 @@ async def load(self) -> bool:
89106 """Load and activate Scan node features."""
90107 if self ._loaded :
91108 return True
92- if self ._cache_enabled :
93- _LOGGER .debug ("Load Scan node %s from cache" , self ._node_info .mac )
94- await self ._load_from_cache ()
95- else :
96- self ._load_defaults ()
97- self ._loaded = True
98- self ._setup_protocol (
99- SCAN_FIRMWARE_SUPPORT ,
100- (
101- NodeFeature .BATTERY ,
102- NodeFeature .INFO ,
103- NodeFeature .PING ,
104- NodeFeature .MOTION ,
105- NodeFeature .MOTION_CONFIG ,
106- ),
107- )
109+
110+ _LOGGER .debug ("Loading Scan node %s" , self ._node_info .mac )
111+ if not await super ().load ():
112+ _LOGGER .warning ("Load Scan base node failed" )
113+ return False
114+
115+ self ._setup_protocol (SCAN_FIRMWARE_SUPPORT , SCAN_FEATURES )
108116 if await self .initialize ():
109117 await self ._loaded_callback (NodeEvent .LOADED , self .mac )
110118 return True
111- _LOGGER .debug ("Load of Scan node %s failed" , self ._node_info .mac )
119+ _LOGGER .warning ("Load Scan node %s failed" , self ._node_info .mac )
112120 return False
113121
114122 @raise_not_loaded
@@ -132,9 +140,9 @@ async def unload(self) -> None:
132140 await super ().unload ()
133141
134142 # region Caching
135- def _load_defaults (self ) -> None :
143+ async def _load_defaults (self ) -> None :
136144 """Load default configuration settings."""
137- super ()._load_defaults ()
145+ await super ()._load_defaults ()
138146 self ._motion_state = MotionState (
139147 state = SCAN_DEFAULT_MOTION_STATE ,
140148 timestamp = None ,
@@ -144,11 +152,28 @@ def _load_defaults(self) -> None:
144152 daylight_mode = SCAN_DEFAULT_DAYLIGHT_MODE ,
145153 sensitivity_level = SCAN_DEFAULT_SENSITIVITY ,
146154 )
155+ if self ._node_info .model is None :
156+ self ._node_info .model = "Scan"
157+ self .node_info_default = True
158+ if self ._node_info .name is None :
159+ self ._node_info .name = f"Scan { self ._node_info .mac [- 5 :]} "
160+ self .node_info_default = True
161+ if self ._node_info .name is None :
162+ self ._node_info .name = f"Scan { self ._node_info .mac [- 5 :]} "
163+ self .node_info_default = True
164+ if self ._node_info .firmware is None :
165+ self ._node_info .firmware = DEFAULT_FIRMWARE
166+ self .node_info_default = True
167+ self ._new_reset_timer = SCAN_DEFAULT_MOTION_RESET_TIMER
168+ self ._new_daylight_mode = SCAN_DEFAULT_DAYLIGHT_MODE
169+ self ._new_sensitivity_level = SCAN_DEFAULT_SENSITIVITY
170+ await self .schedule_task_when_awake (self ._configure_scan_task ())
171+ self ._scan_config_task_scheduled = True
147172
148173 async def _load_from_cache (self ) -> bool :
149174 """Load states from previous cached information. Returns True if successful."""
150175 if not await super ()._load_from_cache ():
151- self ._load_defaults ()
176+ await self ._load_defaults ()
152177 return False
153178 self ._motion_state = MotionState (
154179 state = self ._motion_from_cache (),
0 commit comments