Hi all,
this thread is dead for 1 year, but maybe you can help me.
I'm trying to achieve more or less the same as what timkoers did : inject data on the P1 port.
The reason for doing so is that I have a smartmeter, with P1 port, but here in Luxembourg the data is encrypted.
So the toon would be unable to read it.
I have a RPi reading the data, unencrypting it, and sending to another RPi running domoticz.
First of all the USB-to-serial cable is a specific one that inverts the level.
It works fine for read, and I assume I can use the same for wirting, connecting it to the zwave appliance.
-> maybe this first assumption is wrong, but I don't know how to check if this cable works for both read and write.
I bought it here :
https://webshop.cedel.nl/Slimme-meter-kabel-P1-naar-USB
I configured the toon to work with a P1 smartmeter.
Nothing specific here, I have the green flag on the meter.
Then I used the code provided by timkoers. (but adapted for now in order to not wait for anything from mqtt. I just hardcoded a copy of a data received from my own smartmeter)
It seems I never receive the rts from the toon.
Or actually maybe the opposite : it seems rts is always high since the my software sends the data every seconds. There's no wait for the toon.
Code: Select all
#!/usr/bin/env python
#
import re
import os
import serial
from serial import Serial
import time
import datetime
from time import sleep # import the time function from the sleep library
import crcmod.predefined
from parse import parse
# Program variables
# The true telegram ends with an exclamation mark after a CR/LF
pattern = re.compile(b'\r\n(?=!)')
#pattern = re.compile(b'\n(?=!)')
# According to the DSMR spec, we need to check a CRC16
crc16 = crcmod.predefined.mkPredefinedCrcFun('crc16')
# Create an empty telegram
checksum_found = False
good_checksum = False
checksum = 0
# define ttyUSB0 as serial
#Serial port configuration
ser = serial.Serial()
ser.baudrate = 115200
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.xonxoff = 0
ser.rtscts = 0
ser.timeout = 1
ser.write_timeout = 1.0
ser.port = "/dev/ttyUSB0"
ser.open()
def calculateCRC(injectedTelegram):
calculated_checksum = 0
for m in pattern.finditer(injectedTelegram):
# Remove the exclamation mark from the checksum,
# and make an integer out of it.
# given_checksum = "0x" + int(telegram[m.end() + 1:].decode('ascii'), 16)
# The exclamation mark is also part of the text to be CRC16'd
calculated_checksum = crc16(injectedTelegram[:m.end() + 1])
return calculated_checksum
def fillTelegram() :
timeString = "{:0>2d}".format(datetime.datetime.now().year-2000) + "{:0>2d}".format(datetime.datetime.now().month) + "{:0>2d}".format(datetime.datetime.now().day) + "{:0>2d}".format(datetime.datetime.now().hour) + "{:0>2d}".format(datetime.datetime.now().minute) + "{:0>2d}".format(datetime.datetime.now().second) + "S" if time.localtime().tm_isdst is 1 else "W"
injectedTelegram = "/Lux5\253663629_D\r\n\r\n\
1-3:0.2.8(42)\r\n\
0-0:1.0.0(190916204632S)\r\n\
0-0:42.0.0(53414731303330373030333035353037)\r\n\
1-0:1.8.0(001157.757*kWh)\r\n\
1-0:2.8.0(000000.003*kWh)\r\n\
1-0:3.8.0(000005.312*kvarh)\r\n\
1-0:4.8.0(000420.219*kvarh)\r\n\
1-0:1.7.0(01.190*kW)\r\n\
1-0:2.7.0(00.000*kW)\r\n\
1-0:3.7.0(00.154)\r\n\
1-0:4.7.0(00.057)\r\n\
0-0:17.0.0(77.376)\r\n\
0-0:96.3.10(1)\r\n\
0-0:96.7.21(00013)\r\n\
1-0:32.32.0(00002)\r\n\
1-0:52.32.0(00002)\r\n\
1-0:72.32.0(00002)\r\n\
1-0:32.36.0(00000)\r\n\
1-0:52.36.0(00000)\r\n\
1-0:72.36.0(00000)\r\n\
0-0:96.13.0()\r\n\
0-0:96.13.2()\r\n\
0-0:96.13.3()\r\n\
0-0:96.13.4()\r\n\
0-0:96.13.5()\r\n\
1-0:31.7.0(000*A)\r\n\
1-0:51.7.0(000*A)\r\n\
1-0:71.7.0(004*A)\r\n\
!71B3"
# checksum = calculateCRC(injectedTelegram)
# injectedTelegram += format(checksum,"04X") + "\r\n"
return injectedTelegram
######################
# *** Start here *** #
######################
receivedTelegram = False
lastTelegram = datetime.datetime.now()
shouldWait = True
msg = ""
while True:
if shouldWait:
# Wait for the Toon to stop requesting data
shouldWait = not ser.rts
msg = fillTelegram()
print "Waiting..."
else:
if ser.rts:
msg = fillTelegram()
if abs(datetime.datetime.now().second - lastTelegram.second) >= 1:
if True:
print "Sending " + msg
pass
try:
ser.write(msg)
ser.flush()
except:
print("Exception!")
pass
lastTelegram = datetime.datetime.now()
shouldWait = True
else:
pass
To start hdrv_p1 -vvvv , I first had to edit inittab since that process is respawning autoöatically.
So I was not able to kill it. I guess having 2 hdrv_p1 processes at the same time is not a good idea.
In the end it works, and only one process is running, the one I start manually.
From another ssh session I can see the following :
Code: Select all
eneco-001-151219:~# ps | grep hdrv
693 root 24424 S {hdrv_hue} HCBv2 hdrv_hue [OK] [S1|N1]
698 root 39996 S {hdrv_zwave} HCBv2 hdrv_zwave [OK] [F5BDD5D5 SIS 3.67] [S1|N1]
5127 root 22336 S {hdrv_p1} HCBv2 hdrv_p1 [OK] [C:OK E:COM (P1) ] [S99|N0]
5171 root 3236 S grep hdrv
The only difference between the one I start from the command line, and the, let's say, original one, it that in the end I have S99|N0 instead of S1|N1
Here is the "original" one :
Code: Select all
eneco-001-151219:~# ps | grep hdrv
693 root 24424 S {hdrv_hue} HCBv2 hdrv_hue [OK] [S1|N1]
698 root 39996 S {hdrv_zwave} HCBv2 hdrv_zwave [OK] [F5BDD5D5 SIS 3.67] [S1|N1]
3772 root 22336 S {hdrv_p1} HCBv2 hdrv_p1 [OK] [C:OK E:COM (P1) ] [S1|N1]
3839 root 3236 S grep hdrv
From the logs of hdrv_p1 I can see something that looks strange (but maybe not an issue ...) :
Code: Select all
[hdrv_p1:/tmp/sonar-scanner/jenkins/workspace/qmf_hdrv_p1-Pipeline_master/application/hdrv_p1/src/hdrv_p1.c@initVars():1328]ERROR: No profile 'Metering' found
[hdrv_p1]initting type:usageInfo, intAddr:elec_delivered_total.304d8722-58c9-49b9-8342-2214372ef544, zombie:0, orphan:0
[hdrv_p1:/tmp/sonar-scanner/jenkins/workspace/qmf_hdrv_p1-Pipeline_master/application/hdrv_p1/src/hdrv_p1.c@initVars():1328]ERROR: No profile 'Metering' found
[hdrv_p1]initting type:usageInfo, intAddr:elec_delivered_nt.304d8722-58c9-49b9-8342-2214372ef544, zombie:0, orphan:0
[hdrv_p1:/tmp/sonar-scanner/jenkins/workspace/qmf_hdrv_p1-Pipeline_master/application/hdrv_p1/src/hdrv_p1.c@initVars():1328]ERROR: No profile 'Metering' found
[hdrv_p1]initting type:usageInfo, intAddr:elec_received_nt.304d8722-58c9-49b9-8342-2214372ef544, zombie:0, orphan:0
[hdrv_p1:/tmp/sonar-scanner/jenkins/workspace/qmf_hdrv_p1-Pipeline_master/application/hdrv_p1/src/hdrv_p1.c@initVars():1328]ERROR: No profile 'Metering' found
[hdrv_p1]initting type:usageInfo, intAddr:elec_delivered_lt.304d8722-58c9-49b9-8342-2214372ef544, zombie:0, orphan:0
[hdrv_p1:/tmp/sonar-scanner/jenkins/workspace/qmf_hdrv_p1-Pipeline_master/application/hdrv_p1/src/hdrv_p1.c@initVars():1328]ERROR: No profile 'Metering' found
[hdrv_p1]initting type:usageInfo, intAddr:elec_received_lt.304d8722-58c9-49b9-8342-2214372ef544, zombie:0, orphan:0
[hdrv_p1:/tmp/sonar-scanner/jenkins/workspace/qmf_hdrv_p1-Pipeline_master/application/hdrv_p1/src/hdrv_p1.c@initVars():1328]ERROR: No profile 'Metering' found
In the end it behaves like if the cable is not connected at all.....