def test_name(self): """Check reading of the sensor name.""" poller = MiTempBtPoller(self.TEST_MAC, MockBackend) backend = self._get_backend(poller) backend.name = 'my sensor name' self.assertEqual(backend.name, poller.name())
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 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 retrieve_temp(): global mac_address backend = BluepyBackend poller = MiTempBtPoller(mac_address, backend) temp = poller.parameter_value(MI_TEMPERATURE) return temp
def retrieve_humidity(): global mac_address backend = BluepyBackend poller = MiTempBtPoller(mac_address, backend) humidity = poller.parameter_value(MI_HUMIDITY) return humidity
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 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 get_battery(mac): poller = MiTempBtPoller(mac, BluepyBackend) for _ in range(100): try: return poller.battery_level() except BluetoothBackendException: continue return 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))
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 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 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_no_answer_name(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_0x03_raw = None with self.assertRaises(BluetoothBackendException): poller.name()
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 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 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_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 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 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()
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 start_pollers(self): no_of_devices = len(self._device_config) for device, device_config in self._device_config.items(): poller = MiTempBtPoller(device_config['mac'], BluepyBackend) t = Thread(target=self.poll_device_thread, args=(self.poll_interval, self._cancel_event, device, poller, self.__bluetooth_access_lock, self.database_handler)) t.start() self.__threads[device] = t sleep(self.poll_interval / no_of_devices)
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): 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 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(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(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')
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_parsing(self): """Does the Mi TEMP BT data parser works correctly?""" poller = MiTempBtPoller(None, MockBackend) data = bytes([0x54, 0x3d, 0x32, 0x35, 0x2e, 0x36, 0x20, 0x48, 0x3d, 0x32, 0x33, 0x2e, 0x36, 0x00]) poller._cache = data poller._last_read = datetime.now() self.assertEqual(poller._parse_data()[MI_TEMPERATURE], 25.6) self.assertEqual(poller._parse_data()[MI_HUMIDITY], 23.6)
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))