Blame | Last modification | View Log | RSS feed
## Landi&Gyr UH50 IR Datalogger# $Revision: 9 $# $Author: raymond $# $Date: 2015-09-06 13:21:04 +0200 (zo, 06 sep 2015) $# Copyright (c) 2013 J. van der Linde## Although there is a explicit copyright on this sourcecode, anyone may use it# freely under a "Creative Commons# Naamsvermelding-NietCommercieel-GeenAfgeleideWerken 3.0 Nederland" licentie.# Please check http://creativecommons.org/licenses/by-nc-nd/3.0/nl/ for details## This software is provided as is and comes with absolutely no warranty.# The author is not responsible or liable (direct or indirect) to anyone for# the use or misuse of this software. Any person using this software does so# entirely at his/her own risk. That person bears sole responsibility and# liability for any claims or actions, legal or civil, arising from such use.# If you believe this software is in breach of anyone's copyright you will# inform the author immediately so the offending material can be removed upon# receipt of proof of copyright for that material.## Dependend on Python 3.2+ and Python 3.2+ packages: PySerial 2.5#version = "UH50 v0.10 RVS"import sysimport globimport serialimport datetimeimport csvimport osimport localefrom time import sleepMySQL_loaded=Truetry:import mysql.connectorexcept ImportError:MySQL_loaded=Falsedef scan_serial():# scan for available ports. return a list of tuples (num, name)""" Lists serial port names:raises EnvironmentError:On unsupported or unknown platforms:returns:A list of the serial ports available on the system"""if sys.platform.startswith('win'):ports = ['COM%s' % (i + 1) for i in range(256)]elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):# this excludes your current terminal "/dev/tty"ports = glob.glob('/dev/tty[A-Za-z]*')elif sys.platform.startswith('darwin'):ports = glob.glob('/dev/tty.*')else:raise EnvironmentError('Unsupported platform')port_exceptions = ['/dev/ttyprintk','dev/ttyprintk']for port in port_exceptions:if port in ports:ports.remove(port)available = []for port in ports:try:s = serial.Serial(port)s.close()available.append(port)except (OSError, serial.SerialException):passif not available:available.append('Helaas geen seriele poorten gevonden')return available#################Error display #################def show_error():ft = sys.exc_info()[0]fv = sys.exc_info()[1]print("Fout type: %s" % ft )print("Fout waarde: %s" % fv )return#################Scherm output #################def print_heat_telegram():print ("---------------------------------------------------------------------------------------")print ("Landis & Gyr UH50 telegram ontvangen op: %s" % heat_timestamp)print ("Meter fabrikant/type: Landis & Gyr Ultraheat 50")print (" 0. 0 - Meter identificatie: %s" % heat_equipment_id )print (" 6. 8 - Meterstand Energie: %0.3f %s" % (heat_meterreading_energy, heat_unitmeterreading_energy) )print (" 6.26 - Meterstand Volume: %0.3f %s" % (heat_meterreading_volume, heat_unitmeterreading_volume) )print (" 6.31 - Meterstand Gebruiksduur: %0.3f %s" % (heat_meterreading_hours, heat_unitmeterreading_hours) )print ("Einde UH50 telegram" )return#################Csv output #################def csv_heat_telegram():#New filename every daycsv_filename=datetime.datetime.strftime(datetime.datetime.today(), "UH50_"+"%Y-%m-%d"+".csv" )try:#If csv_file exists: open itcsv_file=open(csv_filename, 'rt')csv_file.close()csv_file=open(csv_filename, 'at', newline='', encoding="utf-8")writer = csv.writer(csv_file, dialect='excel', delimiter=';', quoting=csv.QUOTE_NONNUMERIC)except IOError:#Otherwise: create itcsv_file=open(csv_filename, 'wt', newline='', encoding="utf-8")writer = csv.writer(csv_file, dialect='excel', delimiter=';', quoting=csv.QUOTE_NONNUMERIC)#Write csv-headerwriter.writerow(['heat_timestamp','heat_equipment_id','heat_meterreading_energy','heat_unitmeterreading_energy','heat_meterreading_volume','heat_unitmeterreading_volume','heat_meterreading_hours','heat_unitmeterreading_hours'])print ("UH50 telegram in %s gelogd op: %s" % (csv_filename, heat_timestamp) )writer.writerow([heat_timestamp,heat_equipment_id,heat_meterreading_energy,heat_unitmeterreading_energy,heat_meterreading_volume,heat_unitmeterreading_volume,heat_meterreading_hours,heat_unitmeterreading_hours ])csv_file.close()return#################DB output #################def db_heat_telegram():query = "insert into heat_log values (\'" + \heat_timestamp + "\',\'" + \heat_equipment_id + "\',\'" + \str(heat_meterreading_energy) + "\',\'" + \heat_unitmeterreading_energy + "\',\'" + \str(heat_meterreading_volume) + "\',\'" + \heat_unitmeterreading_volume + "\',\'" + \str(heat_meterreading_hours) + "\',\'" + \heat_unitmeterreading_hours + "\')"# print(query)try:db = mysql.connector.connect(user=p1_mysql_user, password=p1_mysql_passwd, host=p1_mysql_host, database=p1_mysql_db)c = db.cursor()c.execute (query)db.commit()print ("UH50 telegram in database %s / %s gelogd op: %s" % (p1_mysql_host, p1_mysql_db, heat_timestamp) )db.close()except:show_error()print ("Fout bij het openen van / schrijven naar database %s / %s. UH50 Telegram wordt gelogd in csv-bestand." % (p1_mysql_host, p1_mysql_db))csv_heat_telegram()return#################################################################################################################################################Main program################################################################################################################################################print ("Landis & Gyr IR Datalogger %s" % version)equipment_prefix = "UH50"comport=0output_mode="scherm"win_os = (os.name == 'nt')if win_os:print("Windows Mode")else:print("Non-Windows Mode")print("Python versie %s.%s.%s" % sys.version_info[:3])#if not MySQL_Loaded==False:# print("MySQL Connector/Python niet gevonden. Database uitvoer niet mogelijk")print ("Control-C om af te breken")#comport parameterstry:comport=int(sys.argv[1])except:print ("Opstart syntaxis: 'heat.py {COM poort-nummer} {uitvoer-modus} {db_host} {db_user} {db_password} {db_database}'")print ("Ontbrekende of verkeerde parameter: COM poort-nummer.")print ("Toegestane waarden:")#scanserial returns win_os serial ports and non win_os USB serial portsprint (scan_serial())print ("Programma afgebroken.")sys.exit()#output_mode parameterstry:output_mode=sys.argv[2]except:print ("Opstart syntaxis: 'heat.py {COM poort-nummer} {uitvoer-modus} {db_host} {db_user} {db_password} {db_database}'")print ("Ontbrekende of verkeerde parameters: ")print ("- Uitvoer-modus. Geldige waarden: 'scherm', 'csv', 'db'. 'scherm' gebruikt")output_mode="scherm"if output_mode not in ["scherm", "csv", "db"]:print ("Opstart syntaxis: 'heat.py {COM poort-nummer} {uitvoer-modus} {db_host} {db_user} {db_password} {db_database}'")print ("Ontbrekende of verkeerde parameters: ")print ("- Uitvoer-modus. Geldige waarden: 'scherm', 'csv', 'db'. 'scherm' gebruikt")output_mode="scherm"#database parametersif output_mode == "db" and MySQL_loaded:try:p1_mysql_host=sys.argv[3]p1_mysql_user=sys.argv[4]p1_mysql_passwd=sys.argv[5]p1_mysql_db=sys.argv[6]except:print ("Opstart syntaxis: 'heat.py {COM poort-nummer} {uitvoer-modus} {db_host} {db_user} {db_password} {db_database}'")print ("Ontbrekende of verkeerde parameters: ")print ("- db_host. 'localhost' gebruikt")print ("- db_user. 'root' gebruikt")print ("- db_password. 'password' gebruikt")print ("- db_database. 'p1' gebruikt")p1_mysql_host='localhost'p1_mysql_user='root'p1_mysql_passwd='password'p1_mysql_db='p1'if output_mode == "db" and not MySQL_loaded:print ("Opstart syntaxis: 'heat.py {COM poort-nummer} {uitvoer-modus} {db_host} {db_user} {db_password} {db_database}'")print ("Ontbrekende of verkeerde parameters: ")print ("- Uitvoer-modus. MySQL Connector/Python niet gevonden. Uitvoer-modus 'db' niet toegestaan. Uitvoer-modus 'csv' gebruikt")output_mode = "csv"#Set COM port config#if comport != 0:# ser = serial.Serial(# baudrate = 300,# bytesize=serial.SEVENBITS,# parity=serial.PARITY_EVEN,# stopbits=1,# xonxoff=0,# rtscts=0,# timeout=2,# port="/dev/ttyAMA0"# )ser = serial.Serial("/dev/ttyAMA0", baudrate=300, bytesize=7, parity="E", stopbits=1, timeout=2, xonxoff=0, rtscts=0)#Show startup argumentsprint ("Opstart parameters:")if comport != 0:if win_os:print ("COM poort-nummer: %d (%s)" % (comport, ser.name) )else:# ser.name property is not available in Linux.port="/dev/ttyAMA"+str(comport-1) # Linux Style for /dev/ttyAMA0, /dev/ttyUSB1, etc...print ("COM poort-nummer: %d (%s)" % (comport, port) )else:print ("COM poort-nummer: NVT, Interne testdata wordt gebruikt")print ("Uitvoer-modus: %s" % output_mode )if output_mode == "db":print ("MySQL-verbinding: %s / %s" % (p1_mysql_host, p1_mysql_db) )if comport == 0:################################################################## Use test values instead of COM port reading ##################################################################ir_buffer = "/LUGC2WR5\r\n"ir_lines = ir_buffer.strip().split('\r\n')ir_buffer = "6.8(0347.292*GJ)6.26(02647.89*m3)9.21(65298392)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.26*01(02378.83*m3)6.8*01(0311.399*GJ)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "F(0)9.20(65298392)6.35(60*m)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.6(0023.8*kW)6.6*01(0023.8*kW)6.33(000.636*m3ph)9.4(099*C&090*C)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.31(0069294*h)6.32(0000343*h)9.22(R)9.6(000&65298392&0)9.7(20000)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.32*01(0000343*h)6.36(01-01)6.33*01(000.636*m3ph)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.8.1()6.8.2()6.8.3()6.8.4()6.8.5()\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.8.1*01()6.8.2*01()6.8.3*01()\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.8.4*01()6.8.5*01()\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "9.4*01(099*C&090*C)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.36.1(2006-02-17)6.36.1*01(2006-02-17)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.36.2(2011-12-21)6.36.2*01(2011-12-21)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.36.3(2006-03-23)6.36.3*01(2006-03-23)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.36.4(2006-02-21)6.36.4*01(2006-02-21)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "6.36.5(2000-00-00)6.36*02(01)9.36(2013-10-04&12:56:50)9.24(1.5*m3ph)\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "9.17(0)9.18()9.19()9.25()\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "9.1(0&1&0&-&CV&3&2.20)9.2(&&)0.0(65298392)!\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))ir_buffer = "h0\r\n"ir_lines.extend(ir_buffer.strip().split('\r\n'))else:################################################################## COM port reading ###################################################################Open COM porttry:ser = serial.Serial("/dev/ttyAMA0", baudrate=300, bytesize=7, parity="E", stopbits=1, timeout=2, xonxoff=0, rtscts=0)# ser.open()except:if win_os:sys.exit ("Fout bij het openen van %s. Programma afgebroken." % ser.name)else:sys.exit ("Fout bij het openen van %s. Programma afgebroken." % port)print ("Activatie poort.")# Wake up# ser.setRTS(False)# ser.setDTR(False)sleep(5)# ser.setDTR(True)# ser.setRTS(True)ir_command=("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2F\x3F\x21\x0D\x0A")ser.write(ir_command.encode('utf-8'))sleep(1.5)#Initializeprint ("Initialisatie op 300 baud")ir_command='/?!\x0D\x0A'ser.write(ir_command.encode('utf-8'))ser.flush()#Wait for initialize confirmationir_buffer = ''while '/LUGCUH50\r\n' not in ir_buffer:ir_buffer = str(ser.readline(), "utf-8")if '/?!\x0D\x0A' in ir_buffer:ir_buffer = str(ser.readline(), "utf-8")ir_lines = ir_buffer.strip().split('\r\n')print ("Gegevensuitwisseling op 2400 baud")#Set to 2400baudser.baudrate = 2400#Wait for datair_buffer = ''ETX = Falsewhile not ETX:ir_buffer = str(ser.readline(), "utf-8")if '\x03' in ir_buffer:ETX = True#Strip the STX characterir_buffer = ir_buffer.replace('\x02','')#Strip the ! characterir_buffer = ir_buffer.replace('!','')#Strip the ETX characterir_buffer = ir_buffer.replace('\x03','')ir_lines.extend(ir_buffer.strip().split('\r\n'))print ("Gegevensuitwisseling voltooid")#Close port and show statustry:ser.close()except:if win_os:sys.exit ("Fout bij het sluiten van %s. Programma afgebroken." % ser.name)else:sys.exit ("Fout bij het sluiten van %s. Programma afgebroken." % port)################################################################## Process data ###################################################################print ("Number of received elements: %d" % len(ir_lines))#print ("Array of received elements: %s" % ir_lines)heat_timestamp=datetime.datetime.strftime(datetime.datetime.today(), "%Y-%m-%d %H:%M:%S" )heat_data = ir_linesnum_elements = len(ir_lines)#print("Number of elements: %d"% num_elements)#parse all heat_data elementsi=0while i<num_elements:# print("Elements index: %d"% i)heat_element = heat_data[i]# print(heat_element)if heat_element.find("0.0(")!=-1:#heat_equipment_id#0.0(11 digits C/N)heat_num_start=heat_element.find("0.0(")+4heat_num_end=heat_element.find(")",heat_num_start)heat_equipment_id = equipment_prefix + "_" + heat_element[heat_num_start:heat_num_end]if heat_element.find("6.8(")!=-1:#heat_meterreading_energy, heat_unitmeterreading_energy#6.8(Energy * unit)heat_num_start = heat_element.find("6.8(") +4heat_num_end=heat_element.find("*",heat_num_start)heat_meterreading_energy = float(heat_element[heat_num_start:heat_num_end])heat_num_start = heat_num_end+1heat_num_end=heat_element.find(")",heat_num_start)heat_unitmeterreading_energy = heat_element[heat_num_start:heat_num_end]if heat_element.find("6.26(")!=-1:#heat_meterreading_volume, heat_unitmeterreading_volume#6.26(Volume * m3)heat_num_start = heat_element.find("6.26(") +5heat_num_end=heat_element.find("*",heat_num_start)heat_meterreading_volume = float(heat_element[heat_num_start:heat_num_end])heat_num_start = heat_num_end+1heat_num_end=heat_element.find(")",heat_num_start)heat_unitmeterreading_volume = heat_element[heat_num_start:heat_num_end]if heat_element.find("6.31(")!=-1:#heat_meterreading_hours, heat_unitmeterreading_hours#6.31(Hours * h)heat_num_start = heat_element.find("6.31(") +5heat_num_end=heat_element.find("*",heat_num_start)heat_meterreading_hours = float(heat_element[heat_num_start:heat_num_end])heat_num_start = heat_num_end+1heat_num_end=heat_element.find(")",heat_num_start)heat_unitmeterreading_hours = heat_element[heat_num_start:heat_num_end]i+=1################################################################## Output based on startup parameter 'output_mode' ###################################################################Output to schermif output_mode=="scherm": print_heat_telegram()#Output to csv_fileif output_mode=="csv": csv_heat_telegram()#Output to databaseif output_mode=="db": db_heat_telegram()