|
From: <ma...@us...> - 2015-05-26 13:38:18
|
Revision: 2362
http://sourceforge.net/p/openautomation/code/2362
Author: makki1
Date: 2015-05-26 13:38:16 +0000 (Tue, 26 May 2015)
Log Message:
-----------
Modbus (RTU/TCP) Plugin-Example
Added Paths:
-----------
wiregate/plugin/generic/Herget_Modubus_Haus.pl
wiregate/plugin/generic/Herget_Modubus_Schwimm.pl
Added: wiregate/plugin/generic/Herget_Modubus_Haus.pl
===================================================================
--- wiregate/plugin/generic/Herget_Modubus_Haus.pl (rev 0)
+++ wiregate/plugin/generic/Herget_Modubus_Haus.pl 2015-05-26 13:38:16 UTC (rev 2362)
@@ -0,0 +1,122 @@
+# Plugin for Modbus<->KNX
+# Version 1.0 2014-10-17 (MM)
+# apt-get install libprotocol-modbus-perl
+
+####################
+### Definitionen ###
+####################
+# Eigenen Aufruf-Zyklus auf 60 Sekunden setzen
+# = zyklischer Werteversand der Modbus-Register
+$plugin_info{$plugname.'_cycle'} = 60;
+# GAs..
+# subscribe GAs
+# Aktuell alles unten hartcodiert, geht eleganter..
+
+#########################
+### Ende Definitionen ###
+#########################
+use Protocol::Modbus;
+
+$plugin_subscribe{'6/4/191'}{$plugname} = 1;
+$plugin_subscribe{'6/4/192'}{$plugname} = 1;
+$plugin_subscribe{'6/4/193'}{$plugname} = 1;
+$plugin_subscribe{'6/4/194'}{$plugname} = 1;
+$plugin_subscribe{'6/4/195'}{$plugname} = 1;
+$plugin_subscribe{'6/4/196'}{$plugname} = 1;
+$plugin_subscribe{'6/4/197'}{$plugname} = 1;
+$plugin_subscribe{'6/4/198'}{$plugname} = 1;
+$plugin_subscribe{'6/4/199'}{$plugname} = 1;
+$plugin_subscribe{'0/2/5'}{$plugname} = 1;
+
+my $ip = '192.168.17.35';
+
+my $modbus = Protocol::Modbus->new(driver=>'TCP', transport=>'TCP');
+my $trs = Protocol::Modbus::Transport->new(
+ driver => 'TCP',
+ address => $ip,
+ port => 502,
+ timeout => 3,
+);
+my $req = $modbus->readHoldRegistersRequest(
+ address => 0,
+ quantity => 16,
+);
+my $trn = $modbus->transaction($trs, $req);
+my $res = $trn->execute();
+my @inputs = @{ $res->registers() };
+
+if (%msg) { # telegramm vom KNX
+ if ($msg{'apci'} eq "A_GroupValue_Write") {
+ setModbusRegInt16(20,knx_read('6/4/191',0,9)*10);
+ setModbusRegInt16(21,knx_read('6/4/192',0,9)*10);
+ setModbusRegInt16(25,knx_read('0/2/5',0,9)*10);
+ setModbusRegInt16(26,knx_read('6/4/198',0,5.001)*10);
+ setModbusRegInt16(27,knx_read('6/4/199',0,5.001)*10);
+ my $reg24 = 0;
+ $reg24 |= knx_read('6/4/193',0,1);
+ $reg24 |= knx_read('6/4/194',0,1) << 1;
+ $reg24 |= knx_read('6/4/196',0,1) << 3;
+ $reg24 |= knx_read('6/4/195',0,1) << 4;
+ $reg24 |= knx_read('6/4/197',0,1) << 15;
+ setModbusRegInt16(24,$reg24);
+ }
+} else { # zyklisches senden
+ knx_write('6/4/161',getModbusRegInt16(2)/10,9);
+ knx_write('6/4/162',getModbusRegInt16(3)/10,9);
+ knx_write('6/4/163',getModbusRegInt16(4)/10,9);
+ knx_write('6/4/164',getModbusRegInt16(5)/10,9);
+ knx_write('6/4/171',getModbusRegInt16(8)/10,9);
+ knx_write('6/4/172',getModbusRegInt16(9)/10,9);
+ knx_write('6/4/173',getModbusRegInt16(10)/10,9);
+ knx_write('6/4/174',getModbusRegInt16(11),13);
+ knx_write('6/4/175',getModbusRegInt16(12),13);
+
+ my $reg7 = ((hex($inputs[14]) << 8) + hex($inputs[15])); # Status bitwise
+ knx_write('6/4/167',($reg7 >> 0) & 0x01,1);
+ knx_write('6/4/176',($reg7 >> 1) & 0x01,1);
+ knx_write('6/4/177',($reg7 >> 2) & 0x01,1);
+ knx_write('6/4/168',($reg7 >> 3) & 0x01,1);
+ knx_write('6/4/169',($reg7 >> 4) & 0x01,1);
+ knx_write('6/4/170',($reg7 >> 5) & 0x01,1);
+ knx_write('6/4/178',($reg7 >> 6) & 0x01,1);
+ knx_write('6/4/179',($reg7 >> 7) & 0x01,1);
+ knx_write('6/4/180',($reg7 >> 8) & 0x01,1);
+ knx_write('6/4/181',($reg7 >> 9) & 0x01,1);
+ knx_write('6/4/182',($reg7 >> 10) & 0x01,1);
+ knx_write('6/4/183',($reg7 >> 11) & 0x01,1);
+ knx_write('6/4/184',($reg7 >> 12) & 0x01,1);
+ knx_write('6/4/185',($reg7 >> 13) & 0x01,1);
+ knx_write('6/4/187',($reg7 >> 15) & 0x01,1);
+ my $reg15 = ((hex($inputs[30]) << 8) + hex($inputs[31])); # Status bitwise
+ knx_write('6/4/188',($reg15 >> 0) & 0x01,1);
+ knx_write('6/4/189',($reg15 >> 1) & 0x01,1);
+}
+
+sub getModbusRegInt16 {
+ my $idx = shift;
+ #my @in = shift;
+ $idx *= 2;
+ my $val = ((hex($inputs[$idx]) << 8) + hex($inputs[$idx+1]));
+ $val = $val > 32767 ? $val-65536 : $val;
+ return $val;
+}
+
+sub setModbusRegInt16 {
+ my $idx = shift;
+ my $val = shift;
+ $req = $modbus->writeRegisterRequest(
+ address => $idx,
+ value => $val,
+ );
+ $trn = $modbus->transaction($trs, $req);
+ $res = $trn->execute();
+}
+
+return;
+
+# FIXME: undef $modbus $trs $req $trn $res @inputs to avoid memleaks
+
+# TODO:
+# - Check modbus-response better/explicit
+# - Avoid memleaks by re-using a persistent Modbus-RTU/TCP connection
+# - round values to 0.1 before sending to Modbus?
Added: wiregate/plugin/generic/Herget_Modubus_Schwimm.pl
===================================================================
--- wiregate/plugin/generic/Herget_Modubus_Schwimm.pl (rev 0)
+++ wiregate/plugin/generic/Herget_Modubus_Schwimm.pl 2015-05-26 13:38:16 UTC (rev 2362)
@@ -0,0 +1,115 @@
+# Plugin for Modbus<->KNX
+# Version 1.0 2014-10-17 (MM)
+# apt-get install libprotocol-modbus-perl
+
+####################
+### Definitionen ###
+####################
+# Eigenen Aufruf-Zyklus auf 60 Sekunden setzen
+# = zyklischer Werteversand der Modbus-Register
+$plugin_info{$plugname.'_cycle'} = 60;
+# GAs..
+# subscribe GAs
+# Aktuell alles unten hartcodiert, geht eleganter..
+
+#########################
+### Ende Definitionen ###
+#########################
+use Protocol::Modbus;
+
+$plugin_subscribe{'6/0/58'}{$plugname} = 1;
+$plugin_subscribe{'6/0/59'}{$plugname} = 1;
+$plugin_subscribe{'6/0/60'}{$plugname} = 1;
+$plugin_subscribe{'6/0/61'}{$plugname} = 1;
+$plugin_subscribe{'6/0/62'}{$plugname} = 1;
+$plugin_subscribe{'6/0/63'}{$plugname} = 1;
+$plugin_subscribe{'6/0/64'}{$plugname} = 1;
+$plugin_subscribe{'0/2/5'}{$plugname} = 1;
+
+my $ip = '192.168.3.37';
+
+my $modbus = Protocol::Modbus->new(driver=>'TCP', transport=>'TCP');
+my $trs = Protocol::Modbus::Transport->new(
+ driver => 'TCP',
+ address => $ip,
+ port => 502,
+ timeout => 3,
+);
+my $req = $modbus->readHoldRegistersRequest(
+ address => 0,
+ quantity => 13,
+);
+my $trn = $modbus->transaction($trs, $req);
+my $res = $trn->execute();
+my @inputs = @{ $res->registers() };
+
+if (%msg) { # telegramm vom KNX
+ if ($msg{'apci'} eq "A_GroupValue_Write") {
+ setModbusRegInt16(18,knx_read('6/0/59',0,9)*10);
+ setModbusRegInt16(19,knx_read('6/0/60',0,9)*10);
+ setModbusRegInt16(20,knx_read('6/0/61',0,9)*10);
+ setModbusRegInt16(25,knx_read('0/2/5',0,9)*10);
+ my $reg24 = 0;
+ $reg24 |= knx_read('6/0/62',0,1);
+ $reg24 |= knx_read('6/0/63',0,1) << 1;
+ $reg24 |= knx_read('6/0/64',0,1) << 4;
+ $reg24 |= knx_read('6/0/58',0,1) << 15;
+ setModbusRegInt16(24,$reg24);
+ }
+} else { # zyklisches senden
+ knx_write('6/0/34',getModbusRegInt16(0)/10,5.001);
+ knx_write('6/0/35',getModbusRegInt16(1)/10,5.001);
+ knx_write('6/0/14',getModbusRegInt16(4)/10,9);
+ knx_write('6/0/36',getModbusRegInt16(5)/10,9);
+ knx_write('6/0/42',getModbusRegInt16(8)/10,9);
+ knx_write('6/0/43',getModbusRegInt16(9)/10,9);
+ knx_write('6/0/44',getModbusRegInt16(10)/10,9);
+ knx_write('6/0/45',getModbusRegInt16(11),13);
+ knx_write('6/0/46',getModbusRegInt16(12),13);
+ my $reg7 = ((hex($inputs[14]) << 8) + hex($inputs[15])); # Status bitwise
+ knx_write('6/0/37',($reg7 >> 0) & 0x01,1);
+ knx_write('6/0/38',($reg7 >> 1) & 0x01,1);
+ knx_write('6/0/39',($reg7 >> 3) & 0x01,1);
+ knx_write('6/0/40',($reg7 >> 4) & 0x01,1);
+ knx_write('6/0/41',($reg7 >> 5) & 0x01,1);
+ knx_write('6/0/47',($reg7 >> 2) & 0x01,1);
+ knx_write('6/0/48',($reg7 >> 6) & 0x01,1);
+ knx_write('6/0/49',($reg7 >> 7) & 0x01,1);
+ knx_write('6/0/50',($reg7 >> 8) & 0x01,1);
+ knx_write('6/0/51',($reg7 >> 9) & 0x01,1);
+ knx_write('6/0/52',($reg7 >> 10) & 0x01,1);
+ knx_write('6/0/53',($reg7 >> 11) & 0x01,1);
+ knx_write('6/0/54',($reg7 >> 12) & 0x01,1);
+ knx_write('6/0/55',($reg7 >> 13) & 0x01,1);
+ knx_write('6/0/56',($reg7 >> 14) & 0x01,1);
+ knx_write('6/0/57',($reg7 >> 15) & 0x01,1);
+}
+
+sub getModbusRegInt16 {
+ my $idx = shift;
+ #my @in = shift;
+ $idx *= 2;
+ my $val = ((hex($inputs[$idx]) << 8) + hex($inputs[$idx+1]));
+ $val = $val > 32767 ? $val-65536 : $val;
+ return $val;
+}
+
+sub setModbusRegInt16 {
+ my $idx = shift;
+ my $val = shift;
+ $req = $modbus->writeRegisterRequest(
+ address => $idx,
+ value => $val,
+ );
+ $trn = $modbus->transaction($trs, $req);
+ $res = $trn->execute();
+}
+
+return;
+
+# FIXME: undef $modbus $trs $req $trn $res @inputs to avoid memleaks
+
+# TODO:
+# - Check modbus-response better/explicit
+# - Avoid memleaks by re-using a persistent Modbus-RTU/TCP connection
+# - round values to 0.1 before sending to Modbus?
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|