コード例 #1
0
    def SendInfluxMIthermo(cls, InfluxDBClient, MAC):

        print("thermo: " + MAC)
        pollerTemp = MiTempBtPoller(MAC,
                                    BluepyBackend,
                                    retries=1,
                                    cache_timeout=30)
        try:
            Thermo = [{
                "measurement": "Thermo",
                "fields": {
                    "Battery": (pollerTemp.parameter_value(MI_BATTERY)),
                    "Temperature":
                    (pollerTemp.parameter_value(MI_TEMPERATURE)),
                    "Humidity": (pollerTemp.parameter_value(MI_HUMIDITY))
                }
            }]
            cls.client.write_points(Thermo)
        except BTLEException as e:
            print(datetime.datetime.now(),
                  "Error connecting to device: error {}".format(e))
        except BrokenPipeError as e:
            print("BrokenPipeError Thermo")
        except Exception as e:
            #availability = 'offline'
            print(
                datetime.datetime.now(),
                "Error polling device. Device might be unreachable or offline."
            )

        pollerTemp.clear_cache()
コード例 #2
0
    def test_clear_cache(self):
        """Test with negative temperature."""
        poller = MiTempBtPoller(self.TEST_MAC, MockBackend)
        backend = self._get_backend(poller)

        self.assertFalse(poller.cache_available())
        backend.temperature = 1.0
        self.assertAlmostEqual(1.0,
                               poller.parameter_value(MI_TEMPERATURE),
                               delta=0.01)
        self.assertTrue(poller.cache_available())

        # data is taken from cache, new value is ignored
        backend.temperature = 2.0
        self.assertAlmostEqual(1.0,
                               poller.parameter_value(MI_TEMPERATURE),
                               delta=0.01)

        self.assertTrue(poller.cache_available())
        poller.clear_cache()
        self.assertFalse(poller.cache_available())

        backend.temperature = 3.0
        self.assertAlmostEqual(3.0,
                               poller.parameter_value(MI_TEMPERATURE),
                               delta=0.01)
        self.assertTrue(poller.cache_available())
コード例 #3
0
def readVal():
    #print("Polling...")
    for device in devices :
        try:
            print("Polling from "+device["mac"]+" of type "+device["type"])
            """Poll data from the sensor."""
            if (device["type"] == "MJ_HT_V1") :
                poller = MiTempBtPoller(device["mac"], GatttoolBackend, retries=1)
                #print("Getting data from Mi Temperature and Humidity Sensor")
                #print("FW: {}".format(poller.firmware_version()))
                #print("Name: {}".format(poller.name()))
                print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
                temperature = float(poller.parameter_value(MI_TEMPERATURE))
                print("Temperature: "+str(temperature))
                blynk.virtual_write(device["temperature"], temperature)
                humidity = float(poller.parameter_value(MI_HUMIDITY))
                print("Humidity: "+str(humidity))
                blynk.virtual_write(device["humidity"], humidity)
            if (device["type"] == "LYWSD02") :
                client = Lywsd02Client(device["mac"])
                print("Battery: {}".format(client.battery))
                temperature = float(client.temperature)
                print("Temperature: "+str(temperature))
                blynk.virtual_write(device["temperature"], temperature)
                humidity = float(client.humidity)
                print("Humidity: "+str(humidity))
                blynk.virtual_write(device["humidity"], humidity)
        except Exception as e:
            print (e)
コード例 #4
0
def poll():
    """Poll data from the sensor."""
    backend = BluepyBackend
    poller = MiTempBtPoller("4c:65:a8:d1:da:d9", backend)
    print("Getting data from Mi Temperature and Humidity Sensor")
    print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))

    filename = round(time.time())

    while True:
        try:
            row = {}
            time_now = datetime.now()
            t = poller.parameter_value(MI_TEMPERATURE)

            row['time'] = time_now
            row['t'] = t
            print(row)
            with open(f'{filename}.csv', 'a') as csv_file:
                writer = csv.DictWriter(csv_file,
                                        delimiter=";",
                                        fieldnames=['time', 't'],
                                        lineterminator='\n')
                writer.writerow(row)
            time.sleep(10)
        except:
            print('Sensor is not available')
コード例 #5
0
    def sensor_output_to_db(self, *args):
        """
         Leest gegevens van de sensor zendt de gegevens naar een SQL-server.
        """
        for i in args:
            self.pi.write(self.led_read, 1)
            poller = MiTempBtPoller(i, BluepyBackend)
            humidity = poller.parameter_value(MI_HUMIDITY)
            battery = poller.parameter_value(MI_BATTERY)
            temprature = poller.parameter_value(MI_TEMPERATURE)
            self.pi.write(self.led_read, 0)
            for i in range(0, 5):
                self.pi.write(self.led_read, 1)
                time.sleep(0.1)
                self.pi.write(self.led_read, 0)
                time.sleep(0.1)

            if i == "4c:65:a8:d0:8e:35":
                sql = """INSERT INTO Sesnor_35(
                timestamp,
                temprature,
                humidity,
                battery
                )
                VALUES (%s, %s, %s, %s )
                """
            if i == "58:2d:34:36:a8:16":
                sql = """INSERT INTO Sesnor_16(
                timestamp,
                temprature,
                humidity,
                battery
                )
                VALUES (%s, %s, %s, %s )
                 """
            if i == "4c:65:a8:d0:96:f5":
                sql = """INSERT INTO Sesnor_f5(
                timestamp,
                temprature,
                humidity,
                battery
                )
                VALUES (%s, %s, %s, %s )
                """

            ts = time.time()
            timestamp = datetime.datetime.utcfromtimestamp(ts).strftime(
                '%Y-%m-%d %H:%M:%S')
            recordTuple = (timestamp, temprature, humidity, battery)
            try:
                self.sql_cursor.execute(sql, recordTuple)
                self.my_db.commit()
                print(i)
                print("Gesendet")
            except:
                self.my_db.rollback()
                print("Error")
コード例 #6
0
def poll(args):
    """Poll data from the sensor."""
    backend = _get_backend(args)
    poller = MiTempBtPoller(args.mac, backend)
    print("Getting data from Mi Temperature and Humidity Sensor")
    print("FW: {}".format(poller.firmware_version()))
    print("Name: {}".format(poller.name()))
    print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))
コード例 #7
0
    def test_no_answer_data(self):
        """Sensor returns None for handle 0x35.

        Check that this triggers the right exception.
        """
        poller = MiTempBtPoller(self.TEST_MAC, MockBackend)
        backend = self._get_backend(poller)
        backend.handle_0x0010_raw = None
        with self.assertRaises(BluetoothBackendException):
            poller.parameter_value(MI_TEMPERATURE)
コード例 #8
0
 def test_rw_exception(self):
     """Test reaction when getting a BluetoothBackendException."""
     poller = MiTempBtPoller(self.TEST_MAC, RWExceptionBackend, retries=0)
     with self.assertRaises(BluetoothBackendException):
         poller.firmware_version()
     with self.assertRaises(BluetoothBackendException):
         poller.name()
     with self.assertRaises(BluetoothBackendException):
         poller.parameter_value(MI_TEMPERATURE)
     with self.assertRaises(BluetoothBackendException):
         poller.parameter_value(MI_HUMIDITY)
コード例 #9
0
def getXiaomiData(mac, device_name):
    print("Getting data from %s/%s..." % (mac, device_name))
    poller = MiTempBtPoller(mac, BluepyBackend)
    poller.fill_cache()
    temperature = poller.parameter_value('temperature', False)
    humidity = poller.parameter_value('humidity', False)
    print("Found data (%s/%s): Temperature=%s, Humidity=%s" %
          (mac, device_name, temperature, humidity))
    mqttPutMetric("ble/%s/humidity" % device_name, humidity)
    mqttPutMetric("ble/%s/temperature" % device_name, temperature)
    print("")
コード例 #10
0
def poll():
    """Poll data from the sensor."""
    global mac_address
    backend = BluepyBackend
    poller = MiTempBtPoller(mac_address, backend)
    print("Getting data from Mi Temperature and Humidity Sensor")
    print("FW: {}".format(poller.firmware_version()))
    print("Name: {}".format(poller.name()))
    print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))
コード例 #11
0
 def get(self, mac_address):
     try:
         # Getting data from Mi Temperature and Humidity Sensor
         poller = MiTempBtPoller(mac_address, BluepyBackend)
         return {
             'battery': poller.parameter_value(MI_BATTERY),
             'temperature': poller.parameter_value(MI_TEMPERATURE),
             'humidity': poller.parameter_value(MI_HUMIDITY)
         }
     except BluetoothBackendException:
         self.logger.error('Cannot get sensor data for: ' + mac_address)
         return None
コード例 #12
0
ファイル: demo.py プロジェクト: UrielCh/mitemp2prometheus
def poll(args):
    """Poll data from the sensor."""
    backend = _get_backend(args)
    poller = MiTempBtPoller(args.mac, backend)
    data = {
        "mac": poller._mac,
        "name": poller.name(),
        "version": poller.firmware_version(),
        "battery": poller.parameter_value(MI_BATTERY),
        "temperature": poller.parameter_value(MI_TEMPERATURE),
        "humidity": poller.parameter_value(MI_HUMIDITY)
    }
    print(json.dumps(data))
コード例 #13
0
def pollData(position, mac):
    try:
        poller = MiTempBtPoller(mac, BluepyBackend)
        t = poller.parameter_value(MI_TEMPERATURE)
        h = poller.parameter_value(MI_HUMIDITY)
        b = poller.parameter_value(MI_BATTERY)
        print(f'Temperature {t} | Humidity {h}')
        g_temp.labels(position).set(t)
        g_humidity.labels(position).set(h)
        g_battery.labels(position).set(b)
    except:
        print('Unable to read data')
        c_error.labels(position).inc(1)
コード例 #14
0
ファイル: test_everything.py プロジェクト: vnastis/mitemp
    def test_everything(self):
        """Test reading data from a sensor

        This check if we can successfully get some data from a real sensor. This test requires bluetooth hardware and a
        real sensor close by.
        """
        assert hasattr(self, "mac")
        poller = MiTempBtPoller(self.mac, self.backend_type)
        self.assertIsNotNone(poller.firmware_version())
        self.assertIsNotNone(poller.name())
        self.assertIsNotNone(poller.parameter_value(MI_TEMPERATURE))
        self.assertIsNotNone(poller.parameter_value(MI_HUMIDITY))
        self.assertIsNotNone(poller.parameter_value(MI_BATTERY))
コード例 #15
0
def poll_sensor(mac, location_id):
    attempts = 0
    while attempts < 5:
        try:
            poller = MiTempBtPoller(mac, BluepyBackend)
            t = poller.parameter_value(MI_TEMPERATURE, read_cached=False)
            h = poller.parameter_value(MI_HUMIDITY, read_cached=False)
            now = datetime.datetime.now()
            Record(temperature=t, humidity=h, date=now,
                   location=location_id).save()
            break
        except BluetoothBackendException:
            time.sleep(10)
            attempts += 1
コード例 #16
0
def retrieve_temp():
    global mac_address
    backend = BluepyBackend
    poller = MiTempBtPoller(mac_address, backend)

    temp = poller.parameter_value(MI_TEMPERATURE)
    return temp
コード例 #17
0
    def poll_device(cls, device):
        """
        Poll a particular device for measurements

        args:
            - dict
        returns:
            dict
        """
        
        data = {
            'name': device['name'],
            'address': device['address'],
            'measurements': {},
        }

        readings = {
            'temperature': mitemp_bt.mitemp_bt_poller.MI_TEMPERATURE,
            'humidity': mitemp_bt.mitemp_bt_poller.MI_HUMIDITY,
            'battery': mitemp_bt.mitemp_bt_poller.MI_BATTERY
        }

        try:
            poller = MiTempBtPoller(device['address'], BluepyBackend)
            for key, code in readings.items():
                value = poller.parameter_value(code)
                if value is not None:
                    data['measurements'][key] = value
        except Exception:
            logger.exception("Failed to poll device {}".format(device))

        if len(data['measurements']):
            return data
        else:
            return None
コード例 #18
0
def retrieve_humidity():
    global mac_address
    backend = BluepyBackend
    poller = MiTempBtPoller(mac_address, backend)

    humidity = poller.parameter_value(MI_HUMIDITY)
    return humidity
コード例 #19
0
 def test_read_battery(self):
     """Test reading the battery level."""
     poller = MiTempBtPoller(self.TEST_MAC, MockBackend)
     backend = self._get_backend(poller)
     backend.battery_level = 50
     self.assertEqual(50, poller.battery_level())
     self.assertEqual(50, poller.parameter_value(MI_BATTERY))
     self.assertEqual(0, len(backend.written_handles))
コード例 #20
0
ファイル: mitemp.py プロジェクト: jussike/kuappi
class MiTemp(AbstractSensor):
    def __init__(self):
        cache_timeout = CONFIG.get('mitemp_cache_timeout', 300)
        self.poller = MiTempBtPoller(CONFIG.get('mitemp_addr'), BluepyBackend, cache_timeout=cache_timeout, retries=10)

    def _read_data(self):
        temp = None
        hum = None
        while temp is None or hum is None:
            try:
                temp = self.poller.parameter_value(TEMP)
                hum = self.poller.parameter_value(HUM)
            except Exception:
                logging.exception('Failed to read temp')
        return {TEMP: temp,
                HUM: hum}

    def get_data(self):
        return self._read_data()
コード例 #21
0
    def SendInfluxMIthermo(cls, InfluxDBClient, MAC):

        print("thermo: " + MAC)
        for A in range(cls.NofDongles):
            myadapter = 'hci' + str(A)
            print("Polling with: " + myadapter)
            if not cls.ImPolling:
                return

            try:
                pollerTemp = MiTempBtPoller(MAC,
                                            BluepyBackend,
                                            retries=1,
                                            cache_timeout=30,
                                            adapter=myadapter)
                if not cls.ImPolling:
                    return
                Thermo = [{
                    "measurement": "Thermo",
                    "fields": {
                        "Battery": (pollerTemp.parameter_value(MI_BATTERY)),
                        "Temperature":
                        (pollerTemp.parameter_value(MI_TEMPERATURE)),
                        "Humidity": (pollerTemp.parameter_value(MI_HUMIDITY))
                    },
                    "timestamp": time.time()
                }]
                if cls.client.write_points(Thermo):
                    break
            except BTLEException as e:
                print(datetime.datetime.now(),
                      "Error connecting to device: error {}".format(e))
            except BrokenPipeError as e:
                print("BrokenPipeError Thermo")
            except Exception as e:
                #availability = 'offline'
                print(
                    datetime.datetime.now(),
                    "Error polling device. Device might be unreachable or offline."
                )

        pollerTemp.clear_cache()
コード例 #22
0
def poll(args):
    print("Poll data from the sensor")

    url = 'http://localhost:8080/sr/healthcheck'
    response = requests.get(url)
    print(response.text)
    backend = _get_backend(args)

    while True:
        print("Getting data from Mi Temperature and Humidity Sensor")
        poller = MiTempBtPoller(args.mac, backend)
        temperature = poller.parameter_value(MI_TEMPERATURE)
        humidity = poller.parameter_value(MI_HUMIDITY)
        print("Data polled: " + str(temperature) + " / " + str(humidity))
        url = 'http://localhost:8080/sr/sensordata/save'
        response = requests.post(url,
                                 data='{"humidity":' + str(humidity) +
                                 ',"temperature":' + str(temperature) + '}',
                                 headers={"Content-Type": "application/json"})
        time.sleep(1800)
コード例 #23
0
ファイル: mi2sheet.py プロジェクト: mtoensing/mi2sheet
def pollData(args):
    """Poll data from the sensor."""
    backend = _get_backend(args)
    poller = MiTempBtPoller(args.mac, backend)

    #print("Getting data from Mi Temperature and Humidity Sensor")
    #print("FW: {}".format(poller.firmware_version()))
    #print("Name: {}".format(poller.name()))
    #print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    #print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    #print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))

    name = format(poller.name())
    battery = format(poller.parameter_value(MI_BATTERY))
    temperature = format(poller.parameter_value(MI_TEMPERATURE))
    humidity = format(poller.parameter_value(MI_HUMIDITY))

    data = [temperature, humidity, battery]
    print(data)
    return data
コード例 #24
0
def poll(args):
    """Poll data from the sensor."""
    while True:
      try:
        backend = _get_backend(args)
        poller = MiTempBtPoller(args.mac, backend)
        currTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        line1 = "Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE))
        line2 = "Humidity: {}".format(poller.parameter_value(MI_HUMIDITY))
        line3 = "Battery: {}".format(poller.parameter_value(MI_BATTERY))
        # print("FW: {}".format(poller.firmware_version()))
        # print("Name: {}".format(poller.name()))
        print(currTime, line1, line2, line3)
        f = open('/home/pi/soft/Home-Automation/src/api/sensor.log', 'w')
        f.write("%s\n%s\n%s\n%s" % (currTime, line1, line2, line3))
        f.close()
        sleep(10)
      except:
        print("An exception occurred") 
    finally:
コード例 #25
0
ファイル: mi2sheet.py プロジェクト: mtoensing/mi2sheet
def poll(args):
    """Poll data from the sensor."""
    backend = _get_backend(args)
    poller = MiTempBtPoller(args.mac, backend)

    #print("Getting data from Mi Temperature and Humidity Sensor")
    #print("FW: {}".format(poller.firmware_version()))
    #print("Name: {}".format(poller.name()))
    #print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    #print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    #print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))

    name = format(poller.name())
    battery = format(poller.parameter_value(MI_BATTERY))
    temperature = format(poller.parameter_value(MI_TEMPERATURE))
    humidity = format(poller.parameter_value(MI_HUMIDITY))

    #print("Compiling this data")
    now = datetime.datetime.now().strftime("%m/%d/%Y %H:%M:%S")
    data = [now, temperature, humidity, battery]
    print(data)
    return data
コード例 #26
0
    def test_read_measurements(self):
        """Test reading data from new sensors.

        Here we expect some data being written to the sensor.
        """
        poller = MiTempBtPoller(self.TEST_MAC, MockBackend)
        backend = self._get_backend(poller)

        backend.temperature = 56.7

        self.assertAlmostEqual(backend.temperature,
                               poller.parameter_value(MI_TEMPERATURE),
                               delta=0.11)
コード例 #27
0
ファイル: demo.py プロジェクト: schrma/mitemp
def main():
    """Main function.

    Mostly parsing the command line arguments.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--backend',
                        choices=['gatttool', 'bluepy', 'pygatt'],
                        default='gatttool')
    parser.add_argument('-v', '--verbose', action='store_const', const=True)
    subparsers = parser.add_subparsers(help='sub-command help', )

    parser_poll = subparsers.add_parser('poll', help='poll data from a sensor')
    parser_poll.add_argument('mac', type=valid_mitemp_mac)
    parser_poll.set_defaults(func=poll)

    # parser_scan = subparsers.add_parser('scan', help='scan for devices')
    # parser_scan.set_defaults(func=scan)

    parser_scan = subparsers.add_parser('backends',
                                        help='list the available backends')
    parser_scan.set_defaults(func=list_backends)

    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    if not hasattr(args, "func"):
        parser.print_help()
        sys.exit(0)

    backend = _get_backend(args)
    try:
        while True:
            poller = MiTempBtPoller(args.mac, backend)
            print("Temperature: {}".format(
                poller.parameter_value(MI_TEMPERATURE)))
            time.sleep(5)
    except KeyboardInterrupt:
        print("Close program")
コード例 #28
0
def poll(mac):
    """Poll data from the sensor."""
    poller = MiTempBtPoller(mac, BluepyBackend)
    print("Getting data from Mi Temperature and Humidity Sensor with MAC: {}".
          format(mac))
    print("FW: {}".format(poller.firmware_version()))
    print("Name: {}".format(poller.name()))
    print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))

    return jsonify(name=poller.name(),
                   firmware=poller.firmware_version(),
                   battery=poller.parameter_value(MI_BATTERY),
                   temperature=poller.parameter_value(MI_TEMPERATURE),
                   humidity=poller.parameter_value(MI_HUMIDITY))
コード例 #29
0
ファイル: mitemp.py プロジェクト: hassiweb/mitemp
def poll(args):
    """Poll data from the sensor."""
    backend = _get_backend(args)
    poller = MiTempBtPoller(args.mac, backend)
    print("Getting data from Mi Temperature and Humidity Sensor")
    print("FW: {}".format(poller.firmware_version()))
    print("Name: {}".format(poller.name()))
    print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))

    dtnow = dt.now(pytz.timezone('Japan'))
    data = { \
                'time': dtnow.strftime('%Y-%m-%dT%H:%M:%S%z'), \
                'mac': args.mac, \
                'battery': poller.parameter_value(MI_BATTERY), \
                'temperature': poller.parameter_value(MI_TEMPERATURE), \
                'humidity': poller.parameter_value(MI_HUMIDITY) \
            }

    data = append_json_to_file(data,
                               args.location + os.sep + args.mac + '.json')
コード例 #30
0
class terrariumMiTempSensor(terrariumSensorSource):
    TYPE = 'mitemp'
    VALID_SENSOR_TYPES = ['temperature', 'humidity']

    __SCANTIME = 5
    __MIN_DB = -90

    def __init__(self,
                 sensor_id,
                 sensor_type,
                 address,
                 name='',
                 callback_indicator=None,
                 adapter=0):
        self.__firmware = None
        self.__battery = None
        self.__adaptor = 'hci{}'.format(adapter)
        self.__sensor_cache = terrariumSensorCache()

        self.__device = None

        super(terrariumMiTempSensor,
              self).__init__(sensor_id, sensor_type, address, name,
                             callback_indicator)

    def load_data(self):
        data = None

        if self.get_address() is not None:
            if self.__device is None:
                try:
                    self.__device = MiTempBtPoller(self.get_address(),
                                                   BluepyBackend,
                                                   60,
                                                   adapter=self.__adaptor)
                except Exception as ex:
                    logger.warning(
                        'Error connecting to {} sensor \'{}\'. Error message: {}'
                        .format(self.get_type(), self.get_name(), ex))

            if self.__device is not None:
                try:
                    #sensor = MiTempBtPoller(self.get_address(), BluepyBackend, 60, adapter=self.__adaptor)

                    data = {}
                    data['temperature'] = self.__device.parameter_value(
                        MI_TEMPERATURE)
                    data['humidity'] = self.__device.parameter_value(
                        MI_HUMIDITY)
                    data['battery'] = self.__device.parameter_value(MI_BATTERY)
                    data['firmware'] = self.__device.firmware_version()

                    #del(sensor)

                except Exception as ex:
                    logger.warning(
                        'Error getting new data from {} sensor \'{}\'. Error message: {}'
                        .format(self.get_type(), self.get_name(), ex))

        return data

    def get_data(self, temperature_type=None):
        data = super(terrariumMiTempSensor, self).get_data(temperature_type)
        data['firmware'] = self.get_firmware()
        data['battery'] = self.get_battery()

        return data

    def get_firmware(self):
        cached_data = self.__sensor_cache.get_sensor_data(
            self.get_sensor_cache_key())
        if cached_data is not None and 'firmware' in cached_data:
            self.__firmware = cached_data['firmware']

        return self.__firmware

    def get_battery(self):
        cached_data = self.__sensor_cache.get_sensor_data(
            self.get_sensor_cache_key())
        if cached_data is not None and 'battery' in cached_data:
            self.__battery = cached_data['battery']

        return self.__battery

    @staticmethod
    def scan_sensors(callback=None):
        # Due to multiple bluetooth dongles, we are looping 10 times to see which devices can scan. Exit after first success
        logger.info(
            'Scanning {} seconds for Mi Temperature and Humidity bluetooth devices'
            .format(terrariumMiTempSensor.__SCANTIME))
        ok = False
        for counter in range(10):
            try:
                for device in Scanner(counter).scan(
                        terrariumMiTempSensor.__SCANTIME):
                    ok = True
                    if device.rssi > terrariumMiTempSensor.__MIN_DB and device.getValueText(
                            9) is not None and device.getValueText(
                                9).lower() in ['mj_ht_v1']:
                        address = device.addr
                        logger.info(
                            'Found Mi Temperature and Humidity bluetooth device at address {}'
                            .format(address))
                        ok = True
                        for sensor_type in terrariumMiTempSensor.VALID_SENSOR_TYPES:
                            yield terrariumMiTempSensor(
                                None,
                                sensor_type,
                                address,
                                callback_indicator=callback,
                                adapter=counter)

                break

            except Exception as ex:
                print('terrariumMiTempSensor exception')
                print(ex)

        if not ok:
            logger.warning(
                'Bluetooth scanning is not enabled for normal users or there are zero Bluetooth LE devices available.... bluetooth is disabled!'
            )