Introduction / Overview of the device to be hacked
The pressure monitor consists of 2 devices.
The first device is installed on a DIN-rail and includes the power supply and a relais to switch of the ventilation system.
The second device consists of 2 parts, that work more or less independent. Part 1 is just a small PCB that is hidden in the wall. It has the sensor for pressure and a connection for a Pt1000 that is applied to the pipe between oven and chimney.
The second part (of device 2) has a touchdisplay and is installed near the oven. By design it is assembled in the same housing as Part1.
All of these devices communicate via CAN-Bus, so i attached an additional device to this bus to read out all these values.
The goal was twofold:
1. get the information about switch off of the ventilation system to also switch off the fume hood.
2. get the information about the oven being fired to get a feeling how often i use the oven in the winter
(3. because i can)
Understanding the communication
First step was using an oscilloscope to determine a) which is can-high and can-low and b) determine the baudrate.
Using some Raspberry pi can hat, the following settings need to be done:
ip link set can0 type can bitrate 125000
ip link set up can0
by using "candump -a any", the following can be seen:
can0 28A [8] 55 68 26 04 05 06 07 0D 'Uh&.....'
can0 28A [8] 00 16 80 13 00 00 00 0D '........'
can0 28A [8] 01 C4 07 78 0A 01 00 0D '...x....'
can0 28A [8] 09 6E 86 00 00 00 00 0A '.n......'
The CAN communication is all done on the same ID 28A. It comprises of 4 conescutive messages. The first and last bytes are used for signalling.
The first message begins with 0x55 to determine the the start of the sequence. After that, the first byte is used as a multiplexor for the messages. The last byte tells us if there are more messages (0x0D) or if it is the final message (0x0A).
With this information, the bytes can be put together in a bigger array to go hunting for the information.
Since the display of the LUC2 shows all of the information (some in sub menus) and some can be changed by just using the oven, determining which bytes contain which value was relatively easy.
Code for using the information
import can
import struct
import paho.mqtt.client as mqtt
bus=can.Bus(interface='socketcan',channel='can0')
def parsemsg(data):
outdata = []
msgid = 255
if len(data) < 6:
return outdata, 4
for i in range(6):
outdata.append(data[i+1])
if data[0] == 0x55:
msgid = 0
if data[0] == 0:
msgid = 1
if data[0] == 1:
msgid = 2
if data[0] == 9:
msgid = 3
return outdata, msgid
def concatdata(data):
payload = []
for msg in data:
for i in msg:
payload.append(i)
return payload
data = []
raw = []
for i in range(5):
raw.append([])
mqttc = mqtt.Client()
mqttc.connect("192.168.186.10", 1883, 60)
count = 10
tempfilter = 0
for msg in bus:
payload, msgid = parsemsg(msg.data)
if msgid <=4:
while len(data) <= msgid:
dummy = []
data.append(dummy)
data[msgid] = payload
raw[msgid] = msg.data
if msgid == 3:
# ende
rawdata = concatdata(data)
# nur die nutzdaten
# alles, incl header, footer, sonstiges
complete = concatdata(raw)
# print(complete)
if len(rawdata) >= 24:
temp = rawdata[8] + (256 * rawdata[9])
tempfilter += temp
count = count -1
if count == 0:
count = 10
druck = rawdata[6]
if rawdata[7] == 0:
druck = druck * -1
else:
hochdruck = (rawdata[7] - 128) * 256
druck += hochdruck
druck = druck/10
mqttc.publish("/druckwaechter/druck", payload=druck)
tempfiltered = tempfilter / 10
print(rawdata)
mqttc.publish("/druckwaechter/temperatur", payload=temp)
aktiv = rawdata[16]
mqttc.publish("/druckwaechter/lueftungaktiv", payload=aktiv)
zeitinaktiv = rawdata[17]
mqttc.publish("/druckwaechter/zeitinaktiv", payload=zeitinaktiv)
offsetdruck =...
Read more »