1
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-05-04 22:19:38 +00:00
fhem-mirror/t/FHEM/98_Modbus/50_MasterSlave0.t
StefanStrobel 1901729367 98_Modbus: update Tests
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@23942 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2021-03-13 10:12:36 +00:00

256 lines
8.8 KiB
Perl

##############################################
# test master slave end to end
##############################################
package main;
use strict;
use warnings;
use Test::More;
use Time::HiRes qw( gettimeofday tv_interval); # return time as float, not just full seconds
use FHEM::HTTPMOD::Utils qw(:all);
use FHEM::Modbus::TestUtils qw(:all);
fhem 'attr global mseclog 1';
NextStep();
sub testStep1 { # preparation of slave content, enable devices
is(FhemTestUtils_gotLog('attribute'), 0, "no unknown attributes"); # logs during init are not collected.
LogStep "enable Master and set value at Slave";
fhem ('attr Master disable 0');
fhem ('setreading Slave TempWasserEin 12');
fhem ('setreading Slave Test1 1');
fhem ('setreading Slave Test2 2.123');
fhem ('setreading Slave Test3 abcdefg');
fhem ('setreading Slave Test4 40');
readingsSingleUpdate($defs{'Slave'}, 'Test5', pack('H*', 'e4f6fc'), 0);
fhem ('setreading Slave c0 1');
fhem ('setreading Slave c5 1');
fhem ('setreading Slave c17 1');
return 0.1;
}
sub testStep2 { # get holding registers
LogStep "get TempWasserEin";
fhem ('attr Master verbose 3');
fhem ('attr Slave verbose 3');
fhem ('get Master TempWasserEin');
fhem ('get Master Test1');
fhem ('get Master Test2');
fhem ('get Master Test3');
fhem ('get Master Test4');
fhem ('get Master Test5');
return 0.3;
}
sub testStep3 { # check results
LogStep "check result";
fhem ('attr Master verbose 3');
fhem ('attr Slave verbose 3');
is(FhemTestUtils_gotEvent(qr/Master:TempWasserEin:\s12/xms), 1, "Retrieve integer value from local slave");
is(FhemTestUtils_gotEvent(qr/Master:Test1: 6/), 1, "Retrieve another integer value with expressions on both sides from local slave");
is(FhemTestUtils_gotEvent(qr/Master:Test2: 2.12/), 1, "Retrieve float value from local slave");
is(FhemTestUtils_gotEvent(qr/Master:Test3: abcdefg/), 1, "Retrieve ascii value from local slave");
is(FhemTestUtils_gotEvent(qr/Master:Test4: 40/), 0, "ignoreExpr prohibits Test4 set to 40");
is(FhemTestUtils_gotEvent(qr/Master:Test5: äöü/), 1, "encode worked for Test5");
return;
}
sub testStep4 { # set holding register without allowance at salve
LogStep "set TempWasserAus at Slave";
fhem ('set Master TempWasserAus 20');
fhem ('attr Master verbose 4');
return 0.2;
}
sub testStep5 { # check that write was forbidden
LogStep "Check error response";
is(FhemTestUtils_gotLog('Master: HandleResponse got response with error code 86 / 01, illegal function'), 1, "disallow write by default");
fhem ('attr Master verbose 3');
return;
}
sub testStep6 { # allow write at slave and try again to write
LogStep "allow write and try again";
fhem ('attr Slave obj-h258-allowWrite 1');
fhem ('set Master TempWasserAus 20');
return 0.1;
}
sub testStep7 { # check that write holding register did work
LogStep "check result";
is(FhemTestUtils_gotEvent(qr/D1:TempWasserAus:\s20/xms), 1, "Write value to local slave");
return 0.1;
}
sub testStep8 { # check input validation at master and write
LogStep "set with map and min/max";
fhem ('set Master o1 one');
is(FhemTestUtils_gotLog('set Master o1 one : set value one did not match defined map'), 1, "map error message in log");
fhem ('set Master o2 0');
is(FhemTestUtils_gotLog('set Master o2 0 : value 0 is not within defined min/max range'), 1, "min error message in log");
fhem ('set Master o2 4');
is(FhemTestUtils_gotLog('set Master o2 4 : value 4 is not within defined min/max range'), 1, "max error message in log");
fhem ('attr Master verbose 4');
fhem ('set Master o2 2');
fhem ('set Master o1 on');
return 0.2;
}
sub testStep9 { # check write data
LogStep "check log for map and set o2 2";
is(FhemTestUtils_gotLog('0506000a0001698c'), 1, "set o1 on message in log");
is(FhemTestUtils_gotLog('0506000b0002784d'), 1, "set O2 2 message in log");
CheckAndReset();
fhem ('attr Master verbose 3');
return 0.1;
}
sub testStep10 { # check combined read of holding registers and coils
LogStep "getUpdate with combine";
fhem ('attr Master verbose 5'); # 3
fhem ('attr Slave verbose 3');
fhem ('set Master reread');
return 0.15;
}
sub testStep11 { # check results coming from slave and write coils to slave
is(FhemTestUtils_gotEvent(qr/Master:Test1: 6/), 1, "Combined retrieve integer value with expressions on both sides from local slave");
is(FhemTestUtils_gotEvent(qr/Master:Test2: 2.12/), 1, "Combined retrieve float value from local slave");
is(FhemTestUtils_gotEvent(qr/Master:Test3: abcdefg/), 1, "Combined Retrieve ascii value from local slave");
is(FhemTestUtils_gotEvent(qr/Master:c0: 1/), 1, "Combined Retrieve coil bit 0 from local slave");
is(FhemTestUtils_gotEvent(qr/Master:c1: 0/), 1, "Combined Retrieve coil bit 1 from local slave");
is(FhemTestUtils_gotEvent(qr/Master:c17: 1/), 1, "Combined Retrieve coil bit 17 from local slave");
fhem ('attr Slave obj-c402-allowWrite 1');
fhem ('attr Master verbose 5');
fhem ('set Master c2 1');
return 0.1;
}
sub testStep12 {
LogStep "check coil comm";
is(FhemTestUtils_gotLog('sending 05050192ff002daf'), 1, "set c2 1 sending message in log");
is(FhemTestUtils_gotEvent(qr/Master:c2: 1/), 1, "fc5 response for coil shows 1 from local slave");
Log3 undef, 1, "TestStep12: try to write with fc16";
fhem ('attr Master verbose 3');
fhem ('attr Slave verbose 3');
fhem ('attr Master dev-h-write 16');
fhem ('set Master TempWasserAus 29');
return 0.1;
}
sub testStep13 {
LogStep "check write result of fc16";
is(FhemTestUtils_gotEvent(qr/D1:TempWasserAus:\s29/xms), 1, "Write value with fc16 to local slave");
return 0.1;
}
sub testStep14 {
LogStep "closeAfterResponse";
FhemTestUtils_resetEvents();
FhemTestUtils_resetLogs();
fhem ('attr Master closeAfterResponse 1');
fhem ('attr Master verbose 4');
fhem ('set Master reread');
return 0.2;
}
sub testStep15 {
is(FhemTestUtils_gotEvent(qr/Master:Test1: 6/), 1, "Retrieve Test1");
is(FhemTestUtils_gotEvent(qr/Master:Test3: abcdefg/), 1, "Retrieve Test4");
is(FhemTestUtils_gotLog('HandleResponse will close because closeAfterResponse is set and queue is empty'), 1, "closed");
CheckAndReset();
return 0.1;
}
sub testStep16 {
LogStep "try get while closed";
fhem ('get Master TempWasserEin');
fhem ('attr Master queueDelay 0.3');
return 0.1;
}
sub testStep17 {
LogStep "check get result while connection closed";
is(FhemTestUtils_gotLog('device opened'), 1, "device opened");
is(FhemTestUtils_gotEvent(qr/Master:TempWasserEin:\s12/xms), 0, "No retrieve from local slave yet");
return 0.3;
}
sub testStep18 {
LogStep "check get result after another delay";
is(FhemTestUtils_gotEvent(qr/Master:TempWasserEin:\s12/xms), 1, "retrieve from local slave after open and QueueDelay");
is(FhemTestUtils_gotLog('close because closeAfterResponse'), 1, "device closed again");
CheckAndReset();
return 0.1;
}
sub testStep19 {
LogStep "now that the connection is closed again, try another prioritized get";
fhem 'attr Master nonPrioritizedGet 0';
fhem 'attr Master dev-timing-timeout 0.5';
fhem 'attr Master verbose 5';
fhem 'get Master TempWasserEin';
return 0.1;
}
sub testStep20 {
LogStep "check result after prio get";
is(FhemTestUtils_gotLog('device opened'), 1, "device opened");
is(FhemTestUtils_gotLog('Master: Timeout in Readanswer'), 1, "readanswer called but slave cannot answer while sitting in readanswer");
return;
}
sub testStep21 {
LogStep "check result after prio get";
is(FhemTestUtils_gotLog('Master: read.* buffer: 050302000c4981'), 1, "answer arrives after readanswer timeout");
CheckAndReset();
return;
}
sub testStep30 {
LogStep "try to read non existant register from slave";
fhem ('attr Master closeAfterResponse 0');
fhem 'attr Slave verbose 5';
fhem 'attr Master nonPrioritizedGet 1';
fhem 'get Master NoReading';
return 0.2;
}
sub testStep31 {
LogStep "check read NoReading result";
is(FhemTestUtils_gotLog('HandleResponse done.*fCode 131'), 1, "got address error from Slave");
CheckAndReset();
return 0.1;
}
sub testStep35 {
LogStep "try to read non existant register from slave with error code set to 0";
fhem 'attr Slave dev-addressErrCode 0';
fhem 'get Master NoReading';
return 0.2;
}
sub testStep36 {
LogStep "check read NoReading result";
is(FhemTestUtils_gotLog('HandleResponse done.*fCode 131'), 0, "got no address error from Slave");
return 0.1;
}
sub testStep32 {
#LogStep "";
#is(FhemTestUtils_gotEvent(qr/D1:TempWasserAus:\s20/xms), 1, "Write value to local slave");
return 0.1;
}
1;