neues Modul: 98_ModbusSystemair für Systemair KWL Anlagen mit Modbus

Begonnen von Bjoernar, 09 Juni 2016, 10:02:20

Vorheriges Thema - Nächstes Thema

Bjoernar

Hallo,

da ich es so nicht hinbekommen habe meine Systemair KWL Anlage auszulesen habe ich mich dazu entschieden selber ein Modul zu machen.

Ich habe das Modbus Modul für meinen SDM630 genommen und entsprechend abgeändert. Ich hoffe das ist so ok?

Ich kann nun auch schon einige Register auslesen und die Lüfterstufe setzen.
Nur leider werden die Werte nicht automatisch gelesen sondern immer nur wenn ich manuell ein get mache. Obwohl ein Intervall eingetragen ist.

Vielleicht kann mir jemand sagen wo der Fehler liegt.
Gibt es sonst noch User die eine Systemair Anlage betreiben und entsprechend testen können? Ich bekomme z.B. aus einem Register einen komischen Wert den ich nicht nachvollziehen kann.

Hier der Code, Kommentare passe ich später noch an:


package main;

use strict;
use warnings;
use Time::HiRes qw( time );

sub ModbusSystemair_Initialize($);

# deviceInfo defines properties of the device.
# some values can be overwritten in parseInfo, some defaults can even be overwritten by the user with attributes if a corresponding attribute is added to AttrList in _Initialize.
#
my %SystemairMdeviceInfo = (
"timing" => {
timeout => 2, # 2 seconds timeout when waiting for a response
commDelay => 0.7, # 0.7 seconds minimal delay between two communications e.g. a read a the next write,
# can be overwritten with attribute commDelay if added to AttrList in _Initialize below
sendDelay => 0.7, # 0.7 seconds minimal delay between two sends, can be overwritten with the attribute
# sendDelay if added to AttrList in _Initialize function below
},
"i" => { # details for "input registers" if the device offers them
read => 4, # use function code 4 to read discrete inputs. They can not be read by definition.
defLen => 2, # default length (number of registers) per value ((e.g. 2 for a float of 4 bytes that spans 2 registers)
# can be overwritten in parseInfo per reading by specifying the key "len"
combine => 40, # allow combined read of up to 10 adjacent registers during getUpdate
# combine => 1, # no combined read (read more than one registers with one read command) during getUpdate
defFormat => "%.1f", # default format string to use after reading a value in sprintf
# can be overwritten in parseInfo per reading by specifying the key "format"
defUnpack => "f>", # default pack / unpack code to convert raw values, e.g. "n" for a 16 bit integer oder
# "f>" for a big endian float IEEE 754 floating-point numbers
# can be overwritten in parseInfo per reading by specifying the key "unpack"
defPoll => 1, # All defined Input Registers should be polled by default unless specified otherwise in parseInfo or by attributes
defShowGet => 1, # default für showget Key in parseInfo
},
"h" => { # details for "holding registers" if the device offers them
read => 3, # use function code 3 to read holding registers.
write => 6, # use function code 6 to write holding registers (alternative could be 16)
defLen => 2, # default length (number of registers) per value (e.g. 2 for a float of 4 bytes that spans 2 registers)
# can be overwritten in parseInfo per reading by specifying the key "len"
combine => 10, # allow combined read of up to 10 adjacent registers during getUpdate
defUnpack => "n", # default pack / unpack code to convert raw values, e.g. "n" for a 16 bit integer oder
# "f>" for a big endian float IEEE 754 floating-point numbers
# can be overwritten in parseInfo per reading by specifying the key "unpack"
defShowGet => 1, # default für showget Key in parseInfo
},
);

# %parseInfo:
# r/c/i+adress => objHashRef (h = holding register, c = coil, i = input register, d = discrete input)
# the address is a decimal number without leading 0
#
# Explanation of the parseInfo hash sub-keys:
# name internal name of the value in the modbus documentation of the physical device
# reading name of the reading to be used in Fhem
# set can be set to 1 to allow writing this value with a Fhem set-command
# setmin min value for input validation in a set command
# setmax max value for input validation in a set command
# hint string for fhemweb to create a selection or slider
# expr perl expression to convert a string after it has bee read
# map a map string to convert an value from the device to a more readable output string
# or to convert a user input to the machine representation
# e.g. "0:mittig, 1:oberhalb, 2:unterhalb"
# setexpr per expression to convert an input string to the machine format before writing
# this is typically the reverse of the above expr
# format a format string for sprintf to format a value read
# len number of Registers this value spans
# poll defines if this value is included in the read that the module does every defined interval
# this can be changed by a user with an attribute
# unpack defines the translation between data in the module and in the communication frame
# see the documentation of the perl pack function for details.
# example: "n" for an unsigned 16 bit value or "f>" for a float that is stored in two registers
# showget can be set to 1 to allow a Fhem get command to read this value from the device
# polldelay if a value should not be read in each iteration after interval has passed,
# this value can be set to a multiple of interval

###############################################################################################################
# Holding Register
###############################################################################################################

my %SystemairMparseInfo = (
"h100" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_FAN_SPEED_LEVEL", # internal name of this register in the hardware doc
reading => "REG_FAN_SPEED_LEVEL", # name of the reading for this value
set => 1, # this value can be set
},

"h208" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_LVL1", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_LVL1", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h209" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_LVL2", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_LVL2", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h210" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_LVL3", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_LVL3", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h211" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_LVL4", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_LVL4", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h212" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_LVL5", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_LVL5", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h214" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_IN2", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_IN2", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},
"h213" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_IN1", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_IN1", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h214" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_IN2", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_IN2", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h215" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_IN3", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_IN3", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h216" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_IN4", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_IN4", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h217" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_HC_TEMP_IN5", # internal name of this register in the hardware doc
reading => "REG_HC_TEMP_IN5", # name of the reading for this value
set => 0, # this value can be set
expr => '$val/10',
},

"h350" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_ROTOR_STATE", # internal name of this register in the hardware doc
reading => "REG_ROTOR_STATE", # name of the reading for this value
set => 0, # this value can be set
},

"h351" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_ROTOR_RELAY_ACTIVE", # internal name of this register in the hardware doc
reading => "REG_ROTOR_RELAY_ACTIVE", # name of the reading for this value
set => 0, # this value can be set
},

"h500" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_SYSTEM_TYP", # internal name of this register in the hardware doc
reading => "REG_SYSTEM_TYP", # name of the reading for this value
# unpack => "n", # name of the reading for this value
# min => 0, # input validation for set: min value
# max => 4, # input validation for set: max value
# format => '%.s', # format string for sprintf
# set => 1, # this value can be set
},

"h600" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_FILTER_PER", # internal name of this register in the hardware doc
reading => "REG_FILTER_PER", # name of the reading for this value
set => 0, # this value can be set
},

"h601" => { # holding register 0x0014
# Write the network port node address: 1 to 247 for MODBUS Protocol, default 1.
# Requires a restart to become effective.
name => "REG_FILTER_DAYS", # internal name of this register in the hardware doc
reading => "REG_FILTER_DAYS", # name of the reading for this value
set => 0, # this value can be set
},

# Ende parseInfo
);


#####################################
sub
ModbusSystemair_Initialize($)
{
    my ($modHash) = @_;

require "$attr{global}{modpath}/FHEM/98_Modbus.pm";

$modHash->{parseInfo}  = \%SystemairMparseInfo; # defines registers, inputs, coils etc. for this Modbus Defive

$modHash->{deviceInfo} = \%SystemairMdeviceInfo; # defines properties of the device like
# defaults and supported function codes

ModbusLD_Initialize($modHash); # Generic function of the Modbus module does the rest

$modHash->{AttrList} = $modHash->{AttrList} . " " . # Standard Attributes like IODEv etc
$modHash->{ObjAttrList} . " " . # Attributes to add or overwrite parseInfo definitions
$modHash->{DevAttrList} . " " . # Attributes to add or overwrite devInfo definitions
"poll-.* " . # overwrite poll with poll-ReadingName
"polldelay-.* "; # overwrite polldelay with polldelay-ReadingName
}


1;

Bjoernar

Fehler was die Abfrage angeht habe ich nun selber gefunden:

defPoll => 1,

Fehlte oben in der Definition.

Trotzdem würde ich mich freuen wenn es noch jemand gibt der auch eine Anlage hat.

Gruß
Björnar

Bjoernar

...es scheint doch nicht ganz gelöst zu sein.

Er Fragt bis auf 3 Werte alle ab so wie er soll.
Manuell kann ich die Werte die nicht abgefragt werden aber abfragen.

Es geht um: REG_HC_TEMP_IN2, REG_HC_TEMP_IN4 und REG_ROTOR_RELAY_ACTIVE

Ich verstehe nicht warum diese nicht mit abgefragt werden.

Gruß Björnar


CoolTux

Was Du geschrieben hast ist Code für eine 99_myUtils, bitte benenne Deine Datei entsprechend um oder nehme sie ganz weg vom Download. Stelle nur den Code hier rein und sage das er für eine 99_myUtils Datei ist.

Nennen kann man die Datei ja dann 99_myUtils_ModbusSystemair.pm

Für eine ricthige Moduldatei fehlen einige grundlegende Dinge



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Bjoernar

ich habe das Modul 98_ModbusSDM630 kompiert und entsprechend angepasst.
Dann müsste dies ja auch "falsch" sein.

Kannst du den Zusammenhang mit Myutils mal erklären?

CoolTux

Code welcher in einer 99er Datei steht wird immer geladen. Code welcher in einer anderen Datei steht wird erst auf Anweisung des Users geladen. Bei den meisten Modulen durch ein define oder auch durch autocreate Anweisungen bei 2 Stuffigen Modulen. Das was ich bei Deinem Code sehe einschließlich dem 1; am Ende deutet nicht auf ein FHEM Modul im eigentlichen Sinne hin.
Deine Vorlage muß ich gestehen kenne ich nicht und weiß auch nicht wie es dazu kommt das die Datei so eingecheckt wurde.

Aber glaube mir es ist gerade auf hinblick wenn Anfänger damit arbeiten wollen besser daraus entweder ein Device Modul zu machen so wie es im Wiki spezifiziert ist oder lieber eine 99_myUtils_*
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Eine 98_ModbusSDM630 finde ich im offiziellen trunk nicht.
Aber es gibt einige 98_Modbus Module


98_ModbusTrovis5576.pm
98_ModbusSET.pm
Sind wohl Hilfsmodule welche die 98_Modbus.pm benötigen und somit wohl auch über 98_Modbus.pm geladen werden. Dein Code steht allerdings alleine ohne jegliche Abhängigkeit.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Bjoernar

meiner greift auch auf 98_Modbus.pm zu.

require "$attr{global}{modpath}/FHEM/98_Modbus.pm";

CoolTux

Und du hast auch den entsprechend definiert? Dann wird es wohl passen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Bjoernar

Zitat von: CoolTux am 09 Juni 2016, 13:06:41
Und du hast auch den entsprechend definiert? Dann wird es wohl passen.

wie gesagt nur kopiert. Und dazu noch Anfänger.

Ist denn 98_Modbus... richtig oder 99_MyUtils_....?

CoolTux

Ich würde zum jetzigen Zeitpunkt erstmal sagen lass es so.

Ich gehe mal davon aus das Du irgendwo bestimmt ein define vom TYPE=Modbus oder ähnlich hast.



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Bjoernar

Zitat von: wthiess am 13 Juni 2016, 14:01:10
Hallo Bjoernar!

Ich würde gerne mitmachen und Testen.
Bin wieder nächstes Wochenende auf der Baustelle.
Kannst du mir bitte  deinen Schaltplan zukommen lassen. Auch wäre deine Fhem defines hilfreich.
Wo bekomme ich dein Modul?

lg
Wolgang

Hallo,

du musst mehr lesen und dir ein paar Dinge selber erarbeiten. Ansonsten wirst du schnell frustriert sein.

Modul ist im Beitrag 3 angehängt.
Ist aber noch nicht fertig!

Wenn du dir die FHEM Grundlagen durchgelesen hast solltest du es auch ohne Probleme einbinden können.

Deinen Adapter kenne ich nicht:
Bei mir ist es wie hier verdrahtet: https://github.com/gonium/gosdm630
Aber Grundsätzlich gibt es ja nur A und B (+ und -)

Gruß
Björnar

Bjoernar

Zitat von: wthiess am 13 Juni 2016, 14:28:48
Leider schaffe ich es nicht. Trotzdem Danke. Ich werde mir wohl selber ein Modul erarbeiten müssen.

lg
Wolfgang

Das verstehe ich nun überhaupt nicht mehr.
Nach mal Modul hängt am dritten Beitrag. Dort kannst du es dir runterladen und bei dir einbinden.

Bjoernar

Zitat von: wthiess am 13 Juni 2016, 14:42:49Wo bekomme ich dein Modul?

...war darauf bezogen.

Was ist denn dein Problem?
Bekommst du das Modul nicht eingebunden, Verkabelung....?

Bjoernar

habe es erstmal mit den für mich relevanten Werten gemacht.
Lässt sich natürlich noch erweitern.
Sehr interessant finde den Status vom Wärmetauscher (ist glaube ich in der Version noch nicht drin, stelle ich aber später mal ein) und die Temperatur Fühler.
Viele Daten sind für mich irrelevant, was fehlt dir denn noch?

Es ist eine VSR300DE