def test_name(self): """Check reading of the sensor name.""" poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.name = 'my sensor name' self.assertEqual(backend.name, poller.name())
def test_read_battery(self): """Test reading the battery level.""" poller = MiThermometerPoller(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))
def test_no_answer_version(self): """Sensor returns None for handle 0x03. Check that this triggers the right exception. """ poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.handle_0x38_raw = None with self.assertRaises(BluetoothBackendException): poller.name()
def test_no_answer_data(self): """Sensor returns None for handle 0x35. Check that this triggers the right exception. """ poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.handle_0x35_raw = None with self.assertRaises(BluetoothBackendException): poller.parameter_value(MI_TEMPERATURE)
def test_invalid_data(self): """Check if reading of the data fails, when invalid data is received. Try this with a new version number. """ poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.override_read_handles[HANDLE_READ_SENSOR_DATA] = INVALID_DATA with self.assertRaises(BluetoothBackendException): poller.parameter_value(MI_TEMPERATURE)
def test_rw_exception(self): """Test reaction when getting a BluetoothBackendException.""" poller = MiThermometerPoller(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_HUMIDITY) with self.assertRaises(BluetoothBackendException): poller.parameter_value(MI_HUMIDITY)
def test_parsing(self): """Does the Mi Thermometer data parser works correctly?""" poller = MiThermometerPoller(None, MockBackend) data = bytes('T=29.3 H=40.3 ', 'utf-8') poller._cache = data poller._last_read = datetime.now() self.assertEqual(poller._parse_data()[MI_TEMPERATURE], 29.3) self.assertEqual(poller._parse_data()[MI_HUMIDITY], 40.3) data = bytes('T=24.2 H=45.3 ', 'utf-8') poller._cache = data poller._last_read = datetime.now() self.assertEqual(poller._parse_data()[MI_TEMPERATURE], 24.2) self.assertEqual(poller._parse_data()[MI_HUMIDITY], 45.3)
def test_read_measurements(self): """Test reading data from new sensors. Here we expect some data being written to the sensor. """ poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.temperature = 56.7 backend.humidity = 0.0 self.assertAlmostEqual(backend.temperature, poller.parameter_value(MI_TEMPERATURE), delta=0.11)
def _setup(self): from mithermometer.mithermometer_poller import MiThermometerPoller from btlewrap.bluepy import BluepyBackend _LOGGER.info("Adding %d %s devices", len(self.devices), repr(self)) for name, mac in self.devices.items(): _LOGGER.debug("Adding %s device '%s' (%s)", repr(self), name, mac) self.devices[name] = {"mac":mac, "poller": MiThermometerPoller(mac, BluepyBackend)}
def init_sensors(sensor_type, sensors): sensor_type_name = sensor_type_to_name(sensor_type) if sensor_type == sensor_type_miflora: config_section = sensor_type_miflora mac_regexp = "C4:7C:8D:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}" elif sensor_type == sensor_type_mitempbt: config_section = sensor_type_mitempbt mac_regexp = "[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}" else: print_line('Unknown device type: {}'.format(sensor_type), error=True, sd_notify=True) sys.exit(1) for [name, mac] in config[config_section].items(): if not re.match(mac_regexp, mac): print_line('The MAC address "{}" seems to be in the wrong format. Please check your configuration'.format(mac), error=True, sd_notify=True) sys.exit(1) if '@' in name: name_pretty, location_pretty = name.split('@') else: name_pretty, location_pretty = name, '' name_clean = clean_identifier(name_pretty) location_clean = clean_identifier(location_pretty) sensor = dict() print('Adding sensor to device list and testing connection ...') print('Name: "{}"'.format(name_pretty)) #print_line('Attempting initial connection to Mi Flora sensor "{}" ({})'.format(name_pretty, mac), console=False, sd_notify=True) if sensor_type == sensor_type_miflora: sensor_poller = MiFloraPoller(mac=mac, backend=BluepyBackend, cache_timeout=miflora_cache_timeout, retries=3, adapter=used_adapter) elif sensor_type == sensor_type_mitempbt: sensor_poller = MiThermometerPoller(mac=mac, backend=BluepyBackend, cache_timeout=mitempbt_cache_timeout, retries=3, adapter=used_adapter) sensor['poller'] = sensor_poller sensor['name_pretty'] = name_pretty sensor['mac'] = sensor_poller._mac sensor['refresh'] = miflora_sleep_period if (sensor_type == sensor_type_miflora) else mitempbt_sleep_period sensor['location_clean'] = location_clean sensor['location_pretty'] = location_pretty sensor['stats'] = {"count": 0, "success": 0, "failure": 0} try: sensor_poller.fill_cache() sensor_poller.parameter_value(MI_BATTERY) sensor['firmware'] = sensor_poller.firmware_version() except (IOError, BluetoothBackendException, BTLEException, RuntimeError, BrokenPipeError): print_line('Initial connection to {} sensor "{}" ({}) failed.'.format(sensor_type_name, name_pretty, mac), error=True, sd_notify=True) else: print('Internal name: "{}"'.format(name_clean)) print('Device name: "{}"'.format(sensor_poller.name())) print('MAC address: {}'.format(sensor_poller._mac)) print('Firmware: {}'.format(sensor_poller.firmware_version())) print_line('Initial connection to {} sensor "{}" ({}) successful'.format(sensor_type_name, name_pretty, mac), sd_notify=True) print() sensors[name_clean] = sensor
def poll(args): """Poll data from the sensor.""" backend = _get_backend(args) poller = MiThermometerPoller(args.mac, backend) print("Getting data from Mi Flora") print("FW: {}".format(poller.firmware_version())) print("Name: {}".format(poller.name())) print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE))) print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY))) print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
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 = MiThermometerPoller(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))
def test_clear_cache(self): """Test with negative temperature.""" poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) self.assertFalse(poller.cache_available()) backend.temperature = 1.0 backend.humidity = 0.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 backend.humidity = 0.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 backend.humidity = 0.0 self.assertAlmostEqual(3.0, poller.parameter_value(MI_TEMPERATURE), delta=0.01) self.assertTrue(poller.cache_available())
def test_read_version(self): """Test reading the version number.""" poller = MiThermometerPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.set_version(1, 2, 3) self.assertEqual('1.2.3', poller.firmware_version())
def test_format_bytes(self): """Test conversion of bytes to string.""" self.assertEqual('AA BB 00', MiThermometerPoller._format_bytes([0xAA, 0xBB, 0x00]))
def _setup(self): from mithermometer.mithermometer_poller import MiThermometerPoller from btlewrap.bluepy import BluepyBackend for name, mac in self.devices.items(): self.devices[name] = MiThermometerPoller(mac, BluepyBackend)