Skip to content

Commit 48725ec

Browse files
authored
Merge pull request #121 from custom-components/custom_names
Sensor names option
2 parents 0783c15 + 281cdfc commit 48725ec

File tree

4 files changed

+115
-48
lines changed

4 files changed

+115
-48
lines changed

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ sensor:
162162
batt_entities: False
163163
encryptors:
164164
'A4:C1:38:2F:86:6C': '217C568CF5D22808DA20181502D84C1B'
165+
sensor_names:
166+
'A4:C1:38:2F:86:6C': 'Livingroom'
165167
report_unknown: False
166168
whitelist: False
167169
```
@@ -230,6 +232,18 @@ Note: The encryptors parameter is only needed for sensors, for which it is [poin
230232
'A4:C1:38:D1:61:7D': 'C99D2313182473B38001086FEBF781BD'
231233
```
232234
235+
#### sensor_names
236+
237+
(dictionary)(Optional) Use this option to link a sensor name to the mac-address of the sensor. Using this option (or changing a name) will create new entities after restarting Home Assistant. These sensors are named with the following convention: `sensor.mi_sensortype_sensor_name` (e.g. `sensor.mi_temperature_livingroom`) in stead of the default `mi_sensortype_mac` (e.g. `sensor.mi_temperature_A4C1382F86C`). You will have to update your lovelace cards, automation and scripts after each change. Note that you can still override the entity_id from the UI. After the change, you can manually delete the old entities from the Developer Tools section. The old data won't be transfered to the new sensor. Default value: Empty
238+
239+
```yaml
240+
sensor:
241+
- platform: mitemp_bt
242+
sensor_names:
243+
'A4:C1:38:2F:86:6C': 'Livingroom'
244+
'A4:C1:38:D1:61:7D': 'Bedroom'
245+
```
246+
233247
#### report_unknown
234248

235249
(boolean)(Optional) This option is needed primarily for those who want to request an implementation of device support that is not in the list of [supported sensors](#supported-sensors). If you set this parameter to `True`, then the component will log all messages from unknown Xiaomi ecosystem devices to the Home Assitant log. **Attention!** Enabling this option can lead to huge output to the Home Assistant log, do not enable it if you do not need it! Details in the [FAQ](https://github.com/custom-components/sensor.mitemp_bt/blob/master/faq.md#my-sensor-from-the-xiaomi-ecosystem-is-not-in-the-list-of-supported-ones-how-to-request-implementation). Default value: False
@@ -247,8 +261,8 @@ Note: The encryptors parameter is only needed for sensors, for which it is [poin
247261
```
248262

249263
Data from sensors with other addresses will be ignored.
250-
In addition, all addresses listed in the `encryptors` option will be automatically whitelisted.
251-
If you have no sensors other than those listed in `encryptors`, then just set `whitelist` to `True`:
264+
In addition, all addresses listed in the `encryptors` and `sensor_names` option will be automatically whitelisted.
265+
If you have no sensors other than those listed in `encryptors` and/or `sensor_names`, then just set `whitelist` to `True`:
252266

253267
```yaml
254268
sensor:

custom_components/mitemp_bt/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
CONF_ENCRYPTORS = "encryptors"
1616
CONF_REPORT_UNKNOWN = "report_unknown"
1717
CONF_WHITELIST = "whitelist"
18+
CONF_SENSOR_NAMES = "sensor_names"
1819

1920
# Default values for configuration options
2021
DEFAULT_ROUNDING = True

custom_components/mitemp_bt/sensor.py

Lines changed: 72 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
CONF_ENCRYPTORS,
5555
CONF_REPORT_UNKNOWN,
5656
CONF_WHITELIST,
57+
CONF_SENSOR_NAMES,
5758
CONF_TMIN,
5859
CONF_TMAX,
5960
CONF_HMIN,
@@ -70,6 +71,12 @@
7071
MAC_REGEX = "(?i)^(?:[0-9A-F]{2}[:]){5}(?:[0-9A-F]{2})$"
7172
AES128KEY_REGEX = "(?i)^[A-F0-9]{32}$"
7273

74+
SENSOR_NAMES_LIST_SCHEMA = vol.Schema(
75+
{
76+
cv.matches_regex(MAC_REGEX): cv.string
77+
}
78+
)
79+
7380
ENCRYPTORS_LIST_SCHEMA = vol.Schema(
7481
{
7582
cv.matches_regex(MAC_REGEX): cv.matches_regex(AES128KEY_REGEX)
@@ -93,6 +100,7 @@
93100
vol.Optional(
94101
CONF_WHITELIST, default=DEFAULT_WHITELIST
95102
): vol.Any(vol.All(cv.ensure_list, [cv.matches_regex(MAC_REGEX)]), cv.boolean),
103+
vol.Optional(CONF_SENSOR_NAMES, default={}): SENSOR_NAMES_LIST_SCHEMA,
96104
}
97105
)
98106

@@ -363,6 +371,16 @@ def parse_raw_message(data, aeskeyslist, whitelist, report_unknown=False):
363371
return result
364372

365373

374+
def sensor_name(config, mac):
375+
"""Set sensor name."""
376+
fmac = ':'.join(mac[i:i+2] for i in range(0, len(mac), 2))
377+
if fmac in config[CONF_SENSOR_NAMES]:
378+
custom_name = config[CONF_SENSOR_NAMES].get(fmac)
379+
_LOGGER.debug("Name of sensor with mac adress %s is set to: %s", fmac, custom_name)
380+
return custom_name
381+
return mac
382+
383+
366384
class BLEScanner:
367385
"""BLE scanner."""
368386

@@ -450,11 +468,15 @@ def lpacket(mac, packet=None):
450468
if config[CONF_WHITELIST] is True:
451469
for mac in config[CONF_ENCRYPTORS]:
452470
whitelist.append(mac)
471+
for mac in config[CONF_SENSOR_NAMES]:
472+
whitelist.append(mac)
453473
if isinstance(config[CONF_WHITELIST], list):
454474
for mac in config[CONF_WHITELIST]:
455475
whitelist.append(mac)
456476
for mac in config[CONF_ENCRYPTORS]:
457477
whitelist.append(mac)
478+
for mac in config[CONF_SENSOR_NAMES]:
479+
whitelist.append(mac)
458480
for i, mac in enumerate(whitelist):
459481
whitelist[i] = bytes.fromhex(reverse_mac(mac.replace(":", "")).lower())
460482
_LOGGER.debug("%s whitelist item(s) loaded.", len(whitelist))
@@ -625,31 +647,31 @@ def discover_ble_devices(config, aeskeyslist, whitelist):
625647
else:
626648
sensors = []
627649
if t_i != 9:
628-
sensors.insert(t_i, TemperatureSensor(mac))
650+
sensors.insert(t_i, TemperatureSensor(config, mac))
629651
if h_i != 9:
630-
sensors.insert(h_i, HumiditySensor(mac))
652+
sensors.insert(h_i, HumiditySensor(config, mac))
631653
if m_i != 9:
632-
sensors.insert(m_i, MoistureSensor(mac))
654+
sensors.insert(m_i, MoistureSensor(config, mac))
633655
if c_i != 9:
634-
sensors.insert(c_i, ConductivitySensor(mac))
656+
sensors.insert(c_i, ConductivitySensor(config, mac))
635657
if i_i != 9:
636-
sensors.insert(i_i, IlluminanceSensor(mac))
658+
sensors.insert(i_i, IlluminanceSensor(config, mac))
637659
if f_i != 9:
638-
sensors.insert(f_i, FormaldehydeSensor(mac))
660+
sensors.insert(f_i, FormaldehydeSensor(confing, mac))
639661
if cn_i != 9:
640-
sensors.insert(cn_i, ConsumableSensor(mac))
662+
sensors.insert(cn_i, ConsumableSensor(config, mac))
641663
try:
642664
setattr(sensors[cn_i], "_cn_name", CN_NAME_DICT[stype[mac]])
643665
except KeyError:
644666
pass
645667
if sw_i != 9:
646-
sensors.insert(sw_i, SwitchBinarySensor(mac))
668+
sensors.insert(sw_i, SwitchBinarySensor(config, mac))
647669
try:
648670
setattr(sensors[sw_i], "_swclass", SW_CLASS_DICT[stype[mac]])
649671
except KeyError:
650672
pass
651673
if config[CONF_BATT_ENTITIES] and (b_i != 9):
652-
sensors.insert(b_i, BatterySensor(mac))
674+
sensors.insert(b_i, BatterySensor(config, mac))
653675
sensors_by_mac[mac] = sensors
654676
add_entities(sensors)
655677
# append joint attributes
@@ -661,6 +683,9 @@ def discover_ble_devices(config, aeskeyslist, whitelist):
661683
sts.mean(rssi[mac])
662684
)
663685
getattr(sensor, "_device_state_attributes")["sensor type"] = stype[mac]
686+
getattr(sensor, "_device_state_attributes")["mac address"] = (
687+
':'.join(mac[i:i+2] for i in range(0, len(mac), 2))
688+
)
664689
if not isinstance(sensor, BatterySensor) and mac in batt:
665690
getattr(sensor, "_device_state_attributes")[
666691
ATTR_BATTERY_LEVEL
@@ -791,18 +816,18 @@ def update_ble(now):
791816

792817
class TemperatureSensor(Entity):
793818
"""Representation of a sensor."""
794-
795-
def __init__(self, mac):
796-
"""Initialize the sensor."""
819+
def __init__(self, config, mac):
820+
"Initialize the sensor."""
797821
self._state = None
798822
self._battery = None
799-
self._unique_id = "t_" + mac
823+
self._sensor_name = sensor_name(config, mac)
824+
self._unique_id = "t_" + sensor_name(config, mac)
800825
self._device_state_attributes = {}
801826

802827
@property
803828
def name(self):
804829
"""Return the name of the sensor."""
805-
return "mi {}".format(self._unique_id)
830+
return "mi temperature {}".format(self._sensor_name)
806831

807832
@property
808833
def state(self):
@@ -843,17 +868,18 @@ def force_update(self):
843868
class HumiditySensor(Entity):
844869
"""Representation of a Sensor."""
845870

846-
def __init__(self, mac):
871+
def __init__(self, config, mac):
847872
"""Initialize the sensor."""
848873
self._state = None
849874
self._battery = None
850-
self._unique_id = "h_" + mac
875+
self._sensor_name = sensor_name(config, mac)
876+
self._unique_id = "h_" + sensor_name(config, mac)
851877
self._device_state_attributes = {}
852878

853879
@property
854880
def name(self):
855881
"""Return the name of the sensor."""
856-
return "mi {}".format(self._unique_id)
882+
return "mi humidity {}".format(self._sensor_name)
857883

858884
@property
859885
def state(self):
@@ -894,17 +920,18 @@ def force_update(self):
894920
class MoistureSensor(Entity):
895921
"""Representation of a Sensor."""
896922

897-
def __init__(self, mac):
923+
def __init__(self, config, mac):
898924
"""Initialize the sensor."""
899925
self._state = None
900926
self._battery = None
901-
self._unique_id = "m_" + mac
927+
self._sensor_name = sensor_name(config, mac)
928+
self._unique_id = "m_" + sensor_name(config, mac)
902929
self._device_state_attributes = {}
903930

904931
@property
905932
def name(self):
906933
"""Return the name of the sensor."""
907-
return "mi {}".format(self._unique_id)
934+
return "mi moisture {}".format(self._sensor_name)
908935

909936
@property
910937
def state(self):
@@ -945,17 +972,18 @@ def force_update(self):
945972
class ConductivitySensor(Entity):
946973
"""Representation of a Sensor."""
947974

948-
def __init__(self, mac):
975+
def __init__(self, config, mac):
949976
"""Initialize the sensor."""
950977
self._state = None
951978
self._battery = None
952-
self._unique_id = "c_" + mac
979+
self._sensor_name = sensor_name(config, mac)
980+
self._unique_id = "c_" + sensor_name(config, mac)
953981
self._device_state_attributes = {}
954982

955983
@property
956984
def name(self):
957985
"""Return the name of the sensor."""
958-
return "mi {}".format(self._unique_id)
986+
return "mi conductivity {}".format(self._sensor_name)
959987

960988
@property
961989
def state(self):
@@ -996,17 +1024,18 @@ def force_update(self):
9961024
class IlluminanceSensor(Entity):
9971025
"""Representation of a Sensor."""
9981026

999-
def __init__(self, mac):
1027+
def __init__(self, config, mac):
10001028
"""Initialize the sensor."""
10011029
self._state = None
10021030
self._battery = None
1003-
self._unique_id = "l_" + mac
1031+
self._sensor_name = sensor_name(config, mac)
1032+
self._unique_id = "l_" + sensor_name(config, mac)
10041033
self._device_state_attributes = {}
10051034

10061035
@property
10071036
def name(self):
10081037
"""Return the name of the sensor."""
1009-
return "mi {}".format(self._unique_id)
1038+
return "mi llluminance {}".format(self._sensor_name)
10101039

10111040
@property
10121041
def state(self):
@@ -1046,17 +1075,18 @@ def force_update(self):
10461075
class FormaldehydeSensor(Entity):
10471076
"""Representation of a Sensor."""
10481077

1049-
def __init__(self, mac):
1078+
def __init__(self, config, mac):
10501079
"""Initialize the sensor."""
10511080
self._state = None
10521081
self._battery = None
1053-
self._unique_id = "f_" + mac
1082+
self._sensor_name = sensor_name(config, mac)
1083+
self._unique_id = "f_" + sensor_name(config, mac)
10541084
self._device_state_attributes = {}
10551085

10561086
@property
10571087
def name(self):
10581088
"""Return the name of the sensor."""
1059-
return "mi {}".format(self._unique_id)
1089+
return "mi formaldehyde {}".format(self._sensor_name)
10601090

10611091
@property
10621092
def state(self):
@@ -1096,16 +1126,17 @@ def force_update(self):
10961126
class BatterySensor(Entity):
10971127
"""Representation of a Sensor."""
10981128

1099-
def __init__(self, mac):
1129+
def __init__(self, config, mac):
11001130
"""Initialize the sensor."""
11011131
self._state = None
1102-
self._unique_id = "batt_" + mac
1132+
self._sensor_name = sensor_name(config, mac)
1133+
self._unique_id = "batt_" + sensor_name(config, mac)
11031134
self._device_state_attributes = {}
11041135

11051136
@property
11061137
def name(self):
11071138
"""Return the name of the sensor."""
1108-
return "mi {}".format(self._unique_id)
1139+
return "mi battery {}".format(self._sensor_name)
11091140

11101141
@property
11111142
def state(self):
@@ -1145,18 +1176,18 @@ def force_update(self):
11451176
class ConsumableSensor(Entity):
11461177
"""Representation of a Sensor."""
11471178

1148-
def __init__(self, mac):
1179+
def __init__(self, config, mac):
11491180
"""Initialize the sensor."""
11501181
self._state = None
11511182
self._battery = None
1152-
self._cn_name = "cn_"
1153-
self._nmac = mac
1183+
self._sensor_name = sensor_name(config, mac)
1184+
self._unique_id = "cn_" + sensor_name(config, mac)
11541185
self._device_state_attributes = {}
11551186

11561187
@property
11571188
def name(self):
11581189
"""Return the name of the sensor."""
1159-
return "mi {}".format(self._cn_name + self._nmac)
1190+
return "mi consumable {}".format(self._sensor_name)
11601191

11611192
@property
11621193
def state(self):
@@ -1186,7 +1217,7 @@ def device_state_attributes(self):
11861217
@property
11871218
def unique_id(self) -> str:
11881219
"""Return a unique ID."""
1189-
return self._cn_name + self._nmac
1220+
return self._unique_id
11901221

11911222
@property
11921223
def force_update(self):
@@ -1196,12 +1227,13 @@ def force_update(self):
11961227
class SwitchBinarySensor(BinarySensorEntity):
11971228
"""Representation of a Sensor."""
11981229

1199-
def __init__(self, mac):
1230+
def __init__(self, config, mac):
12001231
"""Initialize the sensor."""
12011232
self._state = None
12021233
self._swclass = None
12031234
self._battery = None
1204-
self._unique_id = "sw_" + mac
1235+
self._sensor_name = sensor_name(config, mac)
1236+
self._unique_id = "sw_" + sensor_name(config, mac)
12051237
self._device_state_attributes = {}
12061238

12071239
@property
@@ -1212,7 +1244,7 @@ def is_on(self):
12121244
@property
12131245
def name(self):
12141246
"""Return the name of the sensor."""
1215-
return "mi {}".format(self._unique_id)
1247+
return "mi switch {}".format(self._sensor_name)
12161248

12171249
@property
12181250
def state(self):

0 commit comments

Comments
 (0)