# ============================================================+ # Identity IoT — Node: Sensor # (c) Copyright : ae Aeonian Engineering Limited - Hong Kong # (c) Copyright : WIDE di D. Papa - Naples - Italy # ============================================================+ import utime import ujson import machine try: import uurequests as requests except ImportError: import urequests as requests from identity_iot_aes import aes_cbc_encrypt, aes_cbc_decrypt def _read_internal_temp(): sensor = machine.ADC(4) reading = sensor.read_u16() voltage = reading * 3.3 / 65535 temp_c = 27 - (voltage - 0.706) / 0.001721 return round(temp_c, 2) def _read_dht22(dht_sensor): try: dht_sensor.measure() return { 'temperature': dht_sensor.temperature(), 'humidity': dht_sensor.humidity(), } except Exception as e: print('[sensor] DHT22 read error:', e) return None def _show_reading(reading, label): try: import boot_manager temp = reading.get('temperature', reading.get('temp_internal', '--')) hum = reading.get('humidity') boot_manager._show([ 'Identity IoT', label or 'sensor', 'Temp: ' + str(temp) + 'C', 'Hum: ' + (str(hum) + '%' if hum is not None else '--'), '', ]) except Exception as e: print('[sensor] display error:', e) def _post_reading(cfg, key, iv, payload, jwt_token=''): url = cfg.get('data_destination_url', '') if not url: print('[sensor] no data_destination_url configured') return False try: body = ujson.dumps({'data': aes_cbc_encrypt(ujson.dumps(payload), key, iv)}) resp = requests.post( url, headers={ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + jwt_token, }, data=body, timeout=10, ) raw = resp.text resp.close() outer = ujson.loads(raw) clear = aes_cbc_decrypt(outer['data'], key, iv) result = ujson.loads(clear) if result.get('status') == 'ok': print('[sensor] reading posted ok') return True print('[sensor] post error:', result.get('code', 'unknown')) return False except Exception as e: print('[sensor] post failed:', e) return False def run_sensor(cfg, caps, jwt_token=''): print('[sensor] starting — has_sensor:', caps.get('has_sensor')) key = cfg['comm_key'].encode() if isinstance(cfg['comm_key'], str) else cfg['comm_key'] iv = cfg['comm_iv'].encode() if isinstance(cfg['comm_iv'], str) else cfg['comm_iv'] poll_interval = int(cfg.get('poll_interval', 60)) temp_min = cfg.get('temp_min') temp_max = cfg.get('temp_max') node_id = cfg.get('node_id', '') tenant_id = cfg.get('tenant_id', '') label = cfg.get('node_label', '') dht_sensor = None if caps.get('has_sensor'): try: import dht from machine import Pin dht_pin = cfg.get('pinout', {}).get('dht_pin', 15) dht_sensor = dht.DHT22(Pin(dht_pin)) except Exception as e: print('[sensor] DHT22 init error:', e) while True: reading = {} reading['temp_internal'] = _read_internal_temp() if dht_sensor: dht_data = _read_dht22(dht_sensor) if dht_data: reading['temperature'] = dht_data['temperature'] reading['humidity'] = dht_data['humidity'] print('[sensor] reading:', reading) _show_reading(reading, label) should_post = True if temp_min is not None or temp_max is not None: temp = reading.get('temperature', reading.get('temp_internal')) in_range = True if temp_min is not None and temp < float(temp_min): in_range = False if temp_max is not None and temp > float(temp_max): in_range = False if in_range: should_post = False if should_post: payload = { 'request': 'iot_node_reading', 'node_id': node_id, 'tenant_id': tenant_id, 'label': label, 'reading': reading, 'ts': utime.time(), } _post_reading(cfg, key, iv, payload, jwt_token) utime.sleep(poll_interval)