diff --git a/custom_components/govee_ble_hci/ble_ht.py b/custom_components/govee_ble_hci/ble_ht.py index 6ac7066..6c5baeb 100644 --- a/custom_components/govee_ble_hci/ble_ht.py +++ b/custom_components/govee_ble_hci/ble_ht.py @@ -33,14 +33,21 @@ class BLE_HT_data: _log_spikes: bool _min_temp: float _max_temp: float + _sensor_number: Optional[int] - def __init__(self, mac: str, description: Optional[str]) -> None: + def __init__( + self, + mac: str, + description: Optional[str], + sensor_number: Optional[int] + ) -> None: """Init.""" self._mac = mac self._desc = description self._log_spikes = False self._min_temp = DEFAULT_TEMP_RANGE_MIN self._max_temp = DEFAULT_TEMP_RANGE_MAX + self._sensor_number = sensor_number self.reset() @property @@ -181,6 +188,10 @@ def median_humidity(self) -> Union[float, None]: except (AssertionError, sts.StatisticsError): return None + @property + def sensor_number(self) -> int: + return self._sensor_number + def update( self, temperature: Optional[float], diff --git a/custom_components/govee_ble_hci/const.py b/custom_components/govee_ble_hci/const.py index be6bf00..12a5e0d 100644 --- a/custom_components/govee_ble_hci/const.py +++ b/custom_components/govee_ble_hci/const.py @@ -6,6 +6,7 @@ CONF_DECIMALS = "decimals" CONF_DEVICE_MAC = "mac" CONF_DEVICE_NAME = "name" +CONF_DEVICE_SENSOR_NUMBER = "sensor_number" CONF_GOVEE_DEVICES = "govee_devices" CONF_HCI_DEVICE = "hci_device" CONF_LOG_SPIKES = "log_spikes" diff --git a/custom_components/govee_ble_hci/govee_advertisement.py b/custom_components/govee_ble_hci/govee_advertisement.py index 17201b1..a069c22 100644 --- a/custom_components/govee_ble_hci/govee_advertisement.py +++ b/custom_components/govee_ble_hci/govee_advertisement.py @@ -66,6 +66,7 @@ def __init__(self, data: bytes): self.rssi = rssi_from_byte(data[-1]) self.raw_data = data[10:-1] self.flags = 6 + self.sensor_number = 0 self.name = None self.packet = None self.temperature = None @@ -113,6 +114,14 @@ def __init__(self, data: bytes): self.humidity = float((self.packet % 1000) / 10) self.battery = int(self.mfg_data[7]) self.model = "Govee H5101/H5102" + elif self.check_is_gvh5178(): + mfg_data_5075 = hex_string(self.mfg_data[5:8]).replace(" ", "") + self.packet = int(mfg_data_5075, 16) + self.temperature = decode_temps(self.packet) + self.humidity = float((self.packet % 1000) / 10) + self.battery = int(self.mfg_data[8]) + self.sensor_number = int(self.mfg_data[4]) + self.model = "Govee H5178" elif self.check_is_gvh5179(): temp, hum, batt = unpack_from(" bool: """Check if mfg data is that of Govee H5051.""" return self._mfg_data_check(11, 6) + def check_is_gvh5178(self) -> bool: + """Check if mfg data is that of Govee H5178.""" + return self._mfg_data_check(11, 5) + def check_is_gvh5179(self) -> bool: """Check if mfg data is that of Govee H5179.""" return self._mfg_data_check(11, 6) and self._mfg_data_id_check("0188") diff --git a/custom_components/govee_ble_hci/sensor.py b/custom_components/govee_ble_hci/sensor.py index 6783f6e..d729f4c 100644 --- a/custom_components/govee_ble_hci/sensor.py +++ b/custom_components/govee_ble_hci/sensor.py @@ -27,6 +27,7 @@ CONF_DECIMALS, CONF_DEVICE_MAC, CONF_DEVICE_NAME, + CONF_DEVICE_SENSOR_NUMBER, CONF_GOVEE_DEVICES, CONF_HCI_DEVICE, CONF_LOG_SPIKES, @@ -57,6 +58,7 @@ { vol.Optional(CONF_DEVICE_MAC): cv.string, vol.Optional(CONF_DEVICE_NAME): cv.string, + vol.Optional(CONF_DEVICE_SENSOR_NUMBER): int, } ) @@ -89,7 +91,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None) -> None: _LOGGER.debug("Starting Govee HCI Sensor") govee_devices: List[BLE_HT_data] = [] # Data objects of configured devices - sensors_by_mac = {} # HomeAssistant sensors by MAC address + sensors_by_device = {} # HomeAssistant sensors by their BLE_HT_data device adapter = None def handle_meta_event(hci_packet) -> None: @@ -109,6 +111,10 @@ def handle_meta_event(hci_packet) -> None: # parse packet data ga = GoveeAdvertisement(hci_packet.data) + # Check to make sure sensor numbers match + if ga.sensor_number != device.sensor_number: + continue + # If mfg data information is defined, update values if ga.packet is not None: device.update(ga.temperature, ga.humidity, ga.packet) @@ -123,8 +129,9 @@ def init_configureed_devices() -> None: # Initialize BLE HT data objects mac: str = conf_dev["mac"] given_name = conf_dev.get("name", None) + sensor_number = conf_dev.get("sensor_number", 0) - device = BLE_HT_data(mac, given_name) + device = BLE_HT_data(mac, given_name, sensor_number) device.log_spikes = config[CONF_LOG_SPIKES] device.maximum_temperature = config[CONF_TEMP_RANGE_MAX_CELSIUS] device.minimum_temperature = config[CONF_TEMP_RANGE_MIN_CELSIUS] @@ -135,10 +142,10 @@ def init_configureed_devices() -> None: # Initialize HA sensors name = conf_dev.get("name", mac) - temp_sensor = TemperatureSensor(mac, name) - hum_sensor = HumiditySensor(mac, name) + temp_sensor = TemperatureSensor(mac, name, sensor_number) + hum_sensor = HumiditySensor(mac, name, sensor_number) sensors = [temp_sensor, hum_sensor] - sensors_by_mac[mac] = sensors + sensors_by_device[device] = sensors add_entities(sensors) def update_ble_devices(config) -> None: @@ -150,7 +157,7 @@ def update_ble_devices(config) -> None: textattr = "last median of" if use_median else "last mean of" for device in govee_devices: - sensors = sensors_by_mac[device.mac] + sensors = sensors_by_device[device] _LOGGER.debug( "Last mfg data for {}: {}".format( @@ -242,11 +249,11 @@ def update_ble_loop(now) -> None: class TemperatureSensor(Entity): """Representation of a sensor.""" - def __init__(self, mac: str, name: str): + def __init__(self, mac: str, name: str, sensor_number: int): """Initialize the sensor.""" self._state = None self._battery = None - self._unique_id = "t_" + mac.replace(":", "") + self._unique_id = "t_{}_{}".format(mac.replace(":", ""), sensor_number) self._name = name self._mac = mac.replace(":", "") self._device_state_attributes = {} @@ -307,12 +314,12 @@ def force_update(self) -> bool: class HumiditySensor(Entity): """Representation of a Sensor.""" - def __init__(self, mac: str, name: str): + def __init__(self, mac: str, name: str, sensor_number: int): """Initialize the sensor.""" self._state = None self._battery = None self._name = name - self._unique_id = "h_" + mac.replace(":", "") + self._unique_id = "h_{}_{}".format(mac.replace(":", ""), sensor_number) self._mac = mac.replace(":", "") self._device_state_attributes = {}