Skip to content

Instantly share code, notes, and snippets.

@mattiarossi
Created November 5, 2016 13:52
Show Gist options
  • Select an option

  • Save mattiarossi/8ad369cd8fb0497aff4f7425f4e967de to your computer and use it in GitHub Desktop.

Select an option

Save mattiarossi/8ad369cd8fb0497aff4f7425f4e967de to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Author: mattiarossi
# @Date: 2016-03-27 23:29:25
# @Last Modified by: mattiarossi
# @Last Modified time: 2016-03-28 23:25:55
import time
import threading
import minimalmodbus
minimalmodbus.CLOSE_PORT_AFTER_EACH_CALL = False
import paho.mqtt.client as mqtt
import pprint
import json
# state values
stateDict = {}
user="sdmmonitor"
passwd="ewuriwyurywiryei"
clientid="emonpi01sdmmon"
server=""
topic="ha/value/electricity/"
addresslist={'1': 'generale', '2': 'casa' , '3': 'condizionatori','4':'lavanderia','5':'ups-pc','6':'solar','7':'enel'}
masterMsgInterval = 10
singleInstrumentInterval=0.5
cleansession = False
sessionConnected = False
rs485Instances=[]
# MQTT broker callbacks
def on_connect(mosq, userdata, result_code):
"""
Handle connections (or failures) to the broker.
This is called after the client has received a CONNACK message
from the broker in response to calling connect().
The result_code is one of;
0: Success
1: Refused - unacceptable protocol version
2: Refused - identifier rejected
3: Refused - server unavailable
4: Refused - bad user name or password (MQTT v3.1 broker only)
5: Refused - not authorised (MQTT v3.1 broker only)
"""
if result_code == 0:
print("Connected to MQTT broker, subscribing to topics...")
if not cleansession:
print("Cleansession==False; previous subscriptions for clientid %s remain active on broker" % clientid)
elif result_code == 1:
print("Connection refused - unacceptable protocol version")
elif result_code == 2:
print("Connection refused - identifier rejected")
elif result_code == 3:
print("Connection refused - server unavailable")
elif result_code == 4:
print("Connection refused - bad user name or password")
elif result_code == 5:
print("Connection refused - not authorised")
else:
print("Connection failed - result code %d" % (result_code))
def on_disconnect(mosq, userdata, result_code):
global sessionConnected
"""
Handle disconnections from the broker
"""
if result_code == 0:
print("Clean disconnection from broker")
else:
print("brokerdisconnected", "Broker connection lost. Will attempt to reconnect in 5s...")
time.sleep(5)
sessionConnected = False
sys.exit(0)
def readRs485Data():
global rs485Instances, stateDict
stateDict = {}
for rsInstance in rs485Instances:
counterDict = {}
print rsInstance
try:
counterDict['Volts'] = rsInstance.read_float(0, functioncode=4, numberOfRegisters=2)
counterDict['Current'] = rsInstance.read_float(6, functioncode=4, numberOfRegisters=2)
counterDict['Active_Power'] = rsInstance.read_float(12, functioncode=4, numberOfRegisters=2)
counterDict['Apparent_Power'] = rsInstance.read_float(18, functioncode=4, numberOfRegisters=2)
counterDict['Reactive_Power'] = rsInstance.read_float(24, functioncode=4, numberOfRegisters=2)
counterDict['Power_Factor'] = rsInstance.read_float(30, functioncode=4, numberOfRegisters=2)
counterDict['Phase_Angle'] = rsInstance.read_float(36, functioncode=4, numberOfRegisters=2)
counterDict['Frequency'] = rsInstance.read_float(70, functioncode=4, numberOfRegisters=2)
counterDict['Import_Active_Energy'] = rsInstance.read_float(72, functioncode=4, numberOfRegisters=2)
counterDict['Export_Active_Energy'] = rsInstance.read_float(74, functioncode=4, numberOfRegisters=2)
counterDict['Import_Reactive_Energy'] = rsInstance.read_float(76, functioncode=4, numberOfRegisters=2)
counterDict['Export_Reactive_Energy'] = rsInstance.read_float(78, functioncode=4, numberOfRegisters=2)
counterDict['Total_Active_Energy'] = rsInstance.read_float(342, functioncode=4, numberOfRegisters=2)
counterDict['Total_Reactive_Energy'] = rsInstance.read_float(344, functioncode=4, numberOfRegisters=2)
counterDict['Current_Yield'] = counterDict['Volts']*counterDict['Current']
if (rsInstance.address == 6):
counterDict['Solar_Export']= counterDict['Active_Power'] - stateDict[addresslist['1']]['Active_Power']
if (counterDict['Solar_Export'] < 0):
counterDict['Solar_Export'] = 0
counterDict['Grid_Import']= stateDict[addresslist['1']]['Active_Power'] - counterDict['Active_Power']
if (counterDict['Grid_Import'] < 0):
counterDict['Grid_Import'] = 0
stateDict[addresslist[str(rsInstance.address)]] = counterDict
time.sleep(singleInstrumentInterval)
#print 'Voltage: {0:.1f} Volts'.format(Volts)
#print 'Current: {0:.1f} Amps'.format(Current)
#print 'Active power: {0:.1f} Watts'.format(Active_Power)
#print 'Apparent power: {0:.1f} VoltAmps'.format(Apparent_Power)
#print 'Reactive power: {0:.1f} VAr'.format(Reactive_Power)
#print 'Power factor: {0:.1f}'.format(Power_Factor)
#print 'Phase angle: {0:.1f} Degree'.format(Phase_Angle)
#print 'Frequency: {0:.1f} Hz'.format(Frequency)
#print 'Import active energy: {0:.3f} Kwh'.format(Import_Active_Energy)
#print 'Export active energy: {0:.3f} kwh'.format(Export_Active_Energy)
#print 'Import reactive energy: {0:.3f} kvarh'.format(Import_Reactive_Energy)
#print 'Export reactive energy: {0:.3f} kvarh'.format(Export_Reactive_Energy)
#print 'Total active energy: {0:.3f} kwh'.format(Total_Active_Energy)
#print 'Total reactive energy: {0:.3f} kvarh'.format(Total_Reactive_Energy)
#print 'Current Yield (V*A): {0:.1f} Watt'.format(Volts * Current)
#
except Exception, e:
print "----> 2 ----> Error"
print str(e)
pass
mqttc = mqtt.Client(client_id=clientid)
mqttc.username_pw_set(user, passwd)
mqttc.on_connect = on_connect
mqttc.on_disconnect = on_disconnect
mqttc.connect(server)
sessionConnected = True
for slaveAddr,slaveName in addresslist.iteritems():
print "Adding instrument " ,slaveAddr
rs485 = minimalmodbus.Instrument('/dev/ttyUSB0', int(slaveAddr))
rs485.serial.baudrate = 9600
rs485.serial.bytesize = 8
rs485.serial.parity = minimalmodbus.serial.PARITY_NONE
rs485.serial.stopbits = 1
rs485.serial.timeout = 1
rs485.debug = False
rs485.mode = minimalmodbus.MODE_RTU
rs485Instances.append(rs485)
while True:
readRs485Data()
# send to MQTT
try:
for key,values in stateDict.iteritems():
baseTopic = topic + "counter/"+ str(key) + "/"
#print "Publishing values %s to topic %s",str(values),baseTopic
for t,v in values.iteritems():
fTopic = baseTopic + t
fTopic2 = "emon/"+ str(key) + "/" + t
#print "["+fTopic+"]: " + str(v)
if sessionConnected == False :
print "-----------> Reconnecting ----------"
mqttc.reconnect()
sessionConnected = True
mqttc.publish(fTopic, v, 1)
mqttc.publish(fTopic2, v, 1)
mqttc.loop(2,10)
except Exception as ex:
print "MQTT Exception: " + str(ex)
sys.exit(0)
time.sleep(masterMsgInterval)
mqttc.disconnect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment