kopia lustrzana https://github.com/weetmuts/wmbusmeters
The required field does not contribute to testing of the address expressions before.
rodzic
3247a4a576
commit
8c09f7b2d8
26
README.md
26
README.md
|
@ -11,15 +11,33 @@ log file.
|
|||
Wmbusmeters converts incoming telegrams from (w)mbus/OMS compatible meters like:
|
||||
`2A442D2C998734761B168D2091D37CAC21576C78_02FF207100041308190000441308190000615B7F616713`
|
||||
|
||||
into human readable tab separated fields:
|
||||
`MyTapWater 12345678 6.388 m3 6.377 m3 0.000 m3/h 8°C 23°C DRY(dry 22-31 days) 2018-03-05 12:02.50`
|
||||
into human readable:
|
||||
`MyTapWater 12345678 6.388 m³ 6.377 m³ 0.000 m³/h 8°C 23°C DRY(dry 22-31 days) 2018-03-05 12:02.50`
|
||||
|
||||
or into computer readable fields:
|
||||
or into csv:
|
||||
`MyTapWater;12345678;6.388;6.377;0.000;8;23;DRY(dry 22-31 days);2018-03-05 12:02.50`
|
||||
|
||||
or into json:
|
||||
```json
|
||||
{"media":"cold water","meter":"multical21","name":"MyTapWater","id":"12345678","total_m3":6.388,"target_m3":6.377,"max_flow_m3h":0.000,"flow_temperature":8,"external_temperature":23,"current_status":"DRY","time_dry":"22-31 days","time_reversed":"","time_leaking":"","time_bursting":"","timestamp":"2018-02-08T09:07:22Z","device":"im871a[1234567]","rssi_dbm":-40}
|
||||
{
|
||||
"media":"cold water",
|
||||
"meter":"multical21",
|
||||
"name":"MyTapWater",
|
||||
"id":"12345678",
|
||||
"total_m3":6.388,
|
||||
"target_m3":6.377,
|
||||
"max_flow_m3h":0.000,
|
||||
"flow_temperature":8,
|
||||
"external_temperature":23,
|
||||
"current_status":"DRY",
|
||||
"time_dry":"22-31 days",
|
||||
"time_reversed":"",
|
||||
"time_leaking":"",
|
||||
"time_bursting":"",
|
||||
"timestamp":"2018-02-08T09:07:22Z",
|
||||
"device":"im871a[1234567]",
|
||||
"rssi_dbm":-40
|
||||
}
|
||||
```
|
||||
|
||||
Wmbusmeters can collect telegrams from radio using hardware dongles or rtl-sdr software radio dongles,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
telegram=|414493447514916746377275149167934446044D000020_0C06490000004C0600000000426CFF2CCC080611000000C2086C1F3102FD170000326CFFFF046D330F1432|
|
||||
telegram=|5b44934475149167463778077975149167934446040dff5f3500823d0000810007c006ffff49000000ff2c000000001f3111000000008000800080008000800080008000800080000000000B002f02fd170000046d390d1432488408|
|
||||
telegram=|414493447514916746377275149167934446044D000020_0C06490000004C0600000000426CFF2CCC080611000000C2086C1F3102FD170000326CFFFF046D330F1432|
|
||||
telegram=|5b44934475149167463778077975149167934446040dff5f3500823d0000810007c006ffff49000000ff2c000000001f3111000000008000800080008000800080008000800080000000000B002f02fd170000046d390d1432488408|
|
|
@ -30,7 +30,9 @@ bool doesIdMatchExpression(const std::string& id, std::string match_rule);
|
|||
bool doesAddressMatchExpressions(Address &address,
|
||||
std::vector<AddressExpression>& address_expressions,
|
||||
bool *used_wildcard,
|
||||
bool *filtered_out);
|
||||
bool *filtered_out,
|
||||
bool *required_found,
|
||||
bool *required_failed);
|
||||
|
||||
bool isValidMatchExpression(const string& s, bool *has_wildcard)
|
||||
{
|
||||
|
@ -348,6 +350,7 @@ string AddressExpression::str()
|
|||
string s;
|
||||
|
||||
if (filter_out) s = "!";
|
||||
if (required) s = "R";
|
||||
|
||||
s.append(id);
|
||||
if (mfct != 0xffff)
|
||||
|
@ -443,9 +446,17 @@ bool doesTelegramMatchExpressions(std::vector<Address> &addresses,
|
|||
{
|
||||
bool match = false;
|
||||
bool filtered_out = false;
|
||||
bool required_found = false; // An R12345678 field was found.
|
||||
bool required_failed = true; // Init to fail, set to true if R is satistifed anywhere.
|
||||
|
||||
for (Address &a : addresses)
|
||||
{
|
||||
if (doesAddressMatchExpressions(a, address_expressions, used_wildcard, &filtered_out))
|
||||
if (doesAddressMatchExpressions(a,
|
||||
address_expressions,
|
||||
used_wildcard,
|
||||
&filtered_out,
|
||||
&required_found,
|
||||
&required_failed))
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
|
@ -454,18 +465,21 @@ bool doesTelegramMatchExpressions(std::vector<Address> &addresses,
|
|||
}
|
||||
// If any expression triggered a filter out, then the whole telegram does not match.
|
||||
if (filtered_out) match = false;
|
||||
// If a required field was found and it failed....
|
||||
if (required_found && required_failed) match = false;
|
||||
return match;
|
||||
}
|
||||
|
||||
bool doesAddressMatchExpressions(Address &address,
|
||||
vector<AddressExpression>& address_expressions,
|
||||
bool *used_wildcard,
|
||||
bool *filtered_out)
|
||||
bool *filtered_out,
|
||||
bool *required_found,
|
||||
bool *required_failed)
|
||||
{
|
||||
bool found_match = false;
|
||||
bool found_negative_match = false;
|
||||
bool exact_match = false;
|
||||
bool failed_required_match = false;
|
||||
|
||||
// Goes through all possible match expressions.
|
||||
// If no expression matches, neither positive nor negative,
|
||||
|
@ -485,8 +499,11 @@ bool doesAddressMatchExpressions(Address &address,
|
|||
{
|
||||
bool has_wildcard = ae.has_wildcard;
|
||||
bool is_negative_rule = ae.filter_out;
|
||||
// We currently assume that only a single expression is required, the last one!
|
||||
bool is_required = ae.required;
|
||||
|
||||
if (is_required) *required_found = true;
|
||||
|
||||
bool m = ae.match(address.id, address.mfct, address.version, address.type);
|
||||
|
||||
if (is_negative_rule)
|
||||
|
@ -497,27 +514,22 @@ bool doesAddressMatchExpressions(Address &address,
|
|||
{
|
||||
if (m)
|
||||
{
|
||||
found_match = true;
|
||||
if (!has_wildcard)
|
||||
// A match, but the required does not count.
|
||||
if (!is_required)
|
||||
{
|
||||
exact_match = true;
|
||||
found_match = true;
|
||||
if (!has_wildcard)
|
||||
{
|
||||
exact_match = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match
|
||||
if (is_required)
|
||||
else
|
||||
{
|
||||
// Oups! A required match!
|
||||
failed_required_match = true;
|
||||
*required_failed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failed_required_match)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (found_negative_match)
|
||||
{
|
||||
*filtered_out = true;
|
||||
|
|
|
@ -938,9 +938,12 @@ bool MeterCommonImplementation::isTelegramForMeter(Telegram *t, Meter *meter, Me
|
|||
}
|
||||
|
||||
bool used_wildcard = false;
|
||||
bool match = doesTelegramMatchExpressions(t->addresses, address_expressions, &used_wildcard);
|
||||
bool match = doesTelegramMatchExpressions(t->addresses,
|
||||
address_expressions,
|
||||
&used_wildcard);
|
||||
|
||||
if (!match) {
|
||||
if (!match)
|
||||
{
|
||||
// The id must match.
|
||||
debug("(meter) %s: not for me: no match\n", name.c_str());
|
||||
return false;
|
||||
|
|
6
test.sh
6
test.sh
|
@ -126,6 +126,12 @@ if [ "$?" != "0" ]; then RC="1"; fi
|
|||
tests/test_addresses.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
tests/test_address_filtering.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
tests/test_address_dll.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
tests/test_identity_mode.sh $PROG
|
||||
if [ "$?" != "0" ]; then RC="1"; fi
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROG="$1"
|
||||
|
||||
mkdir -p testoutput
|
||||
TEST=testoutput
|
||||
|
||||
TESTNAME="Test addresses dll"
|
||||
TESTRESULT="OK"
|
||||
|
||||
# Test that selecting the meter using the dll id instead of the tpl id works.
|
||||
OUT=$($PROG --format=fields --selectfields=total_m3 6644496A1064035514377251345015496A0007EE0050052F2F_0C1359000000026CBE2B82046CA12B8C0413FFFFFFFF8D0493132CFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02FD1700002F2F W minomess 55036410 NOKEY)
|
||||
|
||||
if [ "$OUT" != "0.059" ]
|
||||
then
|
||||
echo "ERROR: Test addresses dll failed"
|
||||
else
|
||||
echo "OK: Test addresses dll"
|
||||
fi
|
||||
|
||||
# Test that selecting the meter using the tpl id instead of the dll id works.
|
||||
OUT=$($PROG --format=fields --selectfields=total_m3 6644496A1064035514377251345015496A0007EE0050052F2F_0C1359000000026CBE2B82046CA12B8C0413FFFFFFFF8D0493132CFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02FD1700002F2F W minomess 15503451 NOKEY)
|
||||
|
||||
if [ "$OUT" != "0.059" ]
|
||||
then
|
||||
echo "ERROR: Test addresses tpl failed"
|
||||
else
|
||||
echo "OK: Test addresses tpl"
|
||||
fi
|
||||
|
||||
OUT=$($PROG --format=fields --selectfields=total_m3 6644496A1064035514377251345015496A0007EE0050052F2F_0C1359000000026CBE2B82046CA12B8C0413FFFFFFFF8D0493132CFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02FD1700002F2F W minomess '*.T=07' NOKEY)
|
||||
|
||||
if [ "$OUT" != "0.059" ]
|
||||
then
|
||||
echo "ERROR: Test addresses *.T=07 failed"
|
||||
else
|
||||
echo "OK: Test addresses *.T=07"
|
||||
fi
|
||||
|
||||
OUT=$($PROG --format=fields --selectfields=total_m3 6644496A1064035514377251345015496A0007EE0050052F2F_0C1359000000026CBE2B82046CA12B8C0413FFFFFFFF8D0493132CFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02FD1700002F2F W minomess '*.T=37' NOKEY)
|
||||
|
||||
if [ "$OUT" != "0.059" ]
|
||||
then
|
||||
echo "ERROR: Test addresses *.T=37 failed"
|
||||
else
|
||||
echo "OK: Test addresses *.T=37"
|
||||
fi
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROG="$1"
|
||||
|
||||
mkdir -p testoutput
|
||||
TEST=testoutput
|
||||
|
||||
TESTNAME="Test address type filtering"
|
||||
TESTRESULT="OK"
|
||||
|
||||
$PROG --format=fields simulations/simulation_qheat_bad.txt HEAT qheat '67911475.T=04' NOKEY > $TEST/test_output.txt 2>&1
|
||||
|
||||
cat $TEST/test_output.txt | sed 's/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9].[0-9][0-9]$/1111-11-11 11:11.11/' > $TEST/test_responses.txt
|
||||
|
||||
cat > $TEST/test_expected.txt <<EOF
|
||||
HEAT;67911475;49;2024-01-31;11;1111-11-11 11:11.11
|
||||
EOF
|
||||
|
||||
if ! diff $TEST/test_expected.txt $TEST/test_responses.txt
|
||||
then
|
||||
if [ "$USE_MELD" = "true" ]
|
||||
then
|
||||
meld $TEST/test_expected.txt $TEST/test_responses.txt
|
||||
fi
|
||||
echo "ERROR: $TESTNAME"
|
||||
else
|
||||
echo OK: $TESTNAME
|
||||
fi
|
Ładowanie…
Reference in New Issue