Skip to content

Instantly share code, notes, and snippets.

@g3ntleman
Forked from andypiper/readserial.py
Last active May 10, 2019 16:12
Show Gist options
  • Save g3ntleman/e7f4349d690aa3ffbc371b8efec30647 to your computer and use it in GitHub Desktop.
Save g3ntleman/e7f4349d690aa3ffbc371b8efec30647 to your computer and use it in GitHub Desktop.
Scrape serial port for text data and publish on MQTT
#!/usr/bin/python3
#
#simple app to read string from serial port
#and publish via MQTT
#
#uses the Python MQTT client from the Mosquitto project
#http://mosquitto.org
#
#Andy Piper http://andypiper.co.uk
#2011/09/15
import serial
import os
import binascii
import time
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
serialdev = '/dev/ttyUSB0'
broker = "127.0.0.1"
port = 1883
#MQTT callbacks
def on_connect(rc):
if rc == 0:
#rc 0 successful connect
print("Connected")
else:
raise Exception
def on_publish(val):
print("Published ", val)
#called on exit
#close serial, disconnect MQTT
def cleanup():
print("Ending and cleaning up")
ser.close()
mqttc.disconnect()
try:
print("Connecting... ", serialdev)
#connect to serial port
ser = serial.Serial(serialdev, baudrate=9600, timeout=20)
except:
print("Failed to connect serial")
#unable to continue with no serial input
raise SystemExit
try:
ser.flushInput()
#create an mqtt client
mypid = os.getpid()
client_uniq = "power-pub-"+str(mypid)
mqttc = mqtt.Client(client_id=client_uniq)
#attach MQTT callbacks
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
#connect to broker
mqttc.connect(broker, port, 60)
#remain connected to broker
#marker byte-sequences:
start = '1b1b1b1b01010101'
end = '1b1b1b1b1a'
data = ''
reading = {}
lastReading = None
while True:
bytes = ser.read(1)
bytestring = binascii.hexlify(bytes).decode('ascii')
data = data + bytestring
#print(bytestring + ' ', end='', flush=True)
pos = data.find(start)
if (pos != -1):
data = data[pos:len(data)]
pos = data.find(end)
if (pos != -1):
#print('found ' + data[16:pos] + '\n')
search = '070100020800ff'
pos = data.find(search)
if (pos != -1):
pos = pos + len(search) + 20
value = data[pos:pos + 10]
scale = pow(10,-1) # todo: read from data
energyWatth = int(value, 16) * scale
energyKWh = energyWatth / 1000.0
#print('Power Sent (' + search + ') : 0x', value, ' = ', "{:10.3f}".format(energyKWh), ' kWh')
publish.single("net-power/sent-total", payload=energyWatth, qos=0, retain=False)
reading['sent-total'] = energyWatth
search = '070100010800ff'
pos = data.find(search)
if (pos != -1):
pos = pos + len(search) + 20
value = data[pos:pos + 10]
scale = pow(10,-1) # todo: read from data
energyWatth = int(value, 16) * scale
energyKWh = energyWatth / 1000.0
#print('Power Received (' + search + ') : 0x', value, ' = ', "{:10.3f}".format(energyKWh), ' kWh')
publish.single('net-power/recieved-total', payload=energyWatth, qos=0, retain=False)
reading['received-total'] = energyWatth
search = '070100010700ff'
pos = data.find(search)
if (pos != -1):
pos = pos + len(search) + 14
value = data[pos:pos + 8]
power = int(value, 16) / 1e2
print ('W: ' + search + ' = ' + value + ' = ' + str(power) + ' W')
readingTime = time.time()
reading['time'] = readingTime
if (lastReading is not None):
lastReadingTime = lastReading['time']
duration = readingTime-lastReadingTime
if (duration > 10.0):
consumptionWh = (reading['received-total'] - lastReading['received-total']) - \
(reading['sent-total'] - lastReading['sent-total'])
consumptionWs = consumptionWh * 3600.0;
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(readingTime))
print(timestamp, 'Average Power Consumption, 10s:', '{:0.1f}'.format(consumptionWs/duration), 'Watt')
# Reset reading:
lastReading = reading.copy()
reading = {}
#else:
#print('Elapsed', "{:2.1f}".format(duration)+ 's. ', 'Collecting...')
#print('lastReading ', str(lastReading))
#print('reading ', str(reading))
else:
print('initializing lastRead.')
lastReading = reading.copy() # initial setting
data = ''
# print("got ", line)
#split line as it contains V,temp
#list = line.split(",")
#second list element is temp
#temp = 1
#list[1].rstrip()
#mqttc.publish("net-power/rec", temp)
#pass
# handle list index error (i.e. assume no data received)
except (IndexError):
print("No data received within serial timeout period")
cleanup()
# handle app closure
except (KeyboardInterrupt):
print("Interrupt received")
cleanup()
except (RuntimeError):
print("uh-oh! time to die")
cleanup()
#!/usr/bin/python3
#
#simple app to read string from serial port
#and publish via MQTT
#
#uses the Python MQTT client from the Mosquitto project
#http://mosquitto.org
#
#Andy Piper http://andypiper.co.uk
#2011/09/15
import serial
import os
import paho.mqtt.client as mqtt
serialdev = '/dev/ttyUSB0'
broker = "127.0.0.1"
port = 1883
#MQTT callbacks
def on_connect(rc):
if rc == 0:
#rc 0 successful connect
print("Connected")
else:
raise Exception
def on_publish(val):
print("Published ", val)
#called on exit
#close serial, disconnect MQTT
def cleanup():
print("Ending and cleaning up")
ser.close()
mqttc.disconnect()
try:
print("Connecting... ", serialdev)
#connect to serial port
ser = serial.Serial(serialdev, baudrate=9600, bytesize=7, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=20)
except:
print("Failed to connect serial")
#unable to continue with no serial input
raise SystemExit
try:
ser.flushInput()
#create an mqtt client
mypid = os.getpid()
client_uniq = "arduino_pub_"+str(mypid)
mqttc = mqtt.Client(client_id=client_uniq)
#attach MQTT callbacks
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
#connect to broker
mqttc.connect(broker, port, 60)
#remain connected to broker
#read data from serial and publish
while mqttc.loop() == 0:
line = ser.readline()
print("got ", line)
#split line as it contains V,temp
#list = line.split(",")
#second list element is temp
temp = 1
#list[1].rstrip()
mqttc.publish("net-power/rec", temp)
pass
# handle list index error (i.e. assume no data received)
except (IndexError):
print("No data received within serial timeout period")
cleanup()
# handle app closure
except (KeyboardInterrupt):
print("Interrupt received")
cleanup()
except (RuntimeError):
print("uh-oh! time to die")
cleanup()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment