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)
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))
def test_read_version(self): """Test reading the version number.""" poller = MiTempBtPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.set_version('00.00.11') self.assertEqual('00.00.11', poller.firmware_version()) self.assertEqual(0, len(backend.written_handles))
def test_no_answer_firmware_version(self): """Sensor returns None for handle 0x03. Check that this triggers the right exception. """ poller = MiTempBtPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.handle_0x0024_raw = None self.assertTrue(poller.firmware_version() is None)
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)))
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)))
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))
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))
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')
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!' )
topic_device_info = 'OpenCH/Gw/{}/TeHu/{}/Evt/DeviceInfo'.format( SELF_EUI64, mitemp_eui64) topic_health = 'OpenCH/Gw/{}/TeHu/{}/Evt/Health'.format( SELF_EUI64, mitemp_eui64) topic_measurements = 'OpenCH/Gw/{}/TeHu/{}/Evt/Status'.format( SELF_EUI64, mitemp_eui64) poller = MiTempBtPoller(mitemp_mac, BACKEND) msgs = [] try: if ARGS.devinfo: payload = '{{"name":"{}","firmware_version":"{}"}}' \ .format( \ poller.name(), \ poller.firmware_version()) msgs.append({'topic': topic_device_info, 'payload': payload}) if ARGS.health: payload = '{{"measurements":[{{"name":"battery","value":{},"units":"%"}}]}}' \ .format( \ poller.parameter_value(MI_BATTERY)) msgs.append({'topic': topic_health, 'payload': payload}) if ARGS.measurements: payload = '{{"measurements":[{{"name":"temperature","value":{},"units":"℃"}},{{"name":"humidity","value":{},"units":"%"}}]}}' \ .format( \ poller.parameter_value(MI_TEMPERATURE), \ poller.parameter_value(MI_HUMIDITY)) msgs.append({'topic': topic_measurements, 'payload': payload})