async def save_data(): try: while True: # TODO: Use utils.local_timestamp() and this will be used once v1.3 debian package release # https://github.com/foglamp/FogLAMP/commit/66dead988152cd3724eba6b4288b630cfa6a2e30 time_stamp = str(datetime.datetime.now(datetime.timezone.utc).astimezone()) # utils.local_timestamp() data = { 'asset': 'sinusoid', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "sinusoid": next(generate_data()) } } await Ingest.add_readings(asset='{}'.format(data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) await asyncio.sleep(1/(int(handle['dataPointsPerSec']['value']))) except asyncio.CancelledError: pass except (Exception, RuntimeError) as ex: _LOGGER.exception("Sinusoid exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex)
def plugin_poll(handle): """ Poll readings from the modbus device and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ try: source_address = handle['address']['value'] source_port = int(handle['port']['value']) readings = get_b100_readings(source_address, source_port) wrapper = { 'asset': handle['assetName']['value'], 'timestamp': utils.local_timestamp(), 'key': str(uuid.uuid4()), 'readings': readings } except Exception as ex: raise exceptions.DataRetrievalError(ex) else: return wrapper
async def save_data(): global no_of_assets, cn, asset_srl, cn_time try: time_stamp = utils.local_timestamp() asset_srl = 1 if asset_srl + 1 > no_of_assets else asset_srl + 1 data = { 'asset': "{}_{}".format(handle['assetName']['value'], asset_srl), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "x": random.random(), "y": random.random(), "z": random.random(), } } await Ingest.add_readings(asset='{}'.format(data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) cn += 1 if cn == recs: _LOGGER.exception(">>>> %s recs in % secs", recs, time.time() - cn_time) cn = 0 cn_time = time.time() except RuntimeWarning as ex: _LOGGER.exception("TestSample warning: {}".format(str(ex))) except (Exception, RuntimeError) as ex: _LOGGER.exception("TestSample exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex)
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document; A Python dict - if it is available, None - If no reading is available Raises: DataRetrievalError """ timestamp = str(datetime.now(tz=timezone.utc)) try: data = { 'asset': 'poll_template', 'timestamp': timestamp, 'key': str(uuid.uuid4()), 'readings': {'value': random.randint(0, 1000)} } except Exception as ex: raise exceptions.DataRetrievalError(ex) return data
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ try: humidity, temperature = Adafruit_DHT.read_retry( Adafruit_DHT.DHT11, handle) if humidity is not None and temperature is not None: time_stamp = str(datetime.now(tz=timezone.utc)) readings = {'temperature': temperature, 'humidity': humidity} wrapper = { 'asset': 'dht11', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': readings } return wrapper else: return None except Exception as ex: raise exceptions.DataRetrievalError(ex) return None
def plugin_poll(handle): """ Poll readings from the modbus device and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ readings = [] data = {} try: vaisala_mht410 = handle['vaisala_mht410'] readings = vaisala_mht410.get_readings() data = { "asset": handle['assetName']['value'], "timestamp": utils.local_timestamp() , "key": str(uuid.uuid4()), "readings": readings } except Exception as ex: raise exceptions.DataRetrievalError(ex) else: return data
def plugin_poll(handle): try: time_stamp = str(datetime.utcnow()) readings = {} if handle['temperatureSensor']['value'] == 'true': readings['temperature'] = _enviro.temperature if handle['pressureSensor']['value'] == 'true': readings['pressure'] = _enviro.pressure if handle['humiditySensor']['value'] == 'true': readings['humidity'] = _enviro.humidity if handle['ambientLightSensor']['value'] == 'true': readings['ambient_light'] = _enviro.ambient_light if handle['groveAnalogSensor']['value'] == 'true': readings['grove_analog'] = _enviro.grove_analog wrapper = { 'asset': 'enviro', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': readings } return wrapper except Exception as ex: raise exceptions.DataRetrievalError(ex) return None
async def save_data(): try: while True: time_stamp = utils.local_timestamp() data = { 'asset': handle['assetName']['value'], 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "sinusoid": next(generate_data()) } } await Ingest.add_readings(asset='{}'.format(data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) try: await asyncio.sleep( 1 / (float(handle['dataPointsPerSec']['value']))) except ZeroDivisionError: _LOGGER.warning( 'Data points per second must be greater than 0, defaulting to 1' ) handle['dataPointsPerSec']['value'] = '1' await asyncio.sleep(1) except asyncio.CancelledError: pass except (Exception, RuntimeError) as ex: _LOGGER.exception("Sinusoid exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex)
async def save_data(): if len(probes) is 0: return try: while True: for probe in probes: temperature = await probe.readTemp() time_stamp = str(datetime.datetime.now(tz=datetime.timezone.utc)) data = { 'asset': 'temperature{}'.format(probe.csPin), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "temperature": temperature, } } await Ingest.add_readings(asset='MAX31865/{}'.format(data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) await asyncio.sleep(1) except (Exception, RuntimeError, pexpect.exceptions.TIMEOUT) as ex: _LOGGER.exception("MAX31865 async exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex) _LOGGER.debug("MAX31865 async reading: {}".format(json.dumps(data))) return
def get_readings(handle): """ Get readings from DNP3 master and process needed registers to return readings as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns readings as a Python dict None - If no reading is available Raises: DataRetrievalError """ # The DNP3 master will stay open receiving unsolicited updates continuously after the plugin initializes global master # If the DNP3 master has not been initialized, open it with the configured parameters if master is None: master = open_dnp3_master(handle) time.sleep(30) return # DNP3 register offsets for the variables we are concerned with for this plugin LTC_TANK_TEMP_OFFSET = 5 TOP_OIL_TEMP_OFFSET = 6 B_PHASE_WINDING_CURRENT_OFFSET = 1 TAP_CHANGER_MOTOR_CURRENT_OFFSET = 2 FAN_BANK_1_CURRENT_OFFSET = 3 FAN_BANK_2_CURRENT_OFFSET = 4 try: all_dnp3_readings = master.values # Assemble the readings using the registers that we are concerned about. Apply scaling factor. readings = { 'top_oil_temp': all_dnp3_readings['analog'][TOP_OIL_TEMP_OFFSET], 'ltc_tank_temp': all_dnp3_readings['analog'][LTC_TANK_TEMP_OFFSET], 'b_phase_winding_current': all_dnp3_readings['analog'][B_PHASE_WINDING_CURRENT_OFFSET], 'tap_changer_motor_current': all_dnp3_readings['analog'][TAP_CHANGER_MOTOR_CURRENT_OFFSET], 'fan_bank_1_current': all_dnp3_readings['analog'][FAN_BANK_1_CURRENT_OFFSET], 'fan_bank_2_current': all_dnp3_readings['analog'][FAN_BANK_2_CURRENT_OFFSET] } except Exception as ex: raise exceptions.DataRetrievalError(ex) return readings
def plugin_poll(handle): """ Poll readings from the modbus device and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call - i.e. "the config" Returns: returns a reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ global pollCounter """ We don't want to send readings on every poll so we keep track """ if pollCounter == 0: try: source_address = handle['address']['value'] source_port = int(handle['port']['value']) """ Address and Port are set in the plugin config """ b100_ltc_tank_temp_reg = int( handle['b100_ltc_tank_temp_reg']['value']) b100_top_oil_temp_reg = int( handle['b100_top_oil_temp_reg']['value']) qualitrol_top_oil_reg = int( handle['qualitrol_top_oil_temp_reg']['value']) qualitrol_ltc_tank_reg = int( handle['qualitrol_ltc_tank_temp_reg']['value']) qualitrol_ltc_tap_position_reg = int( handle['qualitrol_ltc_tap_position_reg']['value']) readings = get_sel_readings(source_address, source_port, b100_ltc_tank_temp_reg, b100_top_oil_temp_reg, qualitrol_top_oil_reg, qualitrol_ltc_tank_reg, qualitrol_ltc_tap_position_reg) wrapper = { 'asset': handle['assetName']['value'], 'timestamp': utils.local_timestamp(), 'key': str(uuid.uuid4()), 'readings': readings } except Exception as ex: raise exceptions.DataRetrievalError(ex) else: pollCounter = int(handle['pollInterval']['value']) """ reset the pollcounter to the pollInterval plugin setting """ return wrapper else: pollCounter -= 1
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ port = handle['serial_port']['value'] baudrate = handle['baudrate']['value'] ser = serial.Serial(port, baudrate) counter = 0 x = ser.readline() # _LOGGER.info('RPICT3T1: {}', format(str(x))) values = x.split() if (len(values) == 5): Current1 = float(values[1].decode('UTF-8')) Current2 = float(values[2].decode('UTF-8')) Current3 = float(values[3].decode('UTF-8')) Temperature1 = float(values[4].decode('UTF-8')) else: _LOGGER.info('RPICT3T1: {}', format(str(len(values)))) try: time_stamp = utils.local_timestamp() readings = { 'Current1': Current1, 'Current2': Current2, 'Current3': Current3, 'Temperature': Temperature1 } data = { 'asset': handle['assetName']['value'], 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': readings } except (Exception, RuntimeError) as ex: _LOGGER.exception("RPICT3T1 exception: {}", format(str(ex))) raise exceptions.DataRetrievalError(ex) else: return data
async def save_data(): if 'tag' not in handle: return time_stamp = str(datetime.datetime.now(tz=datetime.timezone.utc)) data = { 'asset': 'TI Sensortag CC2650', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': {} } bluetooth_adr = handle['bluetoothAddress']['value'] tag = handle['tag'] object_temp_celsius = None ambient_temp_celsius = None lux_luminance = None rel_humidity = None rel_temperature = None bar_pressure = None movement = None battery_level = None keypress_state = None try: if not tag.is_connected: raise RuntimeError # Enable notification for notification_handle in handle['notification_handles']: tag.char_write_cmd(notification_handle, notification_enable) # Enable sensors tag.char_write_cmd( handle['characteristics']['temperature']['configuration'] ['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['luminance']['configuration'] ['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['humidity']['configuration'] ['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['pressure']['configuration'] ['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['movement']['configuration'] ['handle'], movement_enable) # TODO: How to implement CTRL-C or terminate process? debug_cnt = 0 # Used only for debugging. debug_cnt should be set to 0 in production. cnt = 0 while True: time_stamp = str( datetime.datetime.now(tz=datetime.timezone.utc)) try: pattern_index = tag.con.expect( 'Notification handle = .*? \r', timeout=4) except pexpect.TIMEOUT: _LOGGER.error("SensorTagCC2650 {} async timeout") print("TIMEOUT exception!") break # expect, if succesfull, will return the index of the pattern "Notification handle = " which ideally # should appear at col 0. If not, then pexpect.TIMEOUT will be raised. Also, this choice of pattern # will help in splitting at line#176. if pattern_index == 0: after = tag.con.after hex_string = after.split()[3:] cnt += 1 # Used only for debugging. debug_cnt should be set to 0 in production if debug_cnt > 0: if cnt >= debug_cnt: break print(cnt, "****", hex_string) # Allow some breathing time for event loop to finish the background tasks. if cnt % 50 == 0: await asyncio.sleep(.5) # Get temperature if int(handle['characteristics']['temperature']['data']['handle'], 16) == \ int(hex_string[0].decode(), 16): object_temp_celsius, ambient_temp_celsius = tag.hex_temp_to_celsius( tag.get_raw_measurement("temperature", hex_string)) data = { 'asset': 'temperature', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { 'temperature': { "object": object_temp_celsius, 'ambient': ambient_temp_celsius }, } } # Get luminance if int(handle['characteristics']['luminance']['data']['handle'], 16) == \ int(hex_string[0].decode(), 16): lux_luminance = tag.hex_lux_to_lux( tag.get_raw_measurement("luminance", hex_string)) data = { 'asset': 'luxometer', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { 'luxometer': { "lux": lux_luminance }, } } # Get humidity if int(handle['characteristics']['humidity']['data']['handle'], 16) == \ int(hex_string[0].decode(), 16): rel_humidity, rel_temperature = tag.hex_humidity_to_rel_humidity( tag.get_raw_measurement("humidity", hex_string)) data = { 'asset': 'humidity', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { 'humidity': { "humidity": rel_humidity, "temperature": rel_temperature }, } } # Get pressure if int(handle['characteristics']['pressure']['data']['handle'], 16) == \ int(hex_string[0].decode(), 16): bar_pressure = tag.hex_pressure_to_pressure( tag.get_raw_measurement("pressure", hex_string)) data = { 'asset': 'pressure', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { 'pressure': { "pressure": bar_pressure }, } } # Get movement if int(handle['characteristics']['movement']['data']['handle'], 16) == \ int(hex_string[0].decode(), 16): gyro_x, gyro_y, gyro_z, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z, acc_range = \ tag.hex_movement_to_movement(tag.char_read_hnd( handle['characteristics']['movement']['data']['handle'], "movement")) movement = { 'gyroscope': { "x": gyro_x, "y": gyro_y, "z": gyro_z }, 'accelerometer': { "x": acc_x, "y": acc_y, "z": acc_z }, 'magnetometer': { "x": mag_x, "y": mag_y, "z": mag_z }, } # Dedicated add_readings for movement for reading_key in movement: data = { 'asset': reading_key, 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { reading_key: movement[reading_key], } } await Ingest.add_readings( asset='TI Sensortag CC2650/{}'.format( data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) # Get battery # FIXME: Investigate why no battery input in async mode? if int(battery['data']['handle'], 16) == int(hex_string[0].decode(), 16): battery_level = tag.get_battery_level( tag.char_read_hnd(battery['data']['handle'], "battery")) data = { 'asset': 'battery', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { 'battery': { "percentage": battery_level }, } } # Get keypress # FIXME: Investigate why no keypress input? if int(keypress['data']['handle'], 16) == int(hex_string[0].decode(), 16): keypress_state = tag.get_keypress_state( tag.char_read_hnd(keypress['data']['handle'], "keypress")) data = { 'asset': 'keypress', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { 'keypress': { "state": keypress_state }, } } # Common add_readings for all keys other than movement if int(handle['characteristics']['movement']['data']['handle'], 16) != \ int(hex_string[0].decode(), 16): await Ingest.add_readings( asset='TI Sensortag CC2650/{}'.format( data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) else: _LOGGER.error("SensorTagCC2650 {} async timeout") print("TIMEOUT!!") except (Exception, RuntimeError) as ex: _LOGGER.exception("SensorTagCC2650 {} exception: {}".format( bluetooth_adr, str(ex))) raise exceptions.DataRetrievalError(ex) _LOGGER.debug("SensorTagCC2650 {} reading: {}".format( bluetooth_adr, json.dumps(data)))
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ time_stamp = str(datetime.datetime.now(tz=datetime.timezone.utc)) data = { 'asset': 'TI Sensortag CC2650', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': {} } bluetooth_adr = handle['bluetooth_adr'] object_temp_celsius = None ambient_temp_celsius = None lux_luminance = None rel_humidity = None rel_temperature = None bar_pressure = None movement = None try: tag = SensorTagCC2650(bluetooth_adr) # pass the Bluetooth Address if not tag.is_connected: raise RuntimeError # Enable sensors tag.char_write_cmd( handle['characteristics']['temperature']['configuration'] ['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['luminance']['configuration']['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['humidity']['configuration']['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['pressure']['configuration']['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['movement']['configuration']['handle'], movement_enable) # Get temperature count = 0 while count < SensorTagCC2650.reading_iterations: object_temp_celsius, ambient_temp_celsius = tag.hex_temp_to_celsius( tag.char_read_hnd( handle['characteristics']['temperature']['data']['handle'], "temperature")) time.sleep(0.5) # wait for a while count = count + 1 # Get luminance lux_luminance = tag.hex_lux_to_lux( tag.char_read_hnd( handle['characteristics']['luminance']['data']['handle'], "luminance")) # Get humidity rel_humidity, rel_temperature = tag.hex_humidity_to_rel_humidity( tag.char_read_hnd( handle['characteristics']['humidity']['data']['handle'], "humidity")) # Get pressure bar_pressure = tag.hex_pressure_to_pressure( tag.char_read_hnd( handle['characteristics']['pressure']['data']['handle'], "pressure")) # Get movement gyro_x, gyro_y, gyro_z, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z, acc_range = tag.hex_movement_to_movement( tag.char_read_hnd( handle['characteristics']['movement']['data']['handle'], "movement")) movement = { 'gyro': { 'x': gyro_x, 'y': gyro_y, 'z': gyro_z, }, 'acc': { 'x': acc_x, 'y': acc_y, 'z': acc_z, }, 'mag': { 'x': mag_x, 'y': mag_y, 'z': mag_z, }, 'acc_range': acc_range } # Disable sensors tag.char_write_cmd( handle['characteristics']['temperature']['configuration'] ['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['luminance']['configuration']['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['humidity']['configuration']['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['pressure']['configuration']['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['movement']['configuration']['handle'], movement_disable) # "values" (and not "readings") denotes that this reading needs to be further broken down to components. data['readings'] = { 'temperature': { "object": object_temp_celsius, 'ambient': ambient_temp_celsius }, 'luxometer': { "lux": lux_luminance }, 'humidity': { "humidity": rel_humidity, "temperature": rel_temperature }, 'pressure': { "pressure": bar_pressure }, 'gyroscope': { "x": gyro_x, "y": gyro_y, "z": gyro_z }, 'accelerometer': { "x": acc_x, "y": acc_y, "z": acc_z }, 'magnetometer': { "x": mag_x, "y": mag_y, "z": mag_z } } for reading_key in data['readings']: asyncio.ensure_future(handle['ingest'].add_readings( asset=data['asset'] + '/' + reading_key, timestamp=data['timestamp'], key=str(uuid.uuid4()), readings=data['readings'][reading_key])) except (Exception, RuntimeError) as ex: _LOGGER.exception("SensorTagCC2650 {} exception: {}".format( bluetooth_adr, str(ex))) raise exceptions.DataRetrievalError(ex) _LOGGER.debug("SensorTagCC2650 {} reading: {}".format( bluetooth_adr, json.dumps(data))) return data
def get_readings(handle): """ Get readings from DNP3 master and process needed registers to return readings as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns readings as a Python dict None - If no reading is available Raises: DataRetrievalError """ # The DNP3 master will stay open receiving unsolicited updates continuously after the plugin initializes global master # If the DNP3 master has not been initialized, open it with the configured parameters if master is None: master = open_dnp3_master(handle) time.sleep(30) return # DNP3 register offsets for the variables we are concerned with for this plugin LTC_TANK_TEMP_OFFSET = 120 TOP_OIL_TEMP_OFFSET = 150 WINDING_1_HOTSPOT_TEMP_OFFSET = 180 WINDING_2_HOTSPOT_TEMP_OFFSET = 210 WINDING_3_HOTSPOT_TEMP_OFFSET = 240 WINDING_1_CURRENT_AMPS_OFFSET = 281 WINDING_2_CURRENT_AMPS_OFFSET = 286 WINDING_3_CURRENT_AMPS_OFFSET = 291 H2_OFFSET = 300 hydrogen = handle['hydrogen']['value'] try: all_dnp3_readings = master.values #_LOGGER.info(f'b100 readings: {all_dnp3_readings}') # Assemble the readings using the registers that we are concerned about. Apply scaling factor. if all_dnp3_readings: if hydrogen: readings = { 'top_oil_temp': all_dnp3_readings['analog'][TOP_OIL_TEMP_OFFSET] / 1000, 'ltc_tank_temp': all_dnp3_readings['analog'][LTC_TANK_TEMP_OFFSET] / 1000, 'winding_1_hotspot_temp': all_dnp3_readings['analog'][WINDING_1_HOTSPOT_TEMP_OFFSET] / 1000, 'winding_2_hotspot_temp': all_dnp3_readings['analog'][WINDING_2_HOTSPOT_TEMP_OFFSET] / 1000, 'winding_3_hotspot_temp': all_dnp3_readings['analog'][WINDING_3_HOTSPOT_TEMP_OFFSET] / 1000, 'winding_1_current_amps': all_dnp3_readings['analog'][WINDING_1_CURRENT_AMPS_OFFSET] / 100, 'winding_2_current_amps': all_dnp3_readings['analog'][WINDING_2_CURRENT_AMPS_OFFSET] / 100, 'winding_3_current_amps': all_dnp3_readings['analog'][WINDING_3_CURRENT_AMPS_OFFSET] / 100, 'h2': all_dnp3_readings['analog'][H2_OFFSET] } else: readings = { 'top_oil_temp': all_dnp3_readings['analog'][TOP_OIL_TEMP_OFFSET] / 1000, 'ltc_tank_temp': all_dnp3_readings['analog'][LTC_TANK_TEMP_OFFSET] / 1000, 'winding_1_hotspot_temp': all_dnp3_readings['analog'][WINDING_1_HOTSPOT_TEMP_OFFSET] / 1000, 'winding_2_hotspot_temp': all_dnp3_readings['analog'][WINDING_2_HOTSPOT_TEMP_OFFSET] / 1000, 'winding_3_hotspot_temp': all_dnp3_readings['analog'][WINDING_3_HOTSPOT_TEMP_OFFSET] / 1000, 'winding_1_current_amps': all_dnp3_readings['analog'][WINDING_1_CURRENT_AMPS_OFFSET] / 100, 'winding_2_current_amps': all_dnp3_readings['analog'][WINDING_2_CURRENT_AMPS_OFFSET] / 100, 'winding_3_current_amps': all_dnp3_readings['analog'][WINDING_3_CURRENT_AMPS_OFFSET] / 100 } else: readings = {} except Exception as ex: raise exceptions.DataRetrievalError(ex) return readings
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ unit = 'hPa' # Pressure unit, can be either hPa (hectopascals) or Pa (pascals) time_stamp = str(datetime.datetime.now(tz=datetime.timezone.utc)) data = list() try: rgb = light.rgb() magnetometer = motion.magnetometer() accelerometer = [round(x, 2) for x in motion.accelerometer()] altitude = weather.altitude( ) # Supply your local qnh for more accurate readings temperature = weather.temperature() pressure = weather.pressure(unit=unit) data.append({ 'asset': 'EnviroHat/rgb', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "r": rgb[0], "g": rgb[1], "b": rgb[2] } }) data.append({ 'asset': 'EnviroHat/magnetometer', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "x": magnetometer[0], "y": magnetometer[1], "z": magnetometer[2] } }) data.append({ 'asset': 'EnviroHat/accelerometer', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "x": accelerometer[0], "y": accelerometer[1], "z": accelerometer[2] } }) data.append({ 'asset': 'EnviroHat/weather', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "altitude": altitude, "pressure": pressure, "temperature": temperature } }) except (Exception, RuntimeError, pexpect.exceptions.TIMEOUT) as ex: _LOGGER.exception("EnviroHat exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex) _LOGGER.debug("EnviroHat reading: {}".format(json.dumps(data))) return data
async def save_data(): attempt = 1 if bus is None: return try: while True: await asyncio.sleep(1) try: try: # wake up call bus.write_i2c_block_data(sensor_add, function_code, [start_add, register_number]) except Exception as e: # expected exception as sensor is sleeping pass # request data bus.write_i2c_block_data(sensor_add, function_code, [start_add, register_number]) # read data sensor_response = bytearray(bus.read_i2c_block_data(sensor_add, function_code, response_bytes)) # function_code=sensor_response[0] # bytes_returned=sensor_response[1] # relative_humidity_high=sensor_response[2] # relative_humidity_low=sensor_response[3] # temperature_high=sensor_response[4] # temperature_low=sensor_response[5] # crc_low=sensor_response[6] # crc_high=sensor_response[7] # temperature temperature= (sensor_response[4] * 256 + sensor_response[5])/10 # humidity humidity= (sensor_response[2] * 256 + sensor_response[3])/10 # crc crc = sensor_response[7] * 256 + sensor_response[6] # calc crc to verify calc_crc = 0xFFFF for byte in sensor_response[0:6]: calc_crc = calc_crc ^ byte for i in range(1,9): if(calc_crc & 0x01): calc_crc = calc_crc >> 1 calc_crc = calc_crc ^ 0xA001 else: calc_crc = calc_crc >> 1 if calc_crc != crc: pass time_stamp = str(datetime.datetime.now(tz=datetime.timezone.utc)) data = { 'asset': 'temperature', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "temperature": temperature, } } await Ingest.add_readings(asset='AM2315/{}'.format(data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) data = { 'asset': 'humidity', 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "humidity": humidity, } } await Ingest.add_readings(asset='AM2315/{}'.format(data['asset']), timestamp=data['timestamp'], key=data['key'], readings=data['readings']) attempt = 1 except (Exception) as ex: attempt += 1 if attempt > attempt_threshold: raise RuntimeError("Attempt {} exceeds attempt threshold of {}".format(attempt, attempt_threshold)) except (Exception, RuntimeError, pexpect.exceptions.TIMEOUT) as ex: _LOGGER.exception("AM2315 async exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex) _LOGGER.debug("AM2315 async reading: {}".format(json.dumps(data))) return
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ try: bus = handle["bus"] i2c_address = handle['i2cAddress']['value'] sensor_add = hex(int(i2c_address, 16)) start_add = 0x00 function_code = 0x03 register_number = 0x04 response_bytes = 8 attempt_threshold = 50 asset_name = '{}'.format(handle['assetName']['value']).replace( '%M', i2c_address) try: # wake up call bus.write_i2c_block_data(sensor_add, function_code, [start_add, register_number]) except Exception as e: # expected exception as sensor is sleeping pass # request data bus.write_i2c_block_data(sensor_add, function_code, [start_add, register_number]) # read data sensor_response = bytearray( bus.read_i2c_block_data(sensor_add, function_code, response_bytes)) # temperature temperature = (sensor_response[4] * 256 + sensor_response[5]) / 10 # humidity humidity = (sensor_response[2] * 256 + sensor_response[3]) / 10 # crc crc = sensor_response[7] * 256 + sensor_response[6] # calc crc to verify calc_crc = 0xFFFF for byte in sensor_response[0:6]: calc_crc = calc_crc ^ byte for i in range(1, 9): if (calc_crc & 0x01): calc_crc = calc_crc >> 1 calc_crc = calc_crc ^ 0xA001 else: calc_crc = calc_crc >> 1 if calc_crc != crc: pass time_stamp = utils.local_timestamp() data = { 'asset': asset_name, 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "temperature": temperature, "humidity": humidity } } except (Exception, RuntimeError) as ex: _LOGGER.exception("AM2315 exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex) return data
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: TimeoutError """ # air quality is voltage reading between 0 and 5.1 # we scale is to a value between 0 and 1023 try: time_stamp = utils.local_timestamp() data = list() if handle['tempHumEnable']['value'] == 'true' and handle['tempHumCount'] == 0: data.append({ 'asset': '{}{}'.format(handle['assetPrefix']['value'], handle['tempHumAssetName']['value']), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "temperature": handle['temperature'].getTemperature(), "humidity": handle['humidity'].getHumidity() } }) if handle['currentEnable']['value'] == 'true' and handle['currentCount'] == 0: data.append({ 'asset': '{}{}'.format(handle['assetPrefix']['value'], handle['currentAssetName']['value']), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "current": handle['current'].getCurrent() } }) if handle['encoderEnable']['value'] == 'true' and handle['encoderCount'] == 0: value = handle['encoder'].getPosition() # convert time_stamp to be usable if ":" == time_stamp[-3:-2]: timestamp_new = datetime.datetime.strptime(time_stamp[:-3]+time_stamp[-2:], '%Y-%m-%d %H:%M:%S.%f%z') else: timestamp_new = datetime.datetime.strptime(time_stamp, '%Y-%m-%d %H:%M:%S.%f%z') if handle['encoderPreviousValue'] > 0: # omit first one # calculate elapse time in milliseconds elapse_time = timestamp_new - handle['encoderPreviousTime'] elapse_time = elapse_time.total_seconds() data.append({ 'asset': '{}{}'.format(handle['assetPrefix']['value'], handle['encoderAssetName']['value']), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { # (current_total_iterations - previous_total_iterations) / (elapsed time in seconds) "rotation-per-second": ((value - handle['encoderPreviousValue'])/1200)/elapse_time } }) # update old values handle['encoderPreviousValue'] = value handle['encoderPreviousTime'] = timestamp_new if handle['accelerometerEnable']['value'] == 'true' and handle['accelerometerCount'] == 0: x, y, z = handle['accelerometer'].getAcceleration() data.append({ 'asset': '{}{}'.format(handle['assetPrefix']['value'], handle['accelerometerAssetName']['value']), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "accelerometer-x": x, "accelerometer-y": y, "accelerometer-z": z } }) if handle['gyroscopeEnable']['value'] == 'true' and handle['gyroscopeCount'] == 0: x, y, z = handle['gyroscope'].getAngularRate() data.append({ 'asset': '{}{}'.format(handle['assetPrefix']['value'], handle['gyroscopeAssetName']['value']), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "gyroscope-x": x, "gyroscope-y": y, "gyroscope-z": z } }) if handle['magnetometerEnable']['value'] == 'true' and handle['magnetometerCount'] == 0: x, y, z = handle['magnetometer'].getMagneticField() data.append({ 'asset': '{}{}'.format(handle['assetPrefix']['value'], handle['magnetometerAssetName']['value']), 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': { "magnetometer-x": x, "magnetometer-y": y, "magnetometer-z": z } }) handle['tempHumCount'] = (handle['tempHumCount'] + 1) % int(handle['tempHumPoll']['value']) handle['currentCount'] = (handle['currentCount'] + 1) % int(handle['currentPoll']['value']) handle['encoderCount'] = (handle['encoderCount'] + 1) % int(handle['encoderPoll']['value']) handle['accelerometerCount'] = (handle['accelerometerCount'] + 1) % int(handle['accelerometerPoll']['value']) handle['gyroscopeCount'] = (handle['gyroscopeCount'] + 1) % int(handle['gyroscopePoll']['value']) handle['magnetometerCount'] = (handle['magnetometerCount'] + 1) % int(handle['magnetometerPoll']['value']) except (Exception, RuntimeError) as ex: _LOGGER.exception("wind_turbine exception: {}".format(str(ex))) raise exceptions.DataRetrievalError(ex) else: return data
def plugin_poll(handle): """ Extracts data from the sensor and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a sensor reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: DataRetrievalError """ if 'tag' not in handle: raise RuntimeError time_stamp = utils.local_timestamp() data = list() bluetooth_adr = handle['bluetoothAddress']['value'] tag = handle['tag'] object_temp_celsius = None ambient_temp_celsius = None lux_luminance = None rel_humidity = None rel_temperature = None bar_pressure = None movement = None battery_level = None keypress_state = None try: if not tag.is_connected: raise RuntimeError # Enable sensors tag.char_write_cmd( handle['characteristics']['temperature']['configuration'] ['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['luminance']['configuration']['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['humidity']['configuration']['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['pressure']['configuration']['handle'], char_enable) tag.char_write_cmd( handle['characteristics']['movement']['configuration']['handle'], movement_enable) # Get temperature count = 0 while count < SensorTagCC2650.reading_iterations: object_temp_celsius, ambient_temp_celsius = tag.hex_temp_to_celsius( tag.char_read_hnd( handle['characteristics']['temperature']['data']['handle'], "temperature")) time.sleep(0.5) # wait for a while count = count + 1 # Get luminance lux_luminance = tag.hex_lux_to_lux( tag.char_read_hnd( handle['characteristics']['luminance']['data']['handle'], "luminance")) # Get humidity rel_humidity, rel_temperature = tag.hex_humidity_to_rel_humidity( tag.char_read_hnd( handle['characteristics']['humidity']['data']['handle'], "humidity")) # Get pressure bar_pressure = tag.hex_pressure_to_pressure( tag.char_read_hnd( handle['characteristics']['pressure']['data']['handle'], "pressure")) # Get movement gyro_x, gyro_y, gyro_z, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z, acc_range = tag.hex_movement_to_movement( tag.char_read_hnd( handle['characteristics']['movement']['data']['handle'], "movement")) movement = { 'gyro': { 'x': gyro_x, 'y': gyro_y, 'z': gyro_z, }, 'acc': { 'x': acc_x, 'y': acc_y, 'z': acc_z, }, 'mag': { 'x': mag_x, 'y': mag_y, 'z': mag_z, }, 'acc_range': acc_range } battery_level = tag.get_battery_level( tag.char_read_hnd( handle['characteristics']['battery']['data']['handle'], "battery")) # Disable sensors tag.char_write_cmd( handle['characteristics']['temperature']['configuration'] ['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['luminance']['configuration']['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['humidity']['configuration']['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['pressure']['configuration']['handle'], char_disable) tag.char_write_cmd( handle['characteristics']['movement']['configuration']['handle'], movement_disable) # "values" (and not "readings") denotes that this reading needs to be further broken down to components. readings = { 'temperature': { "object": object_temp_celsius, 'ambient': ambient_temp_celsius }, 'luxometer': { "lux": lux_luminance }, 'humidity': { "humidity": rel_humidity, "temperature": rel_temperature }, 'pressure': { "pressure": bar_pressure }, 'gyroscope': { "x": gyro_x, "y": gyro_y, "z": gyro_z }, 'accelerometer': { "x": acc_x, "y": acc_y, "z": acc_z }, 'magnetometer': { "x": mag_x, "y": mag_y, "z": mag_z }, 'battery': { "percentage": battery_level }, } for reading_key in readings.keys(): data.append({ 'asset': 'TI Sensortag CC2650/' + reading_key, 'timestamp': time_stamp, 'key': str(uuid.uuid4()), 'readings': readings[reading_key] }) except (Exception, RuntimeError, pexpect.exceptions.TIMEOUT) as ex: _LOGGER.exception("SensorTagCC2650 {} exception: {}".format( bluetooth_adr, str(ex))) raise exceptions.DataRetrievalError(ex) _LOGGER.debug("SensorTagCC2650 {} reading: {}".format( bluetooth_adr, json.dumps(data))) return data