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()
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())
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)
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')
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")
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 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)
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 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("")
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 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
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 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)
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_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
def retrieve_temp(): global mac_address backend = BluepyBackend poller = MiTempBtPoller(mac_address, backend) temp = poller.parameter_value(MI_TEMPERATURE) return temp
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
def retrieve_humidity(): global mac_address backend = BluepyBackend poller = MiTempBtPoller(mac_address, backend) humidity = poller.parameter_value(MI_HUMIDITY) return humidity
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))
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()
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()
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)
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
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:
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
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)
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")
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 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!' )