Skip to content

Commit 54a19ae

Browse files
authored
Code improvements suggested by Claude.ai (#1215)
1 parent 34b2f04 commit 54a19ae

40 files changed

+3355
-3262
lines changed

deebot_client/commands/json/common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
from abc import ABC, abstractmethod
6-
from datetime import UTC, datetime
6+
import time
77
from types import MappingProxyType
88
from typing import TYPE_CHECKING, Any
99

@@ -45,7 +45,7 @@ def _get_payload(self) -> dict[str, Any] | list[Any]:
4545
payload = {
4646
"header": {
4747
"pri": "1",
48-
"ts": datetime.now(tz=UTC).timestamp(),
48+
"ts": time.time(),
4949
"tzm": 480,
5050
"ver": "0.0.50",
5151
}

deebot_client/event_bus.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import asyncio
66
from datetime import UTC, datetime, timedelta
7-
import threading
87
from typing import TYPE_CHECKING, Any, Final, TypeVar
98

109
from .events import AvailabilityEvent, Event, StateEvent
@@ -69,7 +68,6 @@ def __init__(
6968
capabilities: Capabilities,
7069
) -> None:
7170
self._event_processing_dict: dict[type[Event], _EventProcessingData[Any]] = {}
72-
self._lock = threading.Lock()
7371
self._tasks: set[asyncio.Future[Any]] = set()
7472

7573
self._execute_command: Final = execute_command
@@ -208,16 +206,20 @@ async def _call_refresh_function(self, event_class: type[T]) -> None:
208206
def _get_or_create_event_processing_data(
209207
self, event_class: type[T]
210208
) -> _EventProcessingData[T]:
211-
with self._lock:
212-
event_processing_data = self._event_processing_dict.get(event_class, None)
209+
# Python's GIL protects dict.get() and dict.__setitem__() as atomic operations
210+
# So we don't need a lock here - at worst we create the object twice
211+
event_processing_data = self._event_processing_dict.get(event_class, None)
213212

214-
if event_processing_data is None:
215-
event_processing_data = _EventProcessingData(
216-
self._capabilities.get_refresh_commands(event_class)
217-
)
218-
self._event_processing_dict[event_class] = event_processing_data
213+
if event_processing_data is None:
214+
event_processing_data = _EventProcessingData(
215+
self._capabilities.get_refresh_commands(event_class)
216+
)
217+
# Use setdefault to handle race condition - only one will "win"
218+
event_processing_data = self._event_processing_dict.setdefault(
219+
event_class, event_processing_data
220+
)
219221

220-
return event_processing_data
222+
return event_processing_data
221223

222224
def get_last_event(
223225
self,

deebot_client/hardware/2o4lnm.py

Lines changed: 111 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -102,125 +102,127 @@
102102
water_info,
103103
)
104104
from deebot_client.models import StaticDeviceInfo
105-
from deebot_client.util import short_name
106105

107-
from . import DEVICES
108106

109-
DEVICES[short_name(__name__)] = StaticDeviceInfo(
110-
DataType.JSON,
111-
Capabilities(
112-
device_type=DeviceType.VACUUM,
113-
availability=CapabilityEvent(
114-
AvailabilityEvent, [GetBattery(is_available_check=True)]
115-
),
116-
battery=CapabilityEvent(BatteryEvent, [GetBattery()]),
117-
charge=CapabilityExecute(Charge),
118-
clean=CapabilityClean(
119-
action=CapabilityCleanAction(command=Clean, area=CleanArea),
120-
continuous=CapabilitySetEnable(
121-
ContinuousCleaningEvent,
122-
[GetContinuousCleaning()],
123-
SetContinuousCleaning,
124-
),
125-
count=CapabilitySet(CleanCountEvent, [GetCleanCount()], SetCleanCount),
126-
log=CapabilityEvent(CleanLogEvent, [GetCleanLogs()]),
127-
preference=CapabilitySetEnable(
128-
CleanPreferenceEvent, [GetCleanPreference()], SetCleanPreference
107+
def get_device_info() -> StaticDeviceInfo:
108+
"""Get device info for this model."""
109+
return StaticDeviceInfo(
110+
DataType.JSON,
111+
Capabilities(
112+
device_type=DeviceType.VACUUM,
113+
availability=CapabilityEvent(
114+
AvailabilityEvent, [GetBattery(is_available_check=True)]
129115
),
130-
),
131-
custom=CapabilityCustomCommand(
132-
event=CustomCommandEvent, get=[], set=CustomCommand
133-
),
134-
error=CapabilityEvent(ErrorEvent, [GetError()]),
135-
fan_speed=CapabilitySetTypes(
136-
event=FanSpeedEvent,
137-
get=[GetFanSpeed()],
138-
set=SetFanSpeed,
139-
types=(
140-
FanSpeedLevel.QUIET,
141-
FanSpeedLevel.NORMAL,
142-
FanSpeedLevel.MAX,
143-
FanSpeedLevel.MAX_PLUS,
144-
),
145-
),
146-
life_span=CapabilityLifeSpan(
147-
types=(
148-
LifeSpan.BRUSH,
149-
LifeSpan.FILTER,
150-
LifeSpan.SIDE_BRUSH,
151-
LifeSpan.UNIT_CARE,
152-
LifeSpan.ROUND_MOP,
116+
battery=CapabilityEvent(BatteryEvent, [GetBattery()]),
117+
charge=CapabilityExecute(Charge),
118+
clean=CapabilityClean(
119+
action=CapabilityCleanAction(command=Clean, area=CleanArea),
120+
continuous=CapabilitySetEnable(
121+
ContinuousCleaningEvent,
122+
[GetContinuousCleaning()],
123+
SetContinuousCleaning,
124+
),
125+
count=CapabilitySet(CleanCountEvent, [GetCleanCount()], SetCleanCount),
126+
log=CapabilityEvent(CleanLogEvent, [GetCleanLogs()]),
127+
preference=CapabilitySetEnable(
128+
CleanPreferenceEvent, [GetCleanPreference()], SetCleanPreference
129+
),
153130
),
154-
event=LifeSpanEvent,
155-
get=[
156-
GetLifeSpan(
157-
[
158-
LifeSpan.BRUSH,
159-
LifeSpan.FILTER,
160-
LifeSpan.SIDE_BRUSH,
161-
LifeSpan.UNIT_CARE,
162-
LifeSpan.ROUND_MOP,
163-
]
164-
)
165-
],
166-
reset=ResetLifeSpan,
167-
),
168-
map=CapabilityMap(
169-
cached_info=CapabilityEvent(CachedMapInfoEvent, [GetCachedMapInfo()]),
170-
changed=CapabilityEvent(MapChangedEvent, []),
171-
major=CapabilitySet(MajorMapEvent, [GetMajorMap()], SetMajorMap),
172-
minor=CapabilityExecute(GetMinorMap),
173-
multi_state=CapabilitySetEnable(
174-
MultimapStateEvent, [GetMultimapState()], SetMultimapState
131+
custom=CapabilityCustomCommand(
132+
event=CustomCommandEvent, get=[], set=CustomCommand
175133
),
176-
position=CapabilityEvent(PositionsEvent, [GetPos()]),
177-
relocation=CapabilityExecute(SetRelocationState),
178-
rooms=CapabilityEvent(RoomsEvent, [GetCachedMapInfo()]),
179-
set=CapabilityExecute(GetMapSet),
180-
trace=CapabilityEvent(MapTraceEvent, [GetMapTrace()]),
181-
),
182-
network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]),
183-
play_sound=CapabilityExecute(PlaySound),
184-
settings=CapabilitySettings(
185-
advanced_mode=CapabilitySetEnable(
186-
AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode
134+
error=CapabilityEvent(ErrorEvent, [GetError()]),
135+
fan_speed=CapabilitySetTypes(
136+
event=FanSpeedEvent,
137+
get=[GetFanSpeed()],
138+
set=SetFanSpeed,
139+
types=(
140+
FanSpeedLevel.QUIET,
141+
FanSpeedLevel.NORMAL,
142+
FanSpeedLevel.MAX,
143+
FanSpeedLevel.MAX_PLUS,
144+
),
187145
),
188-
carpet_auto_fan_boost=CapabilitySetEnable(
189-
CarpetAutoFanBoostEvent,
190-
[GetCarpetAutoFanBoost()],
191-
SetCarpetAutoFanBoost,
146+
life_span=CapabilityLifeSpan(
147+
types=(
148+
LifeSpan.BRUSH,
149+
LifeSpan.FILTER,
150+
LifeSpan.SIDE_BRUSH,
151+
LifeSpan.UNIT_CARE,
152+
LifeSpan.ROUND_MOP,
153+
),
154+
event=LifeSpanEvent,
155+
get=[
156+
GetLifeSpan(
157+
[
158+
LifeSpan.BRUSH,
159+
LifeSpan.FILTER,
160+
LifeSpan.SIDE_BRUSH,
161+
LifeSpan.UNIT_CARE,
162+
LifeSpan.ROUND_MOP,
163+
]
164+
)
165+
],
166+
reset=ResetLifeSpan,
192167
),
193-
sweep_mode=CapabilitySetEnable(
194-
SweepModeEvent, [GetSweepMode()], SetSweepMode
168+
map=CapabilityMap(
169+
cached_info=CapabilityEvent(CachedMapInfoEvent, [GetCachedMapInfo()]),
170+
changed=CapabilityEvent(MapChangedEvent, []),
171+
major=CapabilitySet(MajorMapEvent, [GetMajorMap()], SetMajorMap),
172+
minor=CapabilityExecute(GetMinorMap),
173+
multi_state=CapabilitySetEnable(
174+
MultimapStateEvent, [GetMultimapState()], SetMultimapState
175+
),
176+
position=CapabilityEvent(PositionsEvent, [GetPos()]),
177+
relocation=CapabilityExecute(SetRelocationState),
178+
rooms=CapabilityEvent(RoomsEvent, [GetCachedMapInfo()]),
179+
set=CapabilityExecute(GetMapSet),
180+
trace=CapabilityEvent(MapTraceEvent, [GetMapTrace()]),
195181
),
196-
true_detect=CapabilitySetEnable(
197-
TrueDetectEvent, [GetTrueDetect()], SetTrueDetect
182+
network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]),
183+
play_sound=CapabilityExecute(PlaySound),
184+
settings=CapabilitySettings(
185+
advanced_mode=CapabilitySetEnable(
186+
AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode
187+
),
188+
carpet_auto_fan_boost=CapabilitySetEnable(
189+
CarpetAutoFanBoostEvent,
190+
[GetCarpetAutoFanBoost()],
191+
SetCarpetAutoFanBoost,
192+
),
193+
sweep_mode=CapabilitySetEnable(
194+
SweepModeEvent, [GetSweepMode()], SetSweepMode
195+
),
196+
true_detect=CapabilitySetEnable(
197+
TrueDetectEvent, [GetTrueDetect()], SetTrueDetect
198+
),
199+
voice_assistant=CapabilitySetEnable(
200+
VoiceAssistantStateEvent,
201+
[GetVoiceAssistantState()],
202+
SetVoiceAssistantState,
203+
),
204+
volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume),
198205
),
199-
voice_assistant=CapabilitySetEnable(
200-
VoiceAssistantStateEvent,
201-
[GetVoiceAssistantState()],
202-
SetVoiceAssistantState,
206+
state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfo()]),
207+
stats=CapabilityStats(
208+
clean=CapabilityEvent(StatsEvent, [GetStats()]),
209+
report=CapabilityEvent(ReportStatsEvent, []),
210+
total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]),
203211
),
204-
volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume),
205-
),
206-
state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfo()]),
207-
stats=CapabilityStats(
208-
clean=CapabilityEvent(StatsEvent, [GetStats()]),
209-
report=CapabilityEvent(ReportStatsEvent, []),
210-
total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]),
211-
),
212-
water=CapabilityWater(
213-
amount=CapabilitySetTypes(
214-
event=water_info.WaterAmountEvent,
215-
get=[GetWaterInfo()],
216-
set=SetWaterInfo,
217-
types=(
218-
water_info.WaterAmount.LOW,
219-
water_info.WaterAmount.MEDIUM,
220-
water_info.WaterAmount.HIGH,
212+
water=CapabilityWater(
213+
amount=CapabilitySetTypes(
214+
event=water_info.WaterAmountEvent,
215+
get=[GetWaterInfo()],
216+
set=SetWaterInfo,
217+
types=(
218+
water_info.WaterAmount.LOW,
219+
water_info.WaterAmount.MEDIUM,
220+
water_info.WaterAmount.HIGH,
221+
),
222+
),
223+
mop_attached=CapabilityEvent(
224+
water_info.MopAttachedEvent, [GetWaterInfo()]
221225
),
222226
),
223-
mop_attached=CapabilityEvent(water_info.MopAttachedEvent, [GetWaterInfo()]),
224227
),
225-
),
226-
)
228+
)

0 commit comments

Comments
 (0)