110 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
import json
 | 
						|
#import fileinput
 | 
						|
import serial
 | 
						|
import datetime
 | 
						|
 | 
						|
import paho.mqtt.client as paho
 | 
						|
 | 
						|
 | 
						|
#input = '{"model":"Oregon-THGR810","id":226,"channel":10,"battery_ok":0,"temperature_C":19.7,"humidity":24,"protocol":"Oregon Scientific Weather Sensor"}'
 | 
						|
SKIP_KEYS = [ "type", "model", "subtype", "channel", "id", "mic", "mod", "freq", "sequence_num", "message_type", "exception", "raw_msg", "protocol", "duration", "sync", "flags", "status" ]
 | 
						|
TOPIC_KEYS = [ "type", "model", "subtype", "channel", "id" ]
 | 
						|
 | 
						|
#default="devices[/type][/model][/subtype][/channel][/id]"
 | 
						|
prefix = "home/rtl_433"
 | 
						|
 | 
						|
broker = "127.0.0.1"
 | 
						|
port = 1883
 | 
						|
 | 
						|
#altitude = 150
 | 
						|
altitude = 210
 | 
						|
 | 
						|
rainref = -1
 | 
						|
rainlast = -1
 | 
						|
rainrefday = -1
 | 
						|
rainday = -1
 | 
						|
 | 
						|
serialdev = "/dev/ttyACM0"
 | 
						|
serialspeed = 115200
 | 
						|
 | 
						|
def get_humidex(tdb, rh):
 | 
						|
  return round(tdb + 5 / 9 * ((6.112 * 10 ** (7.5 * tdb / (237.7 + tdb)) * rh / 100) - 10))
 | 
						|
 | 
						|
def get_sealevel_pressure(pres, altitude, temp):
 | 
						|
  return (pres / pow(1 - ((0.0065 *altitude) / (temp + (0.0065 *altitude) + 273.15)), 5.257));
 | 
						|
 | 
						|
def generate_topic(jsonin):
 | 
						|
  topic = prefix+'/devices'
 | 
						|
  for t in TOPIC_KEYS:
 | 
						|
    if t in jsonin:
 | 
						|
      topic += '/' + str(jsonin[t])
 | 
						|
  return topic
 | 
						|
 | 
						|
def publish(jsonin, prefix_device):
 | 
						|
  for t in jsonin:
 | 
						|
    if t not in SKIP_KEYS:
 | 
						|
      topic = prefix_device + '/' + t
 | 
						|
      value = jsonin[t]
 | 
						|
      #print("{} {}".format(topic, value))
 | 
						|
      mqtt.publish(topic, value) 
 | 
						|
 | 
						|
def on_connect(client, userdata, flags, reason_code, properties):
 | 
						|
  print(f"Connected to MQTT")
 | 
						|
  client.subscribe(prefix+"/cmd")
 | 
						|
  client.subscribe(prefix+"/rain_reset")
 | 
						|
 | 
						|
def on_message(client, userdata, msg):
 | 
						|
  global rainref
 | 
						|
  print(msg.topic+" "+str(msg.payload))
 | 
						|
  if(str(msg.topic) == prefix+"/cmd"):
 | 
						|
    ser.write(msg.payload)
 | 
						|
  if(str(msg.topic) == prefix+"/rain_reset"):
 | 
						|
    rainref = rainlast
 | 
						|
 | 
						|
mqtt=paho.Client(paho.CallbackAPIVersion.VERSION2)
 | 
						|
mqtt.on_connect = on_connect
 | 
						|
mqtt.on_message = on_message
 | 
						|
mqtt.connect(broker,port)
 | 
						|
mqtt.loop_start()
 | 
						|
 | 
						|
ser = serial.Serial(serialdev, serialspeed)
 | 
						|
 | 
						|
#for input in fileinput.input():
 | 
						|
while True:
 | 
						|
  input = ser.readline()
 | 
						|
  try:
 | 
						|
    data = json.loads(input)
 | 
						|
  except json.decoder.JSONDecodeError:
 | 
						|
    print("Error JSON, received {}".format(input))
 | 
						|
    continue 
 | 
						|
  #print(data)
 | 
						|
  #mqtt.publish(prefix+'/events', input.rstrip())
 | 
						|
 | 
						|
  if 'humidity' in data and 'temperature_C' in data:
 | 
						|
    data['humidex'] = get_humidex(data['temperature_C'], data['humidity'])
 | 
						|
  if 'pressure' in data:
 | 
						|
    data['pressure'] = get_sealevel_pressure(data['pressure'], altitude, data['temperature_C'])
 | 
						|
    data['pressure'] = round(data['pressure'], 1)
 | 
						|
  if 'rain_mm' in data:
 | 
						|
    if rainref == -1 or data['rain_mm'] < rainlast:
 | 
						|
      rainref = data['rain_mm']
 | 
						|
      rainrefday = data['rain_mm']
 | 
						|
      rainlast = rainref
 | 
						|
      rainday = datetime.datetime.now().day
 | 
						|
      data['rain_local'] = 0
 | 
						|
      data['rain_day'] = 0
 | 
						|
    else:
 | 
						|
      rainlast = data['rain_mm']
 | 
						|
      data['rain_local'] = round(rainlast - rainref, 2)
 | 
						|
      if datetime.datetime.now().day != rainday:
 | 
						|
        rainday = datetime.datetime.now().day
 | 
						|
        rainrefday = data['rain_mm']
 | 
						|
        data['rain_day'] = 0
 | 
						|
      else:
 | 
						|
        data['rain_day'] = round(data['rain_mm'] - rainrefday,2)
 | 
						|
 | 
						|
  mqtt.publish(prefix+'/events', json.dumps(data)) 
 | 
						|
  prefix_device = generate_topic(data)
 | 
						|
  publish(data, prefix_device)
 | 
						|
 |