Skip to content

Commit 1331e9d

Browse files
authored
feat: add support for 9000 series (#9)
1 parent 09bb66f commit 1331e9d

File tree

2 files changed

+158
-28
lines changed

2 files changed

+158
-28
lines changed

src/oralb_ble/parser.py

+34-28
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class Models(Enum):
4444
IOSeries7 = auto()
4545
IOSeries4 = auto()
4646
SmartSeries7000 = auto()
47+
SmartSeries9000 = auto()
4748

4849

4950
@dataclass
@@ -53,42 +54,44 @@ class ModelDescription:
5354
modes: dict[int, str]
5455

5556

57+
SMART_SERIES_MODES = {
58+
0: "off",
59+
1: "daily clean",
60+
2: "sensitive",
61+
3: "massage",
62+
4: "whitening",
63+
5: "deep clean",
64+
6: "tongue cleaning",
65+
7: "turbo",
66+
255: "unknown",
67+
}
68+
69+
IO_SERIES_MODES = {
70+
0: "daily clean",
71+
1: "sensitive",
72+
2: "gum care",
73+
3: "whiten",
74+
4: "intense",
75+
8: "settings",
76+
}
77+
78+
5679
DEVICE_TYPES = {
5780
Models.IOSeries7: ModelDescription(
5881
device_type="IO Series 7",
59-
modes={
60-
0: "daily clean",
61-
1: "sensitive",
62-
2: "gum care",
63-
3: "whiten",
64-
4: "intense",
65-
8: "settings",
66-
},
82+
modes=IO_SERIES_MODES,
6783
),
6884
Models.IOSeries4: ModelDescription(
6985
device_type="IO Series 4",
70-
modes={
71-
0: "daily clean",
72-
1: "sensitive",
73-
2: "gum care",
74-
3: "whiten",
75-
4: "intense",
76-
8: "settings",
77-
},
86+
modes=IO_SERIES_MODES,
7887
),
7988
Models.SmartSeries7000: ModelDescription(
8089
device_type="Smart Series 7000",
81-
modes={
82-
0: "off",
83-
1: "daily clean",
84-
2: "sensitive",
85-
3: "massage",
86-
4: "whitening",
87-
5: "deep clean",
88-
6: "tongue cleaning",
89-
7: "turbo",
90-
255: "unknown",
91-
},
90+
modes=SMART_SERIES_MODES,
91+
),
92+
Models.SmartSeries9000: ModelDescription(
93+
device_type="Smart Series 9000",
94+
modes=SMART_SERIES_MODES,
9295
),
9396
}
9497

@@ -102,6 +105,7 @@ class ModelDescription:
102105
5: "setup",
103106
6: "flight menu",
104107
8: "selection menu",
108+
9: "off",
105109
113: "final test",
106110
114: "pcb test",
107111
115: "sleeping",
@@ -138,7 +142,7 @@ def _process_mfr_data(
138142
data: bytes,
139143
) -> None:
140144
"""Parser for OralB sensors."""
141-
_LOGGER.debug("Parsing OralB sensor: %s", data)
145+
_LOGGER.debug("Parsing Oral-B sensor: %s", data)
142146
msg_length = len(data)
143147
if msg_length != 11:
144148
return
@@ -155,6 +159,8 @@ def _process_mfr_data(
155159
model = Models.IOSeries7
156160
elif device_bytes == b"\x074\x0c":
157161
model = Models.IOSeries4
162+
elif device_bytes == b"\x03!\x0c":
163+
model = Models.SmartSeries9000
158164
else:
159165
model = Models.SmartSeries7000
160166

tests/test_parser.py

+124
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@
7171
service_data={},
7272
source="local",
7373
)
74+
ORALB_9000_SERIES = BluetoothServiceInfo(
75+
address="78:DB:2F:C2:48:BE",
76+
rssi=-63,
77+
name="9000",
78+
manufacturer_data={220: b"\x03!\x0c\x020\x00\x06\x01\x01\x14\x04"},
79+
service_uuids=[],
80+
service_data={},
81+
source="local",
82+
)
7483

7584

7685
def test_can_create():
@@ -765,3 +774,118 @@ def test_io_series_4():
765774
},
766775
events={},
767776
)
777+
778+
779+
def test_9000_series():
780+
parser = OralBBluetoothDeviceData()
781+
service_info = ORALB_9000_SERIES
782+
result = parser.update(service_info)
783+
assert result == SensorUpdate(
784+
title="Smart Series 9000 48BE",
785+
devices={
786+
None: SensorDeviceInfo(
787+
name="Smart Series 9000 48BE",
788+
model="Smart Series 9000",
789+
manufacturer="Oral-B",
790+
sw_version=None,
791+
hw_version=None,
792+
)
793+
},
794+
entity_descriptions={
795+
DeviceKey(key="sector_timer", device_id=None): SensorDescription(
796+
device_key=DeviceKey(key="sector_timer", device_id=None),
797+
device_class=None,
798+
native_unit_of_measurement=None,
799+
),
800+
DeviceKey(key="mode", device_id=None): SensorDescription(
801+
device_key=DeviceKey(key="mode", device_id=None),
802+
device_class=None,
803+
native_unit_of_measurement=None,
804+
),
805+
DeviceKey(key="toothbrush_state", device_id=None): SensorDescription(
806+
device_key=DeviceKey(key="toothbrush_state", device_id=None),
807+
device_class=None,
808+
native_unit_of_measurement=None,
809+
),
810+
DeviceKey(key="time", device_id=None): SensorDescription(
811+
device_key=DeviceKey(key="time", device_id=None),
812+
device_class=None,
813+
native_unit_of_measurement=None,
814+
),
815+
DeviceKey(key="number_of_sectors", device_id=None): SensorDescription(
816+
device_key=DeviceKey(key="number_of_sectors", device_id=None),
817+
device_class=None,
818+
native_unit_of_measurement=None,
819+
),
820+
DeviceKey(key="sector", device_id=None): SensorDescription(
821+
device_key=DeviceKey(key="sector", device_id=None),
822+
device_class=None,
823+
native_unit_of_measurement=None,
824+
),
825+
DeviceKey(key="pressure", device_id=None): SensorDescription(
826+
device_key=DeviceKey(key="pressure", device_id=None),
827+
device_class=None,
828+
native_unit_of_measurement=None,
829+
),
830+
DeviceKey(key="signal_strength", device_id=None): SensorDescription(
831+
device_key=DeviceKey(key="signal_strength", device_id=None),
832+
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
833+
native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
834+
),
835+
},
836+
entity_values={
837+
DeviceKey(key="sector_timer", device_id=None): SensorValue(
838+
device_key=DeviceKey(key="sector_timer", device_id=None),
839+
name="Sector " "Timer",
840+
native_value=20,
841+
),
842+
DeviceKey(key="mode", device_id=None): SensorValue(
843+
device_key=DeviceKey(key="mode", device_id=None),
844+
name="Mode",
845+
native_value="daily " "clean",
846+
),
847+
DeviceKey(key="toothbrush_state", device_id=None): SensorValue(
848+
device_key=DeviceKey(key="toothbrush_state", device_id=None),
849+
name="Toothbrush " "State",
850+
native_value="idle",
851+
),
852+
DeviceKey(key="time", device_id=None): SensorValue(
853+
device_key=DeviceKey(key="time", device_id=None),
854+
name="Time",
855+
native_value=6,
856+
),
857+
DeviceKey(key="number_of_sectors", device_id=None): SensorValue(
858+
device_key=DeviceKey(key="number_of_sectors", device_id=None),
859+
name="Number " "of " "sectors",
860+
native_value=4,
861+
),
862+
DeviceKey(key="sector", device_id=None): SensorValue(
863+
device_key=DeviceKey(key="sector", device_id=None),
864+
name="Sector",
865+
native_value="sector " "1",
866+
),
867+
DeviceKey(key="pressure", device_id=None): SensorValue(
868+
device_key=DeviceKey(key="pressure", device_id=None),
869+
name="Pressure",
870+
native_value="unknown " "pressure " "48",
871+
),
872+
DeviceKey(key="signal_strength", device_id=None): SensorValue(
873+
device_key=DeviceKey(key="signal_strength", device_id=None),
874+
name="Signal " "Strength",
875+
native_value=-63,
876+
),
877+
},
878+
binary_entity_descriptions={
879+
DeviceKey(key="brushing", device_id=None): BinarySensorDescription(
880+
device_key=DeviceKey(key="brushing", device_id=None), device_class=None
881+
)
882+
},
883+
binary_entity_values={
884+
DeviceKey(key="brushing", device_id=None): BinarySensorValue(
885+
device_key=DeviceKey(key="brushing", device_id=None),
886+
name="Brushing",
887+
native_value=False,
888+
)
889+
},
890+
events={},
891+
)

0 commit comments

Comments
 (0)