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:
|
Wmbusmeters converts incoming telegrams from (w)mbus/OMS compatible meters like:
|
||||||
`2A442D2C998734761B168D2091D37CAC21576C78_02FF207100041308190000441308190000615B7F616713`
|
`2A442D2C998734761B168D2091D37CAC21576C78_02FF207100041308190000441308190000615B7F616713`
|
||||||
|
|
||||||
into human readable tab separated fields:
|
into human readable:
|
||||||
`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`
|
`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`
|
`MyTapWater;12345678;6.388;6.377;0.000;8;23;DRY(dry 22-31 days);2018-03-05 12:02.50`
|
||||||
|
|
||||||
or into json:
|
or into json:
|
||||||
```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,
|
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,
|
bool doesAddressMatchExpressions(Address &address,
|
||||||
std::vector<AddressExpression>& address_expressions,
|
std::vector<AddressExpression>& address_expressions,
|
||||||
bool *used_wildcard,
|
bool *used_wildcard,
|
||||||
bool *filtered_out);
|
bool *filtered_out,
|
||||||
|
bool *required_found,
|
||||||
|
bool *required_failed);
|
||||||
|
|
||||||
bool isValidMatchExpression(const string& s, bool *has_wildcard)
|
bool isValidMatchExpression(const string& s, bool *has_wildcard)
|
||||||
{
|
{
|
||||||
|
@ -348,6 +350,7 @@ string AddressExpression::str()
|
||||||
string s;
|
string s;
|
||||||
|
|
||||||
if (filter_out) s = "!";
|
if (filter_out) s = "!";
|
||||||
|
if (required) s = "R";
|
||||||
|
|
||||||
s.append(id);
|
s.append(id);
|
||||||
if (mfct != 0xffff)
|
if (mfct != 0xffff)
|
||||||
|
@ -443,9 +446,17 @@ bool doesTelegramMatchExpressions(std::vector<Address> &addresses,
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
bool filtered_out = 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)
|
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;
|
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 any expression triggered a filter out, then the whole telegram does not match.
|
||||||
if (filtered_out) match = false;
|
if (filtered_out) match = false;
|
||||||
|
// If a required field was found and it failed....
|
||||||
|
if (required_found && required_failed) match = false;
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool doesAddressMatchExpressions(Address &address,
|
bool doesAddressMatchExpressions(Address &address,
|
||||||
vector<AddressExpression>& address_expressions,
|
vector<AddressExpression>& address_expressions,
|
||||||
bool *used_wildcard,
|
bool *used_wildcard,
|
||||||
bool *filtered_out)
|
bool *filtered_out,
|
||||||
|
bool *required_found,
|
||||||
|
bool *required_failed)
|
||||||
{
|
{
|
||||||
bool found_match = false;
|
bool found_match = false;
|
||||||
bool found_negative_match = false;
|
bool found_negative_match = false;
|
||||||
bool exact_match = false;
|
bool exact_match = false;
|
||||||
bool failed_required_match = false;
|
|
||||||
|
|
||||||
// Goes through all possible match expressions.
|
// Goes through all possible match expressions.
|
||||||
// If no expression matches, neither positive nor negative,
|
// If no expression matches, neither positive nor negative,
|
||||||
|
@ -485,8 +499,11 @@ bool doesAddressMatchExpressions(Address &address,
|
||||||
{
|
{
|
||||||
bool has_wildcard = ae.has_wildcard;
|
bool has_wildcard = ae.has_wildcard;
|
||||||
bool is_negative_rule = ae.filter_out;
|
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;
|
bool is_required = ae.required;
|
||||||
|
|
||||||
|
if (is_required) *required_found = true;
|
||||||
|
|
||||||
bool m = ae.match(address.id, address.mfct, address.version, address.type);
|
bool m = ae.match(address.id, address.mfct, address.version, address.type);
|
||||||
|
|
||||||
if (is_negative_rule)
|
if (is_negative_rule)
|
||||||
|
@ -497,27 +514,22 @@ bool doesAddressMatchExpressions(Address &address,
|
||||||
{
|
{
|
||||||
if (m)
|
if (m)
|
||||||
{
|
{
|
||||||
found_match = true;
|
// A match, but the required does not count.
|
||||||
if (!has_wildcard)
|
if (!is_required)
|
||||||
{
|
{
|
||||||
exact_match = true;
|
found_match = true;
|
||||||
|
if (!has_wildcard)
|
||||||
|
{
|
||||||
|
exact_match = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
// No match
|
|
||||||
if (is_required)
|
|
||||||
{
|
{
|
||||||
// Oups! A required match!
|
*required_failed = false;
|
||||||
failed_required_match = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (failed_required_match)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (found_negative_match)
|
if (found_negative_match)
|
||||||
{
|
{
|
||||||
*filtered_out = true;
|
*filtered_out = true;
|
||||||
|
|
|
@ -938,9 +938,12 @@ bool MeterCommonImplementation::isTelegramForMeter(Telegram *t, Meter *meter, Me
|
||||||
}
|
}
|
||||||
|
|
||||||
bool used_wildcard = false;
|
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.
|
// The id must match.
|
||||||
debug("(meter) %s: not for me: no match\n", name.c_str());
|
debug("(meter) %s: not for me: no match\n", name.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
|
6
test.sh
6
test.sh
|
@ -126,6 +126,12 @@ if [ "$?" != "0" ]; then RC="1"; fi
|
||||||
tests/test_addresses.sh $PROG
|
tests/test_addresses.sh $PROG
|
||||||
if [ "$?" != "0" ]; then RC="1"; fi
|
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
|
tests/test_identity_mode.sh $PROG
|
||||||
if [ "$?" != "0" ]; then RC="1"; fi
|
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