145 lines
4.5 KiB
Python
145 lines
4.5 KiB
Python
# ============================================================+
|
|
# 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)
|