Moin,
leider habe ich kein Plugin für Smarthome.py zu diesem Thema gefunden, jedoch für Wiregate und OpenHAB
Wiregate https://knx-user-forum.de/forum/suppo...arregler-resol
...und auch eine Diskussion zu OpenHAB https://knx-user-forum.de/forum/supp...en/openhab/821
Daher habe ich ein Plugin "geschrieben", mit dem die Daten meiner Solarthermie Anlage ausgelesen werden.
Mein Regler der Solarthermie Anlage ist ähnlich zum "Resol Systemregler DeltaSol® E" http://www.resol.de/index/produktdet...d/8/sprache/de nämlich eine "Cosmo Multi" http://www.cosmo-info.de/fileadmin/u...OSMO-Multi.pdf
Das Skript basiert auf diesem Python2 Skript
https://github.com/herbstmensch/resol-vbus-python
Die Daten aus diesem Skript werden mittels "Pickle" in eine temporäre Datei geschrieben, die vom Smarthome-Plugin ausgelesen werden.
(Nicht schön - läuft jedoch :-)
Nun die Codeschnipsel, die Ihr gerne in Github übernehmen & optimieren dürft:
README.md
__init__.py
resol_background.py
config.py --> IP und Passwort editieren
spec.py (unverändert)
VBusSpecificationCosmoMulti2012.json
leider habe ich kein Plugin für Smarthome.py zu diesem Thema gefunden, jedoch für Wiregate und OpenHAB
Wiregate https://knx-user-forum.de/forum/suppo...arregler-resol
...und auch eine Diskussion zu OpenHAB https://knx-user-forum.de/forum/supp...en/openhab/821
Daher habe ich ein Plugin "geschrieben", mit dem die Daten meiner Solarthermie Anlage ausgelesen werden.
Mein Regler der Solarthermie Anlage ist ähnlich zum "Resol Systemregler DeltaSol® E" http://www.resol.de/index/produktdet...d/8/sprache/de nämlich eine "Cosmo Multi" http://www.cosmo-info.de/fileadmin/u...OSMO-Multi.pdf
Das Skript basiert auf diesem Python2 Skript
https://github.com/herbstmensch/resol-vbus-python
Die Daten aus diesem Skript werden mittels "Pickle" in eine temporäre Datei geschrieben, die vom Smarthome-Plugin ausgelesen werden.
(Nicht schön - läuft jedoch :-)
Nun die Codeschnipsel, die Ihr gerne in Github übernehmen & optimieren dürft:
README.md
Code:
# Resol
## Requirements/Description
Description:
Connects to read-only RESOL VBUS Data over LAN
Requirements:
Edit config.py (not yet done via Smarthome.py config)
Add Resol specific *.json files with content of VBUS
Python2 needed for Python-Script to read VBUS Data over LAN, source: https://github.com/herbstmensch/resol-vbus-python
Writeable directory to save output of async-data (Exchange of Python2 -> Phyton3 Script)
## Supported Hardware
I.e. Resol VBUS Data over LAN: http://www.resol.de/index/produktdetail/kategorie/1/id/76/sprache/en
## Configuration
### plugin.conf
[resol]
class_name = Resol
class_path = plugins.resol
host = localhost # ip of ebusd
cycle = 60 # cycle of each item
# port = 7053 # port of VBUS
# username = 'USERNAME'
# password = 'PASSWORD'
### items.conf
Items need parameter "json_variable"-
[resol]
[[temperature_solar_outside]]
type = num
knx_dpt = 5
knx_send = 15/0/0
knx_reply = 15/0/0
json_variable = "Temperatur Sensor 1"
[[temperature_heating_returnflow_unmixed]]
type = num
knx_dpt = 5
knx_send = 15/0/1
knx_reply = 15/0/1
json_variable = "Temperatur Sensor 7"
[[temperature_heating_returnflow_mixed]]
type = num
knx_dpt = 5
knx_send = 15/0/2
knx_reply = 15/0/2
json_variable = "Temperatur Sensor 8"
Code:
#!/usr/bin/env python3
#
#########################################################################
# Copyright 2015 KNX-Username : KHome
# Inspired by eBus Plug-in & Git-Hub project by "Herbstmensch"
# Includes parts of: https://github.com/herbstmensch/resol-vbus-python
#########################################################################
# Free for non-commercial use
#########################################################################
import pickle
import time
import subprocess
import sys
import logging
import socket
import threading
logger = logging.getLogger('resol')
class Resol():
_items = []
def __init__(self, smarthome, host, username=None, password=None, cycle=60):
self._sh = smarthome
self._host = host
self._cycle = int(cycle)
self._username = username
self._password = password
self.refresh_cycle = self._cycle
#logging.warning("Test Init Phase, starting python2")
self._var = subprocess.Popen(['python2', '/home/pi/smarthome/plugins/resol/resol_background.py'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) #start data receiving in while-loop and save variales via python pickle to a temp file, uses python2
def run(self):
logging.warning("run function")
self.alive = True
self._sh.scheduler.add('resolcycle', self.refresh, prio=5, cycle=self._cycle, offset=2)
# if you want to create child threads, do not make them daemon = True!
# They will not shutdown properly. (It's a python bug)
#
def stop(self):
self.alive = False
def parse_item(self, item):
if 'json_variable' in item.conf:
self._items.append(item)
return self.update_item
#logger.debug("parse item: {0}".format(item))
#
##skeleton part
# def parse_logic(self, logic):
# if 'xxx' in logic.conf:
# # self.function(logic['name'])
# pass
#
def update_item(self, item, caller=None, source=None, dest=None):
#logging.warning("update function")
if caller != 'Resol':
#logger.info("update item: {0}".format(item.id()))
value = str(int(item()))
def refresh(self):
#logging.warning("refresh function")
for item in self._items:
time.sleep(1)
resol_variable = item.conf['json_variable']
value = self.request(resol_variable)
#logging.warning(resol_variable)
#logging.warning(value)
#if reading fails (i.e. at broadcast-commands) the value will not be updated
if value is not None:
item(value, 'resol', 'refresh')
if not self.alive:
brea
def request(self, request):
#logging.warning("request function")
try:
fp = open("/tmp/shared.pkl",'rb')
#logging.warning(request)
shared = pickle.load(fp)
answer = shared[request].rsplit(";",2)[0]
#logging.warning(answer)
return answer
except:
logger.warning("Unexpected error: resol reading shared.pkl")
#logger.warning("Unexpected error:", sys.exc_info()[0])
Code:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#Talk with Resol VBUS over LAN
# https://github.com/herbstmensch/resol-vbus-python
import socket
import time
import sys
import json
import pickle
import codecs
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')
# Load settings
try:
import config
except:
sys.exit("config.py not found!")
# Load Message specification
try:
import spec
except:
sys.exit("Could not load Message Specification")
# Logs in onto the DeltaSol BS Plus over LAN. Also starts (and maintains) the
# actual stream of data.
def login():
dat = recv()
#Check if device answered
if dat != "+HELLO\n":
return False
#Send Password
send("PASS %s\n" % config.vbus_pass)
dat = recv()
return dat.startswith("+OK")
def load_data():
#Request Data
global new_data
send("DATA\n")
dat = recv()
#Check if device is ready to send Data
if not dat.startswith("+OK"):
return
init_first = 1
timeout = time.time() + 60*2
while len(result) < config.expected_packets and time.time() < timeout:
if time.time() > timeout:
break
else:
timeout = time.time() + 60*2
buf = readstream()
msgs = splitmsg(buf)
for msg in msgs:
if "PV1" == get_protocolversion(msg):
if init_first == 1:
result2 = {}
new_data = parse_payload(msg, True, result2)
init_first = init_first+1
else:
old_data = new_data
result2 = {}
new_data = parse_payload(msg, False,result2)
if isinstance(new_data,dict) and isinstance(old_data,dict) :
check_changes(old_data, new_data)
if config.debug:
print format_message_pv1(msg)
elif "PV2" == get_protocolversion(msg):
if config.debug:
print format_message_pv2(msg)
# Receive 1024 bytes from stream
def recv():
dat = sock.recv(1024)
return dat
def check_changes(old_data, new_data):
if cmp(old_data, new_data) == 0:
a=0
# they are the same
else:
#print "not the same"
#
# continoues reading, write to file, uses module pickle
d= DictDiffer(old_data,new_data)
changedlist= list(d.changed())
#shared = unicode(new_data, 'utf-8')
shared = new_data
fp = codecs.open("/tmp/shared.pkl","w", 'utf-8')
#fp = codecs.open("shared.pkl","w")
pickle.dump(shared, fp)
fp.close
#
#for field in (changedlist):
# print field + "; " + new_data[field]
# print field['name'] + ": "+ result[get_source_name(msg)][field['name'][0]]
# Sends given bytes over the stram. Adds debug
def send(dat):
sock.send(dat)
# Read Data until minimum 1 message is received
def readstream():
data = recv()
while data.count(chr(0xAA)) < 4:
data += recv()
return data
#Split Messages on Sync Byte
def splitmsg(buf):
return buf.split(chr(0xAA))[1:-1]
# Format 1 byte as String
def format_byte(byte):
return hex(ord(byte))[0:2] + '0' + hex(ord(byte))[2:] if len(hex(ord(byte))) < 4 else hex(ord(byte))
# Extract protocol Version from msg
def get_protocolversion(msg):
if hex(ord(msg[4])) == '0x10': return "PV1"
if hex(ord(msg[4])) == '0x20': return "PV2"
if hex(ord(msg[4])) == '0x30': return "PV3"
return "UNKNOWN"
# Extract Destination from msg
def get_destination(msg):
return format_byte(msg[1]) + format_byte(msg[0])[2:]
#Extract source from msg
def get_source(msg):
return format_byte(msg[3]) + format_byte(msg[2])[2:]
# Extract command from msg
def get_command(msg):
return format_byte(msg[6]) + format_byte(msg[5:6])[2:]
# Get count of frames in msg
def get_frame_count(msg):
return gb(msg, 7, 8)
# Extract payload from msg
def get_payload(msg):
payload = ''
for i in range(get_frame_count(msg)):
payload += integrate_septett(msg[9+(i*6):15+(i*6)])
return payload
# parse payload and put result in result
def parse_payload(msg, printall, packetdict):
payload = get_payload(msg)
for packet in spec.spec['packet']:
if packet['source'] == get_source(msg) and packet['destination'] == get_destination(msg) and packet['command'] == get_command(msg):
#print packet
for field in packet['field']:
# result[get_source_name(msg)][field['name']] = str(gb(payload, int(field['offset']), int(field['offset'])+((int(field['bitSize'])+1) / 8)) * (float(field['factor']) if field.has_key('factor') else 1)) + field['unit'] if 'unit' in field else ''
if field.has_key('offset'):
packetdict[field['name']] = str(gb(payload, int(field['offset']), int(field['offset'])+((int(field['bitSize'])+1) / 8)) * (float(field['factor']) if field.has_key('factor') else 1)) + "; " + (field['unit'] if field.has_key('unit') else '')
if printall:
# initial reading, write to file, uses module pickle
#shared = unicode(packetdict, 'utf-8')
shared = packetdict
fp = codecs.open("/tmp/shared.pkl","w", 'utf-8')
#fp = codecs.open("shared.pkl","w")
pickle.dump(shared, fp)
fp.close
#print field['name'] + "; "+ packetdict[field['name']]
return packetdict
def format_message_pv1(msg):
parsed = "PARSED: \n"
parsed += " ZIEL".ljust(15,'.')+": " + get_destination(msg) + "\n"
parsed += " QUELLE".ljust(15,'.')+": " + get_source(msg) + " " + get_source_name(msg) + "\n"
parsed += " PROTOKOLL".ljust(15,'.')+": " + get_protocolversion(msg) + "\n"
parsed += " BEFEHL".ljust(15,'.')+": " + get_command(msg) + "\n"
parsed += " ANZ_FRAMES".ljust(15,'.')+": " + str(get_frame_count(msg)) + "\n"
parsed += " CHECKSUM".ljust(15,'.')+": " + format_byte(msg[8]) + "\n"
for i in range(get_frame_count(msg)):
integrated = integrate_septett(msg[9+(i*6):15+(i*6)])
parsed += (" NB"+str(i*4+1)).ljust(15,'.')+": " + format_byte(msg[9+(i*6)]) + " - " + format_byte(integrated[0]) + "\n"
parsed += (" NB"+str(i*4+2)).ljust(15,'.')+": " + format_byte(msg[10+(i*6)]) + " - " + format_byte(integrated[1]) + "\n"
parsed += (" NB"+str(i*4+3)).ljust(15,'.')+": " + format_byte(msg[11+(i*6)]) + " - " + format_byte(integrated[2]) + "\n"
parsed += (" NB"+str(i*4+4)).ljust(15,'.')+": " + format_byte(msg[12+(i*6)]) + " - " + format_byte(integrated[3]) + "\n"
parsed += (" SEPTETT"+str(i+1)).ljust(15,'.')+": " + format_byte(msg[13+(i*6)]) + "\n"
parsed += (" CHECKSUM"+str(i+1)).ljust(15,'.')+": " + format_byte(msg[14+(i*6)]) + "\n"
parsed += " PAYLOAD".ljust(15,'.')+": " + (" ".join(format_byte(b) for b in get_payload(msg)))+"\n"
return parsed
def format_message_pv2(msg):
parsed = "PARSED: \n"
parsed += " ZIEL1".ljust(15,'.')+": " + format_byte(msg[0:1]) + "\n"
parsed += " ZIEL2".ljust(15,'.')+": " + format_byte(msg[1:2]) + "\n"
parsed += " QUELLE1".ljust(15,'.')+": " + format_byte(msg[2:3]) + "\n"
parsed += " QUELLE2".ljust(15,'.')+": " + format_byte(msg[3:4]) + "\n"
parsed += " PROTOKOLL".ljust(15,'.')+": " + format_byte(msg[4:5]) + "\n"
parsed += " BEFEHL1".ljust(15,'.')+": " + format_byte(msg[5:6]) + "\n"
parsed += " BEFEHL2".ljust(15,'.')+": " + format_byte(msg[6:7]) + "\n"
parsed += " ID1".ljust(15,'.')+": " + format_byte(msg[7:8]) + "\n"
parsed += " ID2".ljust(15,'.')+": " + format_byte(msg[8:9]) + "\n"
parsed += " WERT1".ljust(15,'.')+": " + format_byte(msg[9:10]) + "\n"
parsed += " WERT2".ljust(15,'.')+": " + format_byte(msg[10:11]) + "\n"
parsed += " WERT3".ljust(15,'.')+": " + format_byte(msg[11:12]) + "\n"
parsed += " WERT4".ljust(15,'.')+": " + format_byte(msg[12:13]) + "\n"
parsed += " SEPTETT".ljust(15,'.')+": " + format_byte(msg[13:14]) + "\n"
parsed += " CHECKSUM".ljust(15,'.')+": " + format_byte(msg[14:15]) + "\n"
return parsed
def get_compare_length(mask):
i = 1
while i < 6 and mask[i] != '0':
i += 1
return i+1
def get_source_name(msg):
src = format_byte(msg[3]) + format_byte(msg[2])[2:]
for device in spec.spec['device']:
if src[:get_compare_length(device['mask'])] == device['address'][:get_compare_length(device['mask'])]:
return device['name'] if get_compare_length(device['mask']) == 7 else str(device['name']).replace('#',device['address'][get_compare_length(device['mask'])-1:],1)
return ""
def integrate_septett(frame):
data = ''
septet = ord(frame[4])
for j in range(4):
if septet & (1 /< /< j):
data += chr(ord(frame[j]) | 0x80)
else:
data += frame[j]
return data
class DictDiffer(object):
"""
Calculate the difference between two dictionaries as:
(1) items added
(2) items removed
(3) keys same in both but changed values
(4) keys same in both and unchanged values
"""
def __init__(self, current_dict, past_dict):
self.current_dict, self.past_dict = current_dict, past_dict
self.current_keys, self.past_keys = [
set(d.keys()) for d in (current_dict, past_dict)
]
self.intersect = self.current_keys.intersection(self.past_keys)
def added(self):
return self.current_keys - self.intersect
def removed(self):
return self.past_keys - self.intersect
def changed(self):
return set(o for o in self.intersect
if self.past_dict[o] != self.current_dict[o])
def unchanged(self):
return set(o for o in self.intersect
if self.past_dict[o] == self.current_dict[o])
# Gets the numerical value of a set of bytes (respect Two's complement by value Range)
def gb(data, begin, end): # GetBytes
wbg = sum([0xff /< /< (i * 8) for i, b in enumerate(data[begin:end])])
s = sum([ord(b) /< /< (i * 8) for i, b in enumerate(data[begin:end])])
if s >= wbg/2:
s = -1 * (wbg - s)
return s
if __name__ == '__main__':
while 1:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(config.address)
result = dict()
login()
load_data()
# print json.dumps(result)
try:
sock.shutdown(0)
except:
pass
sock.close()
sock = None
time.sleep(3)
Code:
address = ("192.168.178.x", 7053)
vbus_pass = "PASSWORD"
spec_file = "/home/pi/smarthome/plugins/resol/VBusSpecificationCosmoMulti2012.json"
debug = False
expected_packets = 2
Code:
#!/usr/bin/env python2
__author__ = 'Tim'
import json
import sys
import config
# Load given specFile. Specfile was created from original
# RESOL Configuration File XML shippes with RSC (Resol Service Center)
# using XML to JSON converter at http://www.utilities-online.info/xmltojson
with open(config.spec_file) as json_data:
data = json.load(json_data)
try:
spec = data['vbusSpecification']
except:
sys.exit('Cannot load Spec')
if config.debug:
for device in spec['device']:
print device
for packet in spec['packet']:
print packet
for field in packet['field']:
print " " + str(field)
json_data.close()
Code:
{
"vbusSpecification": {
"device": [
{
"address": "0x7821",
"mask": "0xFFFF",
"name": "COSMO Multi",
"isMaster": "true"
},
{
"address": "0x7822",
"mask": "0xFFFF",
"name": "COSMO Multi WMZ",
"isMaster": "false"
},
{
"address": "0x7831",
"mask": "0xFFFF",
"name": "COSMO Multi HK 1 Estrichtrockung Modul 1",
"isMaster": "false"
},
{
"address": "0x7832",
"mask": "0xFFFF",
"name": "COSMO Multi HK 2 Estrichtrockung Modul 2",
"isMaster": "false"
},
{
"address": "0x7833",
"mask": "0xFFFF",
"name": "COSMO Multi HK 3 Estrichtrockung Modul 3",
"isMaster": "false"
},
{
"address": "0x7834",
"mask": "0xFFFF",
"name": "COSMO Multi HK Estrichtrockung Lokal",
"isMaster": "false"
}
],
"packet": [
{
"destination": "0x0010",
"source": "0x7821",
"command": "0x0100",
"field": [
{
"-commonUsage": "collector1",
"offset": "0",
"name": "Temperatur Sensor 1",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"-commonUsage": "store1",
"offset": "2",
"name": "Temperatur Sensor 2",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "4",
"name": "Temperatur Sensor 3",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "6",
"name": "Temperatur Sensor 4",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "8",
"name": "Temperatur Sensor 5",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "10",
"name": "Temperatur Sensor 6",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "12",
"name": "Temperatur Sensor 7",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "14",
"name": "Temperatur Sensor 8",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "16",
"name": "Temperatur Sensor 9",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "18",
"name": "Temperatur Sensor 10",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "20",
"name": "Einstrahlung CS",
"bitSize": "15",
"factor": "1",
"unit": " W/m²"
},
{
"offset": "22",
"name": "Impulse 1 V40",
"bitSize": "16",
"factor": "1",
"unit": " "
},
{
"offset": "24",
"name": "Digital Input",
"bitSize": "16",
"factor": "1",
"unit": " "
},
{
"offset": "26",
"name": "Drehzahl Relais 1",
"bitSize": "7",
"unit": " %"
},
{
"offset": "27",
"name": "Drehzahl Relais 2",
"bitSize": "7",
"unit": " %"
},
{
"offset": "28",
"name": "Drehzahl Relais 3",
"bitSize": "7",
"unit": " %"
},
{
"offset": "29",
"name": "Drehzahl Relais 4",
"bitSize": "7",
"unit": " %"
},
{
"offset": "30",
"name": "Drehzahl Relais 5",
"bitSize": "7",
"unit": " %"
},
{
"offset": "31",
"name": "Drehzahl Relais 6",
"bitSize": "7",
"unit": " %"
},
{
"offset": "32",
"name": "Drehzahl Relais 7",
"bitSize": "7",
"unit": " %"
},
{
"-commonUsage": "error",
"offset": "36",
"name": "Fehlermaske",
"bitSize": "16"
},
{
"offset": "38",
"name": "Meldungen",
"bitSize": "16"
},
{
"offset": "40",
"name": "System",
"bitSize": "7"
},
{
"offset": "42",
"name": "Schema",
"bitSize": "16"
},
{
"offset": "44",
"name": "Vorlauf Soll HK1 Modul Sensor 18",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "46",
"name": "Status HK1 Modul",
"bitSize": "16"
},
{
"offset": "48",
"name": "Vorlauf Soll HK2 Modul Sensor 25",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "50",
"name": "Status HK2 Modul",
"bitSize": "16"
},
{
"offset": "52",
"name": "Vorlauf Soll HK3 Modul Sensor 32",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "54",
"name": "Status HK3 Modul",
"bitSize": "16"
},
{
"offset": "56",
"name": "Vorlauf Soll Heizkreis Sensor 11",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "58",
"name": "Status Heizkreis",
"bitSize": "16"
},
{
"offset": "62",
"name": "Systemzeit",
"bitSize": "15",
"format": "t",
"timeRef": "1"
},
{
"offset": "64",
"name": "Jahr",
"bitSize": "15",
"factor": "1"
},
{
"offset": "66",
"name": "Monat",
"bitSize": "7",
"factor": "1"
},
{
"offset": "67",
"name": "Tag",
"bitSize": "7",
"factor": "1"
},
{
"name": "Version",
"field": [
{
"offset": "60",
"bitSize": "7",
"factor": "1"
},
{
"offset": "61",
"bitSize": "7",
"factor": "0,01"
}
],
"format": "F2"
}
]
},
{
"destination": "0x0010",
"source": "0x7822",
"command": "0x0100",
"field": [
{
"offset": "0",
"name": "Temperatur Vorlauf",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "2",
"name": "Temperatur Rücklauf",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "4",
"name": "Durchfluss Sensor 8",
"bitSize": "15",
"unit": " l/h"
},
{
"-commonUsage": "heat",
"name": "Wärmemenge",
"unit": " Wh",
"field": [
{
"offset": "6",
"bitSize": "16",
"factor": "1"
},
{
"offset": "8",
"bitSize": "16",
"factor": "1000"
},
{
"offset": "10",
"bitSize": "16",
"factor": "1000000"
}
]
}
]
},
{
"destination": "0x0010",
"source": "0x7831",
"sourceMask": "0xFFF0",
"command": "0x0100",
"field": [
{
"offset": "0",
"name": "Jahr",
"bitSize": "15",
"factor": "1"
},
{
"offset": "2",
"name": "Monat",
"bitSize": "7",
"factor": "1"
},
{
"offset": "3",
"name": "Tag",
"bitSize": "7",
"factor": "1"
},
{
"offset": "4",
"name": "Systemzeit",
"bitSize": "15",
"format": "t",
"timeRef": "1"
},
{
"offset": "6",
"name": "Status",
"bitSize": "7"
},
{
"offset": "7",
"name": "Fehlermeldung",
"bitSize": "7"
},
{
"offset": "8",
"name": "Vorlauf-Soll-Temperatur",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "10",
"name": "Vorlauftemperatur",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "12",
"name": "Relais Pumpe",
"bitSize": "7",
"unit": " %"
},
{
"offset": "13",
"name": "Relais Mischer Auf",
"bitSize": "7",
"unit": " %"
},
{
"offset": "14",
"name": "Relais Mischer Zu",
"bitSize": "7",
"unit": " %"
},
{
"offset": "15",
"name": "Handebetrieb Relais Pumpe",
"bitSize": "7"
},
{
"offset": "16",
"name": "Handebetrieb Relais Mischer Auf",
"bitSize": "7"
},
{
"offset": "17",
"name": "Handebetrieb Relais Mischer Zu",
"bitSize": "7"
},
{
"offset": "18",
"name": "NH-Anforderung",
"bitSize": "7"
},
{
"offset": "19",
"name": "Parameter Start",
"bitSize": "7"
},
{
"offset": "20",
"name": "Parameter TStart",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "22",
"name": "Parameter TMax",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "24",
"name": "Parameter Anstieg",
"bitSize": "15",
"factor": "0.1",
"unit": " °C"
},
{
"offset": "26",
"name": "Parameter Anstiegszeit",
"bitSize": "7",
"unit": " h"
},
{
"offset": "27",
"name": "Parameter Haltezeit",
"bitSize": "7",
"unit": " d"
}
]
}
]
}
}



- es ist vielmehr ein Provisorium 
Kommentar