kopia lustrzana https://github.com/weetmuts/wmbusmeters
Porównaj commity
40 Commity
Autor | SHA1 | Data |
---|---|---|
Fredrik Öhrström | 73dd60d67b | |
Fredrik Öhrström | b3771a9b8e | |
Fredrik Öhrström | 257a9c1ad2 | |
Fredrik Öhrström | f954860d80 | |
Fredrik Öhrström | 251b575f68 | |
Fredrik Öhrström | 7c117cc26c | |
jetmcquack | 40229d81ff | |
Fredrik Öhrström | 8748a2d52f | |
Fredrik Öhrström | 1396fff5a0 | |
Fredrik Öhrström | 759160b415 | |
Fredrik Öhrström | 9684345cb6 | |
Fredrik Öhrström | 1a4169ed23 | |
PovilasID | aa4f1956e8 | |
Fredrik Öhrström | d90dbb196e | |
Fredrik Öhrström | 14d021426a | |
Michał Morański | f32179a939 | |
Fredrik Öhrström | a32fcfdf9a | |
Fredrik Öhrström | efcc41d107 | |
Fredrik Öhrström | a69e547a17 | |
Fredrik Öhrström | 23f2279a64 | |
Fredrik Öhrström | 05edab0882 | |
Fredrik Öhrström | ff72e1debc | |
Fredrik Öhrström | c1509f6139 | |
Fredrik Öhrström | 9facddf019 | |
Fredrik Öhrström | 9a34a55abb | |
Fredrik Öhrström | 465a450a8b | |
Jean-Samuel REYNAUD | 9576550f85 | |
Fredrik Öhrström | 1f2cd10160 | |
Fredrik Öhrström | 8c09f7b2d8 | |
Fredrik Öhrström | 3247a4a576 | |
Fredrik Öhrström | 23779cb9f7 | |
Fredrik Öhrström | 5962e727ff | |
Arthur van Dorp | 03d95e780e | |
Fredrik Öhrström | 11c83c1f37 | |
Fredrik Öhrström | 7634b95438 | |
Fredrik Öhrström | 78e7c47503 | |
Fredrik Öhrström | 0c98b474bb | |
Fredrik Öhrström | 9d27ab3fb3 | |
Fredrik Öhrström | c21efd1d69 | |
testuser7 | 67230b4213 |
|
@ -11,8 +11,8 @@ on:
|
|||
env:
|
||||
DOCKERHUB_IMAGE: ${{ github.repository }}
|
||||
IMAGE_TAG: |
|
||||
${{ github.ref_type == 'tag' && (contains(github.ref_name, '-RC') &&
|
||||
format('{0}-{1}', 'candidate', github.ref_name) || format('{0}-{1}', 'release', github.ref_name)) || 'latest' }}
|
||||
${{ github.ref_type == 'tag' && format('{0}-{1}', (contains(github.ref_name, '-RC') &&
|
||||
'candidate' || 'release'), github.ref_name) || 'latest' }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
@ -3,6 +3,7 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macOS-latest
|
||||
|
|
29
CHANGES
29
CHANGES
|
@ -1,3 +1,32 @@
|
|||
|
||||
Fixed long standing confusion wether the DIF binary values are by
|
||||
default signed or unsigned. It turns out that they are signed!
|
||||
Thank you Mathias (Zeppelin500) and KaVauA for sorting this out!
|
||||
|
||||
For unknown VIFS and non-compliant meters the signedness
|
||||
can be overriden to unsigned.
|
||||
|
||||
New improved address specification. E.g. use 12345678.M=KAM.V=1b.T=16
|
||||
to listen to exactly the telegrams with id 12345678 manufacturer KAM,
|
||||
version 0x1b and type 0x16. You if you do not specify any M,V or T, they
|
||||
become wildcards which will be the old default behaviour.
|
||||
|
||||
If you receive multiple telegram versions from the same id, and you want to
|
||||
filter out some versions, do: 12345678,!12345678.V=77
|
||||
|
||||
You can now specify p0 to p250, to read from an mbus using the primary address.
|
||||
E.g. wmbusmeters --pollinterval=5s /dev/ttyUSB1:mbus:2400 TEMP piigth:mbus p0 NOKEY
|
||||
|
||||
Added option --identitymode=(id|id-mfct|full|none) to specify how
|
||||
wmbusmeters groups meter state when receiving telegrams.
|
||||
|
||||
The default (which is the same as before) is to map state based only on id.
|
||||
This usually works ok, however if you have two meters with the same id, but
|
||||
from different manufacturers, you must separate their state with --identitymode=id-mfct
|
||||
Full takes into account version and type as well. None means do not separate state
|
||||
at all, used with wildcards and meters that do not need to keep state, ie all info
|
||||
is in every telegram.
|
||||
|
||||
Version 1.16.1 2024-02-22
|
||||
|
||||
Fix docker file generation.
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,5 +1,4 @@
|
|||
|
||||
# Copyright (C) 2017-2023 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
# Copyright (C) 2017-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -153,6 +152,7 @@ $(BUILD)/%.o: src/%.c $(wildcard src/%.h)
|
|||
$(CXX) -I/usr/include/libxml2 -fpermissive $(CXXFLAGS) $< -MMD -c -o $@
|
||||
|
||||
PROG_OBJS:=\
|
||||
$(BUILD)/address.o \
|
||||
$(BUILD)/aes.o \
|
||||
$(BUILD)/aescmac.o \
|
||||
$(BUILD)/bus.o \
|
||||
|
|
69
README.md
69
README.md
|
@ -6,6 +6,33 @@ wireless wm-bus meters. The readings can then be published using
|
|||
MQTT, curled to a REST api, inserted into a database or stored in a
|
||||
log file.
|
||||
|
||||
# What does it do?
|
||||
|
||||
Wmbusmeters converts incoming telegrams from (w)mbus/OMS compatible meters like:
|
||||
`1844AE4C4455223368077A55000000_041389E20100023B0000`
|
||||
|
||||
into human readable:
|
||||
`MyTapWater 33225544 123.529 m³ 0 m³/h 2024-03-03 19:36:22`
|
||||
|
||||
or into csv:
|
||||
`MyTapWater;33225544;123.529;0;2024-03-03 19:36:45`
|
||||
|
||||
or into json:
|
||||
```json
|
||||
{
|
||||
"media":"water",
|
||||
"meter":"iperl",
|
||||
"name":"MyTapWater",
|
||||
"id":"33225544",
|
||||
"max_flow_m3h":0,
|
||||
"total_m3":123.529,
|
||||
"timestamp":"2024-03-03T18:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Wmbusmeters can collect telegrams from radio using hardware dongles or rtl-sdr software radio dongles,
|
||||
or from m-bus meters using serial ports, or from files/pipes.
|
||||
|
||||
[FAQ/WIKI/MANUAL pages](https://wmbusmeters.github.io/wmbusmeters-wiki/)
|
||||
|
||||
The program runs on GNU/Linux, MacOSX, FreeBSD, and Raspberry Pi.
|
||||
|
@ -130,9 +157,11 @@ bus the mbus poll request should be sent to.
|
|||
wmbusmeters --pollinterval=60s MAIN=/dev/ttyUSB0:mbus:2400 MyTempMeter piigth:MAIN:mbus 12001932 NOKEY
|
||||
```
|
||||
|
||||
If you want to poll an mbus meter using the primary address, just use
|
||||
a number between 0 and 250 instead of the full 8 digit secondary
|
||||
address.
|
||||
If you want to poll an mbus meter using the primary address, use p0 to p250 (deciman numbers)
|
||||
instead of the full 8 digit secondary address.
|
||||
```
|
||||
wmbusmeters --pollinterval=60s MAIN=/dev/ttyUSB0:mbus:2400 MyTempMeter piigth:MAIN:mbus p0 NOKEY
|
||||
```
|
||||
|
||||
# Example wmbusmeter.conf file
|
||||
|
||||
|
@ -173,7 +202,7 @@ And an mbus meter file in /etc/wmbusmeters.d/MyTempHygro
|
|||
```ini
|
||||
name=MyTempHygro
|
||||
id=11223344
|
||||
driver=piigth:mbus
|
||||
driver=piigth:MAIN:mbus
|
||||
pollinterval=60s
|
||||
```
|
||||
|
||||
|
@ -217,9 +246,15 @@ The latest reading of the meter can also be found here: `/var/lib/wmbusmeters/me
|
|||
You can use several ids using `id=1111111,2222222,3333333` or you can listen to all
|
||||
meters of a certain type `id=*` or you can suffix with star `id=8765*` to match
|
||||
all meters with a given prefix. If you supply at least one positive match rule, then you
|
||||
can add negative match rules as well. For example `id=*,!2222*`
|
||||
can add filter out rules as well. For example `id=*,!2222*`
|
||||
which will match all meter ids, except those that begin with 2222.
|
||||
|
||||
You can also specify the exact manufacturer, version and type: `id=11111111.M=KAM.V=1b.T=16`
|
||||
or a subset: `id=11111111.T=16` or all telegrams from 22222222 except those with version 77:
|
||||
`id=22222222,!22222222.V=77` You can also use the fully specified secondary address that is
|
||||
printed by libmbus after doing a bus scan, ie `100002842941011B` which is equivalent to
|
||||
`10000284.M=PII.V=01.T=1B`
|
||||
|
||||
When matching all meters from the command line you can use `ANYID` instead of `*` to avoid shell quotes.
|
||||
|
||||
# Add static and calculated fields to the output
|
||||
|
@ -419,6 +454,7 @@ As {options} you can use:
|
|||
--exitafter=<time> exit program after time, eg 20h, 10m 5s
|
||||
--format=<hr/json/fields> for human readable, json or semicolon separated fields
|
||||
--help list all options
|
||||
--identitymode=(id|id-mfct|full|none) group meter state based on the identity mode. Default is id.
|
||||
--ignoreduplicates=<bool> ignore duplicate telegrams, remember the last 10 telegrams
|
||||
--field_xxx=yyy always add "xxx"="yyy" to the json output and add shell env METER_xxx=yyy (--json_xxx=yyy also works)
|
||||
--license print GPLv3+ license
|
||||
|
@ -832,6 +868,12 @@ Or start nc explicitly in a pipe.
|
|||
nc -lku 4444 | wmbusmeters stdin:rtlwmbus
|
||||
```
|
||||
|
||||
Telegrams can also be pulled in by listening on MQTT topics if they were captured by other tools like [rtl_433](https://github.com/merbanan/rtl_433)
|
||||
```shell
|
||||
wmbusmeters 'hex:CMD(/usr/bin/mosquitto_sub -h 192.168.x.x -t rtl_433/device/devices/6/Wireless-MBus/+/data | tr -d "\n" )'
|
||||
```
|
||||
`+` is a wild card that listens to all the captured telegrams but can be replaced with a specific meter's ID
|
||||
|
||||
# Decoding hex string telegrams
|
||||
|
||||
If you have a single telegram as hex, which you want decoded, you do not need to create a simulation file,
|
||||
|
@ -988,10 +1030,21 @@ If you like to send the bytes manually, the correct bytes are:
|
|||
|
||||
# How to add a new driver
|
||||
|
||||
Drivers are self contained source code files named `src/driver_xyz.cc`
|
||||
They register themselves at startup. The source file also contains the necessary tests for that driver.
|
||||
Drivers for OMS-compliant meters are text files `drivers/src/*.xmq`
|
||||
First collect an unecrypted telegram as a hex string <hex> using --logtelegrams and any other driver.
|
||||
Then run `wmbusmeters --analyze <hex>` to see the best match.
|
||||
|
||||
Read more here: [doc/CreateDriver.md](doc/CreateDriver.md)
|
||||
Copy that meters aaa,xmq file to a new filename bbb.xmq and change the name field from aaa to bbb in the driver source.
|
||||
|
||||
Now run the new driver with `wmbusmeters --analyze=drivers/src/bbb.xmq <hex>`
|
||||
and start modifying the driver until it produces the desired json output.
|
||||
|
||||
You can now run `make; make install` from within the drivers directory
|
||||
and then rebuild from the wmbusmeters directory `make`. The new driver is now
|
||||
compiled into the binary.
|
||||
|
||||
You can also put the new driver file bbb.xmq into /etc/wmbusmeters.drivers.d and it will immediately
|
||||
be available to the wmbusmeters program without recompiling.
|
||||
|
||||
# Caveat
|
||||
|
||||
|
|
|
@ -2283,6 +2283,12 @@ freebsd*)
|
|||
CFLAGS="$CFLAGS -I/usr/local/include"
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -I/usr/local/include -I/opt/homebrew/include"
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/local/include -I/opt/homebrew/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib -L/opt/homebrew/lib"
|
||||
find /opt -name "*rtlsdr*"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@ freebsd*)
|
|||
CFLAGS="$CFLAGS -I/usr/local/include"
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -I/usr/local/include -I/opt/homebrew/include"
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/local/include -I/opt/homebrew/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib -L/opt/homebrew/lib"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
@ -1,362 +0,0 @@
|
|||
# Creating a new driver
|
||||
|
||||
To create a new driver, it is very convenient, to start with an existing driver,
|
||||
that mostly matches the one you want to integrate. I will use the EurisII as a base for
|
||||
Integration of Aventies HCA.
|
||||
|
||||
In fact, most of the manufacturers already exist in the source code
|
||||
with their respective shortcodes, e.g. Aventies with "AAA".
|
||||
|
||||
Create the `/etc/wmbusmeters.conf` with content adapted to your installation, e.g.:
|
||||
```
|
||||
loglevel=debug
|
||||
device=/dev/ttyUSB0:t1
|
||||
logtelegrams=true
|
||||
format=json
|
||||
meterfiles=/var/lib/wmbusmeters/meter_readings
|
||||
meterfilesaction=overwrite
|
||||
meterfilesnaming=name-id
|
||||
logfile=/var/log/wmbusmeters/wmbusmeters.log
|
||||
```
|
||||
|
||||
Create a meter config in `/etc/wmbusmeters.d/` with content like this, using the existing type, you selected as a base for your class (adjust also name, id and key to your needs):
|
||||
|
||||
```
|
||||
name=ABOGGLKZ
|
||||
driver=eurisii
|
||||
id=60900126
|
||||
key=xxxxxxxxx
|
||||
```
|
||||
|
||||
If you now start wmbusmeters with `wmbusmeters --debug --verbose --useconfig=/etc` and your meter transmits a message,
|
||||
you will see a log like this:
|
||||
|
||||
```
|
||||
[2021-07-05_21:07:30] (meter) ABOGGLKZ: meter detection did not match the selected driver eurisii! correct driver is: unknown!
|
||||
(meter) Not printing this warning again for id: 60900126 mfct: (AAA) Aventies, Germany (0x421) type: Heat Cost Allocator (0x08) ver: 0x55
|
||||
[2021-07-05_21:07:30] (meter) please consider opening an issue at https://github.com/wmbusmeters/wmbusmeters/
|
||||
[2021-07-05_21:07:30] (meter) to add support for this unknown mfct,media,version combination
|
||||
(meter) ABOGGLKZ: yes for me
|
||||
(meter) ABOGGLKZ eurisii handling telegram from 60900126
|
||||
(meter) ABOGGLKZ 60900126 "7644210426019060550872260190602104550806006005CA4269D455F02AE4A475AD546F7FF1EDF3C959E5480AA0A2341B6B6EA28884FA1E0EC355A23E66D055E3C790298553C3870727149DF88612ABF2EA184AEF0821B16BC11DA5BAABEFB34E4E68C6F2728D935011EAB98FCAA29274CC685B8079F7"
|
||||
(wmbus) parseDLL @0 119
|
||||
(telegram) DLL L=76 C=44 (from meter SND_NR) M=0421 (AAA) A=60900126 VER=55 TYPE=08 (Heat Cost Allocator) (driver unknown!) DEV=im871a[00101387] RSSI=-77
|
||||
(wmbus) parseELL @10 109
|
||||
(wmbus) parseAFL @10 109
|
||||
(wmbus) parseTPL @10 109
|
||||
(TPL) decrypting "CA4269D455F02AE4A475AD546F7FF1EDF3C959E5480AA0A2341B6B6EA28884FA1E0EC355A23E66D055E3C790298553C3870727149DF88612ABF2EA184AEF0821B16BC11DA5BAABEFB34E4E68C6F2728D935011EAB98FCAA29274CC685B8079F7"
|
||||
(TPL) num encrypted blocks 6 (96 bytes and remaining unencrypted 0 bytes)
|
||||
(TPL) IV 21042601906055080606060606060606
|
||||
(TPL) decrypted "2F2F0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000"
|
||||
(telegram) TPL CI=72 ACC=06 STS=00 CFG=0560 (AES_CBC_IV nb=6 cntn=0 ra=0 hc=0) ID=26019060 MFT=2104 VER=55 TYPE=08 (Heat Cost Allocator)
|
||||
telegram=|76442104260190605508722601906021045508060060052F2F|0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000|+6647
|
||||
(eurisii) 00: 76 length (118 bytes)
|
||||
(eurisii) 01: 44 dll-c (from meter SND_NR)
|
||||
(eurisii) 02: 2104 dll-mfct (AAA)
|
||||
(eurisii) 04: 26019060 dll-id (60900126)
|
||||
(eurisii) 08: 55 dll-version
|
||||
(eurisii) 09: 08 dll-type (Heat Cost Allocator)
|
||||
(eurisii) 0a: 72 tpl-ci-field (EN 13757-3 Application Layer (long tplh))
|
||||
(eurisii) 0b: 26019060 tpl-id (60900126)
|
||||
(eurisii) 0f: 2104 tpl-mfct (AAA)
|
||||
(eurisii) 11: 55 tpl-version
|
||||
(eurisii) 12: 08 tpl-type (Heat Cost Allocator)
|
||||
(eurisii) 13: 06 tpl-acc-field
|
||||
(eurisii) 14: 00 tpl-sts-field (OK)
|
||||
(eurisii) 15: 6005 tpl-cfg 0560 (AES_CBC_IV nb=6 cntn=0 ra=0 hc=0 )
|
||||
(eurisii) 17: 2f2f decrypt check bytes
|
||||
(eurisii) 19: 0B dif (6 digit BCD Instantaneous value)
|
||||
(eurisii) 1a: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 1b: * 660100 current consumption (166.000000 hca)
|
||||
(eurisii) 1e: 42 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 1f: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 20: * A600 consumption at set date 1 (166.000000 hca)
|
||||
(eurisii) 22: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 23: 01 dife (subunit=0 tariff=0 storagenr=2)
|
||||
(eurisii) 24: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 25: * A600 consumption at set date 2 (166.000000 hca)
|
||||
(eurisii) 27: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 28: 01 dife (subunit=0 tariff=0 storagenr=3)
|
||||
(eurisii) 29: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 2a: * 9E00 consumption at set date 3 (158.000000 hca)
|
||||
(eurisii) 2c: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 2d: 02 dife (subunit=0 tariff=0 storagenr=4)
|
||||
(eurisii) 2e: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 2f: * 7E00 consumption at set date 4 (126.000000 hca)
|
||||
(eurisii) 31: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 32: 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(eurisii) 33: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 34: * 5B00 consumption at set date 5 (91.000000 hca)
|
||||
(eurisii) 36: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 37: 03 dife (subunit=0 tariff=0 storagenr=6)
|
||||
(eurisii) 38: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 39: * 4200 consumption at set date 6 (66.000000 hca)
|
||||
(eurisii) 3b: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 3c: 03 dife (subunit=0 tariff=0 storagenr=7)
|
||||
(eurisii) 3d: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 3e: * 7701 consumption at set date 7 (375.000000 hca)
|
||||
(eurisii) 40: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 41: 04 dife (subunit=0 tariff=0 storagenr=8)
|
||||
(eurisii) 42: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 43: * 5B01 consumption at set date 8 (347.000000 hca)
|
||||
(eurisii) 45: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 46: 04 dife (subunit=0 tariff=0 storagenr=9)
|
||||
(eurisii) 47: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 48: * 4C01 consumption at set date 9 (332.000000 hca)
|
||||
(eurisii) 4a: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 4b: 05 dife (subunit=0 tariff=0 storagenr=10)
|
||||
(eurisii) 4c: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 4d: * 4701 consumption at set date 10 (327.000000 hca)
|
||||
(eurisii) 4f: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 50: 05 dife (subunit=0 tariff=0 storagenr=11)
|
||||
(eurisii) 51: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 52: * 3E01 consumption at set date 11 (318.000000 hca)
|
||||
(eurisii) 54: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 55: 06 dife (subunit=0 tariff=0 storagenr=12)
|
||||
(eurisii) 56: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 57: * 3B01 consumption at set date 12 (315.000000 hca)
|
||||
(eurisii) 59: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 5a: 06 dife (subunit=0 tariff=0 storagenr=13)
|
||||
(eurisii) 5b: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 5c: * 3B01 consumption at set date 13 (315.000000 hca)
|
||||
(eurisii) 5e: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 5f: 07 dife (subunit=0 tariff=0 storagenr=14)
|
||||
(eurisii) 60: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 61: * 3B01 consumption at set date 14 (315.000000 hca)
|
||||
(eurisii) 63: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 64: 07 dife (subunit=0 tariff=0 storagenr=15)
|
||||
(eurisii) 65: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 66: * 3B01 consumption at set date 15 (315.000000 hca)
|
||||
(eurisii) 68: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 69: 08 dife (subunit=0 tariff=0 storagenr=16)
|
||||
(eurisii) 6a: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 6b: * 1301 consumption at set date 16 (275.000000 hca)
|
||||
(eurisii) 6d: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(eurisii) 6e: 08 dife (subunit=0 tariff=0 storagenr=17)
|
||||
(eurisii) 6f: 6E vif (Units for H.C.A.)
|
||||
(eurisii) 70: * 9C00 consumption at set date 17 (156.000000 hca)
|
||||
(eurisii) 72: 02 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(eurisii) 73: FD vif (Second extension FD of VIF-codes)
|
||||
(eurisii) 74: 17 vife (Error flags (binary))
|
||||
(eurisii) 75: * 0000 error flags (0000)
|
||||
```
|
||||
|
||||
Now keep especially the following lines in mind for integation into the meter definitions:
|
||||
```
|
||||
[2021-07-05_21:07:30] (meter) ABOGGLKZ: meter detection did not match the selected driver eurisii! correct driver is: unknown!
|
||||
(meter) Not printing this warning again for id: 60900126 mfct: (AAA) Aventies, Germany (0x421) type: Heat Cost Allocator (0x08) ver: 0x55
|
||||
```
|
||||
|
||||
and the telegram line with the decrypted content.
|
||||
```
|
||||
telegram=|76442104260190605508722601906021045508060060052F2F#0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000|+6647
|
||||
```
|
||||
|
||||
You can now analyze the telegram with this command:
|
||||
```
|
||||
wmbusmeters --analyze 76442104260190605508722601906021045508060060052F2F0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000
|
||||
```
|
||||
|
||||
This will test all existing drivers to see which drivers seems to be matching the best. (This method can be improved so do some sanity checks as well.) If the driver already decodes 100% of the content then perhaps you should only add
|
||||
```
|
||||
di.addDetection(MANUFACTURER_AAA, 0x08, 0x55);
|
||||
```
|
||||
to the existing driver_eursii.cc file. But in this case we chose to create a new driver.
|
||||
(Remember to add a new test case at the end of the cc file.)
|
||||
|
||||
## Creating your new driver
|
||||
|
||||
As we used the eurisii meter as a template, you need to copy the driver_eurisii.cc to driver_xyz.cc replacing xyz
|
||||
with a name created by you. In my case it is driver_aventieshca.cc
|
||||
|
||||
As long as you do not need any new (not-yet-implemented) wmbus protocol features, then the
|
||||
entire driver is self contained within a single cc file, including tests.
|
||||
|
||||
Now replace all occurences of class name MeterEurisII by the class name you created (e.g. MeterAventiesHCA in my case).
|
||||
|
||||
Adjust the test cases at the end of the cc file! These test cases are picked up automatically
|
||||
by the testing system. Such regression tests are very important for the future stability of wmbusmeters.
|
||||
|
||||
Media/type 0x08 is the code for a Heat Cost allocator. You can find other codes here [here](https://m-bus.com/assets/downloads/MBDOC48.PDF) (on page 76). At least you should check for plausibility...
|
||||
|
||||
### Further adjustments
|
||||
|
||||
If you need to do processing that is not support by the current addFieldWithExtractor code, then
|
||||
you will have to implement the processContent function.
|
||||
|
||||
To collect the releavant data correctly, you need to adjust the code
|
||||
for processing and printing the data from the meter. For this you
|
||||
should edit the `MeterXXX::processContent` method to fit your
|
||||
needs. Adhere to the debug log output of the processing function and
|
||||
have a look at other meter's classes for examples how to process
|
||||
multiple values with different sorage numbers or types.
|
||||
|
||||
If you get errors, it is quite probable that you missed the correct value information (e.g. ValueInformation::Volume):
|
||||
```
|
||||
if(findKey(MeasurementType::Unknown, ValueInformation::Volume, 0, 0, &key, &t->values)) {
|
||||
extractDVdouble(&t->values, key, &offset, &total_water_consumption_m3_);
|
||||
t->addMoreExplanation(offset, " total consumption (%f m3)", total_water_consumption_m3_);
|
||||
}
|
||||
```
|
||||
|
||||
Possible ValueInformation types are:
|
||||
|
||||
- Volume (0x10,0x17)
|
||||
- OperatingTime (0x24,0x27)
|
||||
- VolumeFlow (0x38,0x3F)
|
||||
- FlowTemperature (0x58,0x5B)
|
||||
- ReturnTemperature (0x5C,0x5F)
|
||||
- TemperatureDifference (0x60,0x63)
|
||||
- ExternalTemperature (0x64,0x67)
|
||||
- HeatCostAllocation (0x6E,0x6E)
|
||||
- Date (0x6C,0x6C)
|
||||
- DateTime (0x6D,0x6D)
|
||||
- EnergyMJ (0x0E,0x0F)
|
||||
- EnergyWh (0x00,0x07)
|
||||
- PowerW (0x28,0x2f)
|
||||
- ActualityDuration (0x74,0x77)
|
||||
|
||||
You can add also special properties and getters for special data of your meter, like it is handled with the error codes for EurisII.
|
||||
|
||||
## Compiling and testing
|
||||
|
||||
If everything was right, you can try compiling the project:
|
||||
|
||||
```
|
||||
./configure
|
||||
make -j4
|
||||
```
|
||||
|
||||
Test your new version with the analyze command: `./build/wmbusmeters --analyze ...`
|
||||
|
||||
Now test your code:
|
||||
./build/wmbusmeters --format=json <hex> MyHCA aventieshca 12345678 NOKEY
|
||||
|
||||
It should print:
|
||||
```
|
||||
{"media":"heat cost allocation","meter":"aventieshca","name":"MyHCA","id":"60900126","current_consumption_hca":166,"consumption_at_set_date_hca":166,"consumption_at_set_date_2_hca":166,"consumption_at_set_date_3_hca":158,"consumption_at_set_date_4_hca":126,"consumption_at_set_date_5_hca":91,"consumption_at_set_date_6_hca":66,"consumption_at_set_date_7_hca":375,"consumption_at_set_date_8_hca":347,"consumption_at_set_date_9_hca":332,"consumption_at_set_date_10_hca":327,"consumption_at_set_date_11_hca":318,"consumption_at_set_date_12_hca":315,"consumption_at_set_date_13_hca":315,"consumption_at_set_date_14_hca":315,"consumption_at_set_date_15_hca":315,"consumption_at_set_date_16_hca":275,"consumption_at_set_date_17_hca":156,"error_flags":"","timestamp":"2022-01-18T10:04:08Z"}
|
||||
```
|
||||
|
||||
And now you can run it for real:
|
||||
./build_debug/wmbusmeters --format=json auto:t1 Water MyMeter 12345678 <key>
|
||||
|
||||
or using the config that you setup before:
|
||||
`./build/wmbusmeters --debug --verbose useconfig=/`
|
||||
|
||||
When it looks good, now run the tests:
|
||||
```
|
||||
make test
|
||||
```
|
||||
|
||||
If you have the time please try to build with debug information as well: `make DEBUG=true` and `make testd`
|
||||
This will test the code and check that there are no memory leaks or buffer overflows etc.
|
||||
|
||||
Finally try the daemon: make; sudo make install
|
||||
(Do the daemon reload command if such is requested.)
|
||||
sudo systemctl start wmbusmeters.service
|
||||
|
||||
Update the regression tests in the end of driver_aventieshca.cc
|
||||
|
||||
If again everything was ok, `sudo make install` the new wmbusmeters and start it.
|
||||
|
||||
## Provide some Information (for decumentation and debugging)
|
||||
|
||||
Now edit your meter config in `/etc/wmbusmeters.d/` to use the new meter type (mine is aventieshca).
|
||||
|
||||
The log should show the correct recognition (aventieshca)-tags at the beginning of each decoding line for your meter.
|
||||
```
|
||||
(aventieshca) 17: 2f2f decrypt check bytes
|
||||
(aventieshca) 19: 0B dif (6 digit BCD Instantaneous value)
|
||||
(aventieshca) 1a: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 1b: * 660100 current consumption (166.000000 hca)
|
||||
(aventieshca) 1e: 42 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 1f: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 20: * A600 consumption at set date 1 (166.000000 hca)
|
||||
(aventieshca) 22: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 23: 01 dife (subunit=0 tariff=0 storagenr=2)
|
||||
(aventieshca) 24: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 25: * A600 consumption at set date 2 (166.000000 hca)
|
||||
(aventieshca) 27: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 28: 01 dife (subunit=0 tariff=0 storagenr=3)
|
||||
(aventieshca) 29: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 2a: * 9E00 consumption at set date 3 (158.000000 hca)
|
||||
(aventieshca) 2c: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 2d: 02 dife (subunit=0 tariff=0 storagenr=4)
|
||||
(aventieshca) 2e: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 2f: * 7E00 consumption at set date 4 (126.000000 hca)
|
||||
(aventieshca) 31: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 32: 02 dife (subunit=0 tariff=0 storagenr=5)
|
||||
(aventieshca) 33: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 34: * 5B00 consumption at set date 5 (91.000000 hca)
|
||||
(aventieshca) 36: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 37: 03 dife (subunit=0 tariff=0 storagenr=6)
|
||||
(aventieshca) 38: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 39: * 4200 consumption at set date 6 (66.000000 hca)
|
||||
(aventieshca) 3b: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 3c: 03 dife (subunit=0 tariff=0 storagenr=7)
|
||||
(aventieshca) 3d: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 3e: * 7701 consumption at set date 7 (375.000000 hca)
|
||||
(aventieshca) 40: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 41: 04 dife (subunit=0 tariff=0 storagenr=8)
|
||||
(aventieshca) 42: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 43: * 5B01 consumption at set date 8 (347.000000 hca)
|
||||
(aventieshca) 45: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 46: 04 dife (subunit=0 tariff=0 storagenr=9)
|
||||
(aventieshca) 47: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 48: * 4C01 consumption at set date 9 (332.000000 hca)
|
||||
(aventieshca) 4a: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 4b: 05 dife (subunit=0 tariff=0 storagenr=10)
|
||||
(aventieshca) 4c: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 4d: * 4701 consumption at set date 10 (327.000000 hca)
|
||||
(aventieshca) 4f: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 50: 05 dife (subunit=0 tariff=0 storagenr=11)
|
||||
(aventieshca) 51: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 52: * 3E01 consumption at set date 11 (318.000000 hca)
|
||||
(aventieshca) 54: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 55: 06 dife (subunit=0 tariff=0 storagenr=12)
|
||||
(aventieshca) 56: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 57: * 3B01 consumption at set date 12 (315.000000 hca)
|
||||
(aventieshca) 59: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 5a: 06 dife (subunit=0 tariff=0 storagenr=13)
|
||||
(aventieshca) 5b: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 5c: * 3B01 consumption at set date 13 (315.000000 hca)
|
||||
(aventieshca) 5e: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 5f: 07 dife (subunit=0 tariff=0 storagenr=14)
|
||||
(aventieshca) 60: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 61: * 3B01 consumption at set date 14 (315.000000 hca)
|
||||
(aventieshca) 63: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 64: 07 dife (subunit=0 tariff=0 storagenr=15)
|
||||
(aventieshca) 65: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 66: * 3B01 consumption at set date 15 (315.000000 hca)
|
||||
(aventieshca) 68: 82 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 69: 08 dife (subunit=0 tariff=0 storagenr=16)
|
||||
(aventieshca) 6a: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 6b: * 1301 consumption at set date 16 (275.000000 hca)
|
||||
(aventieshca) 6d: C2 dif (16 Bit Integer/Binary Instantaneous value storagenr=1)
|
||||
(aventieshca) 6e: 08 dife (subunit=0 tariff=0 storagenr=17)
|
||||
(aventieshca) 6f: 6E vif (Units for H.C.A.)
|
||||
(aventieshca) 70: * 9C00 consumption at set date 17 (156.000000 hca)
|
||||
(aventieshca) 72: 02 dif (16 Bit Integer/Binary Instantaneous value)
|
||||
(aventieshca) 73: FD vif (Second extension FD of VIF-codes)
|
||||
(aventieshca) 74: 17 vife (Error flags (binary))
|
||||
(aventieshca) 75: * 0000 error flags (0000)
|
||||
```
|
||||
|
||||
You can also provide an encrypted telegram, the AES key for the telegram and the decoded data in your pull request for Fredrik to add it to the regression tests. The information is part of the log and looks like this:
|
||||
```
|
||||
(serial) received binary "A5C203764421042601906055087226019060210455080A00600537A7B807E3BA027FE98D75848595628733C29F2D3262F23BA4D2C01D37084E784691E115674D6D8CB874698D4D2C9DB3832A38A39021457A46F151FCBC86947EE7E35CF7AFC049381E74FB2B19E0F835B867B40D22E61129D395263441F4DED061B541"
|
||||
(im871a) checkIM871AFrame "A5C203764421042601906055087226019060210455080A00600537A7B807E3BA027FE98D75848595628733C29F2D3262F23BA4D2C01D37084E784691E115674D6D8CB874698D4D2C9DB3832A38A39021457A46F151FCBC86947EE7E35CF7AFC049381E74FB2B19E0F835B867B40D22E61129D395263441F4DED061B541"
|
||||
(im871a) has_timestamp=0 has_rssi=1 has_crc16=1
|
||||
[...]
|
||||
(TPL) decrypting "37A7B807E3BA027FE98D75848595628733C29F2D3262F23BA4D2C01D37084E784691E115674D6D8CB874698D4D2C9DB3832A38A39021457A46F151FCBC86947EE7E35CF7AFC049381E74FB2B19E0F835B867B40D22E61129D395263441F4DED0"
|
||||
(TPL) num encrypted blocks 6 (96 bytes and remaining unencrypted 0 bytes)
|
||||
(TPL) IV 21042601906055080A0A0A0A0A0A0A0A
|
||||
(TPL) decrypted "2F2F0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000"
|
||||
(telegram) TPL CI=72 ACC=0a STS=00 CFG=0560 (AES_CBC_IV nb=6 cntn=0 ra=0 hc=0) ID=26019060 MFT=2104 VER=55 TYPE=08 (Heat Cost Allocator)
|
||||
telegram=|764421042601906055087226019060210455080A0060052F2F|0B6E660100426EA60082016EA600C2016E9E0082026E7E00C2026E5B0082036E4200C2036E770182046E5B01C2046E4C0182056E4701C2056E3E0182066E3B01C2066E3B0182076E3B01C2076E3B0182086E1301C2086E9C0002FD170000|+7599
|
||||
```
|
||||
|
||||
It would also be handy to provide a datasheet of the sensor within the pull request.
|
||||
|
||||
That's all :-)
|
||||
Have fun!
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
$(shell mkdir -p build/test)
|
||||
|
||||
PROG?=wmbusmeters
|
||||
|
||||
database:
|
||||
@./generate.sh $(PROG)
|
||||
|
||||
web:
|
||||
@mkdir -p build/web
|
||||
@for i in $(wildcard src/*) ; do xmq $$i render-html --darkbg > build/web/$$(basename $${i}).html; done
|
||||
@./generate_index.sh > build/web/index.html
|
||||
|
||||
tests:
|
||||
@echo -n "// Generated " > build/generated_tests.xmq
|
||||
@date +%Y-%m-%d_%H:%M >> build/generated_tests.xmq
|
||||
@for i in $(wildcard src/*) ; do xmq $$i select /driver/test to-xmq >> build/generated_tests.xmq; done
|
||||
|
||||
install: database tests
|
||||
@grep -v "// Generated " < build/generated_database.cc > build/a
|
||||
@grep -v "// Generated " < ../src/generated_database.cc > build/b
|
||||
@if ! diff build/a build/b ; then \
|
||||
cp build/generated_database.cc ../src ; echo "Installed db"; else echo "No changes db." ; fi
|
||||
@grep -v "// Generated " < build/generated_tests.xmq > build/a
|
||||
@grep -v "// Generated " < ../tests/generated_tests.xmq > build/b
|
||||
@if ! diff build/a build/b ; then \
|
||||
cp build/generated_tests.xmq ../tests/generated_tests.xmq ; echo "Installed tests." ; else echo "No changes test." ; fi
|
||||
|
||||
test:
|
||||
@for i in $(wildcard src/*) ; do ./test.sh $(PROG) $$i ; done
|
||||
|
||||
.PHONY: database web tests install test
|
|
@ -0,0 +1,58 @@
|
|||
#!/bin/bash
|
||||
|
||||
export PROG="$1"
|
||||
export OUT="build/generated_database.cc"
|
||||
|
||||
cat > $OUT <<EOF
|
||||
/*
|
||||
Copyright (C) 2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Generated $(date +%Y-%m-%d_%H:%M)
|
||||
|
||||
BuiltinDriver builtins_[] =
|
||||
{
|
||||
EOF
|
||||
|
||||
# { "elster", "driver{name=elster meter_type=GasMeter default_fields=name,id,total_m3,timestamp detect{mvt=ELS,81,03}field{name=total quantity=Volume match{measurement_type=Instantaneous vif_range=Volume}}}", false },
|
||||
|
||||
for i in src/*.xmq
|
||||
do
|
||||
NAME=$(basename $i)
|
||||
NAME="${NAME%.*}"
|
||||
CONTENT="$(xmq $i delete /driver/test to-xmq --compact | sed 's/"/\\"/g')"
|
||||
cat >>$OUT <<EOF
|
||||
{ "$NAME", "$CONTENT", false },
|
||||
EOF
|
||||
done
|
||||
|
||||
cat >> $OUT <<EOF
|
||||
};
|
||||
|
||||
MapToDriver builtins_mvts_[] =
|
||||
{
|
||||
EOF
|
||||
|
||||
for i in src/*.xmq
|
||||
do
|
||||
NAME=$(basename $i)
|
||||
export NAME="${NAME%.*}"
|
||||
(xmq $i for-each /driver/detect/mvt --shell='./print_mvt.sh "${.}" "$NAME"') >> $OUT
|
||||
done
|
||||
|
||||
cat >> $OUT <<EOF
|
||||
};
|
||||
EOF
|
|
@ -0,0 +1 @@
|
|||
#!/bin/bash
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
MVT="$1"
|
||||
DRIVER="$2"
|
||||
|
||||
M=$(echo "$1" | cut -f 1 -d ',')
|
||||
V=$(echo "$1" | cut -f 2 -d ',')
|
||||
T=$(echo "$1" | cut -f 3 -d ',')
|
||||
|
||||
echo " { { MANUFACTURER_${M},0x${V},0x${T} }, \"$DRIVER\" },"
|
|
@ -0,0 +1,29 @@
|
|||
driver {
|
||||
name = elster
|
||||
meter_type = GasMeter
|
||||
default_fields = name,id,total_m3,timestamp
|
||||
detect {
|
||||
mvt = ELS,81,03
|
||||
}
|
||||
use = actuality_duration_s
|
||||
field {
|
||||
name = total
|
||||
quantity = Volume
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = Volume
|
||||
}
|
||||
about {
|
||||
de = 'Der Gesamtwasserverbrauch.'
|
||||
en = 'The total water consumption.'
|
||||
fr = '''La consommation totale d'eau.'''
|
||||
sv = 'Den totala vattenförbrukningen.'
|
||||
}
|
||||
}
|
||||
test {
|
||||
args = 'Gas elster 05105025 NOKEY'
|
||||
telegram = 3644A511640010253837722550100593158103E70020052F2F_0374E602000C137034220302FD74EE0F2F2F2F2F2F2F2F2F2F2F2F2F2F2F
|
||||
json = '{"media":"gas","meter":"elster","name":"Gas","id":"05105025","actuality_duration_s":742,"total_m3":3223.47,"timestamp":"1111-11-11T11:11:11Z"}'
|
||||
fields = 'Gas;05105025;3223.47;1111-11-11 11:11.11'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
driver {
|
||||
name = eltako
|
||||
default_fields = name,id,total_kwh,timestamp
|
||||
meter_type = ElectricityMeter
|
||||
detect {
|
||||
mvt = ELT,01,02
|
||||
}
|
||||
field {
|
||||
name = status
|
||||
quantity = Text
|
||||
info = status_and_error_flags
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = ErrorFlags
|
||||
}
|
||||
lookup {
|
||||
name = ERROR_FLAGS
|
||||
map_type = BitToString
|
||||
mask_bits = 0xff
|
||||
default_message = OK
|
||||
map {
|
||||
name = BUSY
|
||||
info = 'System is busy'
|
||||
value = 0x01
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = GENERIC_APP_ERROR
|
||||
info = 'Generic application error'
|
||||
value = 0x02
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = CURRENT_LOW
|
||||
info = 'Current too low'
|
||||
value = 0x04
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = PERMANENT_ERROR
|
||||
info = 'permanent error'
|
||||
value = 0x08
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = TEMPORARY_ERROR
|
||||
info = 'temporary error'
|
||||
value = 0x10
|
||||
test = Set
|
||||
}
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = 'total_tariff_1'
|
||||
quantity = Energy
|
||||
info = 'Total cumulative active energy per tariff.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyEnergyVIF
|
||||
tariff_nr = 1
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = 'total_tariff_2'
|
||||
quantity = Energy
|
||||
info = 'Total cumulative active energy per tariff.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyEnergyVIF
|
||||
tariff_nr = 2
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = 'total_reactive_tariff_{tariff_counter}'
|
||||
quantity = Energy
|
||||
info = 'Total cumulative reactive energy per tariff.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyEnergyVIF
|
||||
storage_nr = 2
|
||||
tariff_nr = 1,10
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = voltage_l1_n
|
||||
quantity = Voltage
|
||||
info = 'Instantaneous voltage between L1 and neutral.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = Voltage
|
||||
add_combinable = Mfct01
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = current_l1
|
||||
quantity = Amperage
|
||||
info = 'Instantaneous current in the L1 phase.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = Amperage
|
||||
add_combinable = Mfct01
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = power_l1
|
||||
quantity = Power
|
||||
info = 'active Power in L1 phase'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
add_combinable = Mfct01
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = reactive_power_l1
|
||||
quantity = Power
|
||||
info = 'reactive Power in L1 phase'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
subunit_nr = 1
|
||||
add_combinable = Mfct01
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = voltage_l2_n
|
||||
quantity = Voltage
|
||||
info = 'Instantaneous voltage between L2 and neutral.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = Voltage
|
||||
add_combinable = Mfct02
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = current_l2
|
||||
quantity = Amperage
|
||||
info = 'Instantaneous current in the L2 phase.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = Amperage
|
||||
add_combinable = Mfct02
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = power_l2
|
||||
quantity = Power
|
||||
info = 'active Power in L2 phase'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
add_combinable = Mfct02
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = reactive_power_l2
|
||||
quantity = Power
|
||||
info = 'reactive Power in L2 phase'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
subunit_nr = 1
|
||||
add_combinable = Mfct02
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = voltage_l3_n
|
||||
quantity = Voltage
|
||||
info = 'Instantaneous voltage between L3 and neutral.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = Voltage
|
||||
add_combinable = Mfct03
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = current_l3
|
||||
quantity = Amperage
|
||||
info = 'Instantaneous current in the L3 phase.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = Amperage
|
||||
add_combinable = Mfct03
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = power_l3
|
||||
quantity = Power
|
||||
info = 'active Power in L3 phase'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
add_combinable = Mfct03
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = reactive_power_l3
|
||||
quantity = Power
|
||||
info = 'reactive Power in L3 phase'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
subunit_nr = 1
|
||||
add_combinable = Mfct03
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = ct_numerator
|
||||
info = 'Current transformer ratio (numerator)'
|
||||
quantity = Dimensionless
|
||||
vif_scaling = None
|
||||
match {
|
||||
difvifkey = 02FF68
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = active_power_overall
|
||||
quantity = Power
|
||||
info = 'active Power overall'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
add_combinable = Mfct00
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = reactive_power_overall
|
||||
quantity = Power
|
||||
info = 'reactive Power overall'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_scaling = Auto
|
||||
vif_range = AnyPowerVIF
|
||||
subunit_nr = 1
|
||||
add_combinable = Mfct00
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = active_tariff
|
||||
info = 'active tariff'
|
||||
quantity = Dimensionless
|
||||
vif_scaling = None
|
||||
match {
|
||||
difvifkey = 01FF13
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = 'total'
|
||||
quantity = Energy
|
||||
info = 'Total active energy over all tariffs.'
|
||||
calculate = total_tariff_1_kwh+total_tariff_2_kwh
|
||||
}
|
||||
test {
|
||||
args = 'Eltako eltako 23451236 NOKEY'
|
||||
telegram = 689292680800723612452394150102cd0000008c1004688902008c1104688902008c2004000000008c21040000000002fdc9ff01ee0002fddBff01100002acff0120008240acff010a0002fdc9ff02ef0002fddBff02110002acff0224008240acff02070002fdc9ff03ee0002fddBff030e0002acff031c008240acff03060002ff68010002acff0062008240acff00190001ff1300f416
|
||||
json = '{"active_power_overall_kw": 0.98,"active_tariff_counter": 0,"ct_numerator_counter": 1,"current_l1_a": 1.6,"current_l2_a": 1.7,"current_l3_a": 1.4,"id": "23451236","media": "electricity","meter": "eltako","name": "Eltako","power_l1_kw": 0.32,"power_l2_kw": 0.36,"power_l3_kw": 0.28,"reactive_power_l1_kw": 0.1,"reactive_power_l2_kw": 0.07,"reactive_power_l3_kw": 0.06,"reactive_power_overall_kw": 0.25,"timestamp": "1111-11-11T11:11:11Z","total_kwh": 289.68,"total_reactive_tariff_1_kwh": 289.68,"total_reactive_tariff_2_kwh": 0,"total_tariff_1_kwh": 289.68,"total_tariff_2_kwh": 0,"voltage_l1_n_v": 238,"voltage_l2_n_v": 239,"voltage_l3_n_v": 238}'
|
||||
fields = 'Eltako;23451236;289.68;1111-11-11 11:11.11'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
driver {
|
||||
name = iperl
|
||||
meter_type = WaterMeter
|
||||
default_fields = name,id,total_m3,max_flow_m3h,timestamp
|
||||
detect {
|
||||
mvt = SEN,68,06
|
||||
mvt = SEN,68,07
|
||||
mvt = SEN,7c,07
|
||||
}
|
||||
field {
|
||||
name = total
|
||||
quantity = Volume
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = Volume
|
||||
}
|
||||
about {
|
||||
de = 'Der Gesamtwasserverbrauch.'
|
||||
en = 'The total water consumption.'
|
||||
fr = '''La consommation totale d'eau.'''
|
||||
sv = 'Den totala vattenförbrukningen.'
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = max_flow
|
||||
quantity = Flow
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = VolumeFlow
|
||||
}
|
||||
about {
|
||||
en = 'The maximum flow recorded during previous period.'
|
||||
}
|
||||
}
|
||||
test {
|
||||
args = 'MoreWater iperl 12345699 NOKEY'
|
||||
coment = 'Test iPerl T1 telegram, that after decryption, has 2f2f markers.'
|
||||
telegram = 1E44AE4C9956341268077A36001000_2F2F0413181E0000023B00002F2F2F2F
|
||||
json = '{"media":"water","meter":"iperl","name":"MoreWater","id":"12345699","total_m3":7.704,"max_flow_m3h":0,"timestamp":"1111-11-11T11:11:11Z"}'
|
||||
fields = 'MoreWater;12345699;7.704;0;1111-11-11 11:11.11'
|
||||
}
|
||||
test {
|
||||
args = 'WaterWater iperl 33225544 NOKEY'
|
||||
comment = 'Test iPerl T1 telegram not encrypted, which has no 2f2f markers.'
|
||||
telegram = 1844AE4C4455223368077A55000000_041389E20100023B0000
|
||||
json = '{"media":"water","meter":"iperl","name":"WaterWater","id":"33225544","total_m3":123.529,"max_flow_m3h":0,"timestamp":"1111-11-11T11:11:11Z"}'
|
||||
fields = 'WaterWater;33225544;123.529;0;1111-11-11 11:11.11'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
driver {
|
||||
name = kampress
|
||||
default_fields = name,id,status,pressure_bar,max_pressure_bar,min_pressure_bar,timestamp
|
||||
meter_type = PressureSensor
|
||||
detect {
|
||||
mvt = KAM,01,18
|
||||
}
|
||||
field {
|
||||
name = status
|
||||
quantity = Text
|
||||
info = status_and_error_flags
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = ErrorFlags
|
||||
}
|
||||
lookup {
|
||||
name = ERROR_FLAGS
|
||||
map_type = BitToString
|
||||
mask_bits = 0xffff
|
||||
default_message = OK
|
||||
map {
|
||||
name = DROP
|
||||
info = 'Unexpected drop in pressure in relation to average pressure.'
|
||||
value = 0x01
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = SURGE
|
||||
info = 'Unexpected increase in pressure in relation to average pressure.'
|
||||
value = 0x02
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = HIGH
|
||||
info = 'Average pressure has reached configurable limit. Default 15 bar.'
|
||||
value = 0x04
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = LOW
|
||||
info = 'Average pressure has reached configurable limit. Default 1.5 bar.'
|
||||
value = 0x08
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = TRANSIENT
|
||||
info = 'Pressure changes quickly over short timeperiods. Average is fluctuating.'
|
||||
value = 0x10
|
||||
test = Set
|
||||
}
|
||||
map {
|
||||
name = COMM_ERROR
|
||||
info = 'Cannot measure properly or bad internal communication.'
|
||||
value = 0x20
|
||||
test = Set
|
||||
}
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = pressure
|
||||
quantity = Pressure
|
||||
info = 'The measured pressure.'
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = Pressure
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = max_pressure
|
||||
quantity = Pressure
|
||||
info = 'The maximum pressure measured during ?'
|
||||
match {
|
||||
measurement_type = Maximum
|
||||
vif_range = Pressure
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = min_pressure
|
||||
quantity = Pressure
|
||||
info = 'The minimum pressure measured during ?'
|
||||
match {
|
||||
measurement_type = Minimum
|
||||
vif_range = Pressure
|
||||
}
|
||||
}
|
||||
field {
|
||||
name = alfa
|
||||
info = 'We do not know what this is.'
|
||||
quantity = Dimensionless
|
||||
vif_scaling = None
|
||||
match {
|
||||
difvifkey = 05FF09
|
||||
}
|
||||
}
|
||||
|
||||
field {
|
||||
name = beta
|
||||
info = 'We do not know what this is.'
|
||||
quantity = Dimensionless
|
||||
vif_scaling = None
|
||||
match {
|
||||
difvifkey = 05FF0A
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
args = 'Pressing kampress 77000317 NOKEY'
|
||||
telegram = 32442D2C1703007701188D280080E39322DB8F78_22696600126967000269660005FF091954A33A05FF0A99BD823A02FD170800
|
||||
json = '{"media":"pressure","meter":"kampress","name":"Pressing","id":"77000317","status":"LOW","pressure_bar":1.02,"max_pressure_bar":1.03,"min_pressure_bar":1.02,"alfa_counter":0.001246,"beta_counter":0.000997,"timestamp":"1111-11-11T11:11:11Z"}'
|
||||
fields = 'Pressing;77000317;LOW;1.02;1.03;1.02;1111-11-11 11:11.11'
|
||||
}
|
||||
|
||||
test {
|
||||
args = 'Pressing kampress 77000317 NOKEY'
|
||||
telegram = '32442D2C1703007701188D280080E39322DB8F78_22696600126967000269660005FF091954A33A05FF0A99BD823A02FD170800
|
||||
27442D2C1703007701188D280194E393226EC679DE735657_660067006600962B913A21B9423A0800'
|
||||
json = '{"media":"pressure","meter":"kampress","name":"Pressing","id":"77000317","status":"LOW","pressure_bar":1.02,"max_pressure_bar":1.03,"min_pressure_bar":1.02,"alfa_counter":0.001108,"beta_counter":0.000743,"timestamp":"1111-11-11T11:11:11Z"}'
|
||||
fields = 'Pressing;77000317;LOW;1.02;1.03;1.02;1111-11-11 11:11.11'
|
||||
}
|
||||
|
||||
test {
|
||||
args = 'Pressing kampress 77000317 NOKEY'
|
||||
telegram = '32442D2C1703007701188D280080E39322DB8F78_22696600126967000269660005FF091954A33A05FF0A99BD823A02FD170800
|
||||
27442D2C1703007701188D289554F295224ED579DE73188A_650066006600E80EA43A6B97A3BA0800'
|
||||
json = '{"media":"pressure","meter":"kampress","name":"Pressing","id":"77000317","status":"LOW","pressure_bar":1.02,"max_pressure_bar":1.02,"min_pressure_bar":1.01,"alfa_counter":0.001252,"beta_counter":-0.001248,"timestamp":"1111-11-11T11:11:11Z"}'
|
||||
fields = 'Pressing;77000317;LOW;1.02;1.02;1.01;1111-11-11 11:11.11'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
driver {
|
||||
name = werhlemodwm
|
||||
meter_type = WaterMeter
|
||||
default_fields = name,id,total_m3,timestamp
|
||||
detect {
|
||||
mvt = WZG,03,16
|
||||
}
|
||||
use = meter_datetime
|
||||
use = target_date
|
||||
use = target_m3
|
||||
use = total_m3
|
||||
use = fabrication_no
|
||||
field {
|
||||
name = next_target
|
||||
quantity = PointInTime
|
||||
display_unit = date
|
||||
match {
|
||||
measurement_type = Instantaneous
|
||||
vif_range = Date
|
||||
add_combinable = FutureValue
|
||||
storage_nr = 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
export PROG="$1"
|
||||
export DRIVER="$2"
|
||||
echo Testing $DRIVER
|
||||
xmq $DRIVER for-each /driver/test --shell='./test_case.sh "$PROG" "$DRIVER" "${args}" "${telegram}" "${json}" "${fields}" "$1"'
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
|
||||
TEST=build/test
|
||||
|
||||
PROG="$1"
|
||||
DRIVER="$2"
|
||||
ARGS="$3"
|
||||
HEX="$4"
|
||||
JSON="$5"
|
||||
FIELDS="$6"
|
||||
|
||||
rm -f $TEST/test_output.txt $TEST/test_expected.txt $TEST/simulation_tmp.txt
|
||||
|
||||
echo "$HEX" | sed 's/^/telegram=/g' > $TEST/simulation_tmp.txt
|
||||
|
||||
$PROG --driver=$DRIVER --format=json $TEST/simulation_tmp.txt $ARGS \
|
||||
| tail -n 1 \
|
||||
| jq . --sort-keys \
|
||||
| sed 's/"timestamp": "....-..-..T..:..:..Z"/"timestamp": "1111-11-11T11:11:11Z"/' \
|
||||
> $TEST/test_output.txt
|
||||
|
||||
echo "$JSON" | jq . --sort-keys > $TEST/test_expected.txt
|
||||
|
||||
if ! diff $TEST/test_expected.txt $TEST/test_output.txt
|
||||
then
|
||||
if [ "$USE_MELD" = "true" ]
|
||||
then
|
||||
meld $TEST/test_expected.txt $TEST/test_output.txt
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f $TEST/test_output.txt $TEST/test_expected.txt
|
||||
|
||||
$PROG --driver=$DRIVER --format=fields $TEST/simulation_tmp.txt $ARGS \
|
||||
| sed 's/....-..-.. ..:..:../1111-11-11 11:11.11/' \
|
||||
| tail -n 1 \
|
||||
> $TEST/test_output.txt
|
||||
|
||||
echo "$FIELDS" > $TEST/test_expected.txt
|
||||
|
||||
if ! diff $TEST/test_expected.txt $TEST/test_output.txt
|
||||
then
|
||||
if [ "$USE_MELD" = "true" ]
|
||||
then
|
||||
meld $TEST/test_expected.txt $TEST/test_output.txt
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,2 @@
|
|||
telegram=|7B4479169977997730378C208B900F002C25E4EF0A002EA98E7D58B3ADC57299779977991611028B005087102F2F#0DFD090F34302e3030562030303030303030300D790E31323334353637383839595345310DFD100AAAAAAAAAAAAAAAAAAAAA0D780E31323334353637383930594553312F2F2F2F2F2F2F2F2F2F2F|
|
||||
telegram=|7B4479169977997730378C20F0900F002C2549EE0A0077C19D3D1A08ABCD729977997779161102F0005007102F2F#0702F5C3FA000000000007823C5407000000000000841004E081020084200415000000042938AB000004A9FF01FA0A000004A9FF02050A000004A9FF03389600002F2F2F2F2F2F2F2F2F2F2F2F2F|
|
|
@ -0,0 +1,19 @@
|
|||
telegram=|A244EE4D785634123C067A8F000000_0C1348550000426CE1F14C130000000082046C21298C0413330000008D04931E3A3CFE3300000033000000330000003300000033000000330000003300000033000000330000003300000033000000330000004300000034180000046D0D0B5C2B03FD6C5E150082206C5C290BFD0F0200018C4079678885238310FD3100000082106C01018110FD610002FD66020002FD170000|
|
||||
{"media":"warm water","meter":"supercom587","name":"MyWarmWater","id":"12345678","total_m3":5.548,"software_version":"010002","status":"OK","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|MyWarmWater;12345678;5.548;1111-11-11 11:11.11
|
||||
|
||||
telegram=|A244EE4D111111113C077AAC000000_0C1389490000426CE1F14C130000000082046C21298C0413010000008D04931E3A3CFE0100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000001600000031130000046D0A0C5C2B03FD6C60150082206C5C290BFD0F0200018C4079629885238310FD3100000082106C01018110FD610002FD66020002FD170000|
|
||||
{"media":"water","meter":"supercom587","name":"MyColdWater","id":"11111111","total_m3":4.989,"software_version":"010002","status":"OK","timestamp":"1111-11-11T11:11:11Z"}
|
||||
|MyColdWater;11111111;4.989;1111-11-11 11:11.11
|
||||
|
||||
telegram=|1E44AE4C9956341268077A36001000_2F2F0413181E0000023B00002F2F2F2F|
|
||||
{"media":"water","meter":"iperl","name":"MoreWater","id":"12345699","total_m3":7.704,"max_flow_m3h":0,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|MoreWater;12345699;7.704;0;1111-11-11 11:11.11
|
||||
|
||||
telegram=|1844AE4C4455223368077A55000000_041389E20100023B0000|
|
||||
{"media":"water","meter":"iperl","name":"WaterWater","id":"33225544","total_m3":123.529,"max_flow_m3h":0,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|WaterWater;33225544;123.529;0;1111-11-11 11:11.11
|
||||
|
||||
telegram=|31446850226677116980A0119F27020480048300C408F709143C003D341A2B0B2A0707000000000000062D114457563D71A1850000|
|
||||
{"media":"heat cost allocator","meter":"fhkvdataiii","name":"Room","id":"11776622","current_hca":131,"current_date":"2020-02-08T02:00:00Z","previous_hca":1026,"previous_date":"2019-12-31T02:00:00Z","temp_room_c":22.44,"temp_radiator_c":25.51,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|Room;11776622;131;2020-02-08T02:00:00Z;1026;2019-12-31T02:00:00Z;22.44;25.51;1111-11-11 11:11.11
|
|
@ -0,0 +1,4 @@
|
|||
telegram=|414493447514916746377275149167934446044D000020_0C06490000004C0600000000426CFF2CCC080611000000C2086C1F3102FD170000326CFFFF046D330F1432|
|
||||
telegram=|5b44934475149167463778077975149167934446040dff5f3500823d0000810007c006ffff49000000ff2c000000001f3111000000008000800080008000800080008000800080000000000B002f02fd170000046d390d1432488408|
|
||||
telegram=|414493447514916746377275149167934446044D000020_0C06490000004C0600000000426CFF2CCC080611000000C2086C1F3102FD170000326CFFFF046D330F1432|
|
||||
telegram=|5b44934475149167463778077975149167934446040dff5f3500823d0000810007c006ffff49000000ff2c000000001f3111000000008000800080008000800080008000800080000000000B002f02fd170000046d390d1432488408|
|
|
@ -60,7 +60,7 @@ telegram=|374468506549235827C3A2_129F25383300A8622600008200800A2AF86211517555287
|
|||
# Test FHKV data II/III
|
||||
# There is a problem in the decoding here, the data stored inside the telegram does not seem to properly encode/decode the year....
|
||||
# We should not report a current_date with a full year, if the year is actually not part of the telegram.
|
||||
telegram=|31446850226677116980A0119F27020480048300C408F709143C003D341A2B0B2A0707000000000000062D114457563D71A1850000|
|
||||
telegram=|34446850226677116980A0119F27020480048300C408F709143C003D341A2B0B2A0707000000000000062D114457563D71A1850000|
|
||||
{"media":"heat cost allocator","meter":"fhkvdataiii","name":"Room","id":"11776622","current_hca":131,"current_date":"2020-02-08T02:00:00Z","previous_hca":1026,"previous_date":"2019-12-31T02:00:00Z","temp_room_c":22.44,"temp_radiator_c":25.51,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|Room;11776622;131;2020-02-08T02:00:00Z;1026;2019-12-31T02:00:00Z;22.44;25.51;1111-11-11 11:11.11
|
||||
|
||||
|
@ -199,7 +199,7 @@ telegram=|3944FA122162092002067A3600202567C94D48D00DC47B11213E23383DB51968A705AA
|
|||
# Test topaseskr water meter
|
||||
|
||||
telegram=|4E44B40512345678F1077A310040052F2F_01FD08040C13991848004C1359423500CC101300000000CC201359423500426C7F2C0B3B00000002FD74DA10025AD300C4016D3B179F27CC011387124600|
|
||||
{"media":"water","meter":"topaseskr","name":"Witer","id":"78563412","total_m3":481.899,"access_counter":4,"temperature_c":21.1,"current_flow_m3h":0,"volume_year_period_m3":354.259,"reverse_volume_year_period_m3":0,"meter_year_period_start_date":"2019-12-31","volume_month_period_m3":461.287,"meter_month_period_start_datetime":"2020-07-31 23:59","battery_y":11.811331,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
{"media":"water","meter":"topaseskr","name":"Witer","id":"78563412","total_m3":481.899,"access_counter":4,"temperature_c":21.1,"current_flow_m3h":0,"volume_year_period_m3":354.259,"reverse_volume_year_period_m3":0,"meter_year_period_end_date":"2019-12-31","volume_month_period_m3":461.287,"meter_month_period_end_datetime":"2020-07-31 23:59","battery_y":11.811331,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
|Witer;78563412;481.899;21.1;0;354.259;0;2019-12-31;461.287;2020-07-31 23:59;1111-11-11 11:11.11
|
||||
|
||||
# Test Ultrimis water meter
|
||||
|
|
|
@ -0,0 +1,656 @@
|
|||
/*
|
||||
Copyright (C) 2017-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include"address.h"
|
||||
#include"manufacturers.h"
|
||||
|
||||
#include<assert.h>
|
||||
#include<algorithm>
|
||||
#include<string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<string> splitSequenceOfAddressExpressionsAtCommas(const string& mes);
|
||||
bool isValidMatchExpression(const std::string& s, bool *has_wildcard);
|
||||
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 *required_found,
|
||||
bool *required_failed);
|
||||
|
||||
bool isValidMatchExpression(const string& s, bool *has_wildcard)
|
||||
{
|
||||
string me = s;
|
||||
|
||||
// Examples of valid match expressions:
|
||||
// 12345678
|
||||
// *
|
||||
// 123*
|
||||
// !12345677
|
||||
// 2222222*
|
||||
// !22222222
|
||||
// We also accept an secondary libmbus address:
|
||||
// 100002842941011B
|
||||
|
||||
// A match expression cannot be empty.
|
||||
if (me.length() == 0) return false;
|
||||
|
||||
// An me can be filtered out with an exclamation mark first.
|
||||
if (me.front() == '!') me.erase(0, 1);
|
||||
|
||||
// More than one negation is not allowed.
|
||||
if (me.front() == '!') return false;
|
||||
|
||||
// A match expression cannot be only a negation mark.
|
||||
if (me.length() == 0) return false;
|
||||
|
||||
int count = 0;
|
||||
// Some non-compliant meters have full hex in the id,
|
||||
// but according to the standard there should only be bcd here...
|
||||
// We accept hex anyway.
|
||||
while (me.length() > 0 &&
|
||||
((me.front() >= '0' && me.front() <= '9') ||
|
||||
(me.front() >= 'A' && me.front() <= 'F') ||
|
||||
(me.front() >= 'a' && me.front() <= 'f')))
|
||||
{
|
||||
me.erase(0,1);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (me.length() == 0 && count == 16)
|
||||
{
|
||||
// A secondary libmbus address: 100002842941011B
|
||||
// Strictly speaking the leading 8 digits should be bcd,
|
||||
// but we accept hex as well.
|
||||
*has_wildcard = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wildcard_used = false;
|
||||
// An expression can end with a *
|
||||
if (me.length() > 0 && me.front() == '*')
|
||||
{
|
||||
me.erase(0,1);
|
||||
wildcard_used = true;
|
||||
if (has_wildcard) *has_wildcard = true;
|
||||
}
|
||||
|
||||
// Now we should have eaten the whole expression.
|
||||
if (me.length() > 0) return false;
|
||||
|
||||
// Check the length of the matching bcd/hex
|
||||
// If no wildcard is used, then the match expression must be exactly 8 digits.
|
||||
if (!wildcard_used) return count == 8;
|
||||
|
||||
// If wildcard is used, then the match expressions must be 7 or less digits,
|
||||
// even zero is allowed which means a single *, which matches any bcd/hex id.
|
||||
return count <= 7;
|
||||
}
|
||||
|
||||
vector<string> splitSequenceOfAddressExpressionsAtCommas(const string& mes)
|
||||
{
|
||||
vector<string> r;
|
||||
bool eof, err;
|
||||
vector<uchar> v (mes.begin(), mes.end());
|
||||
auto i = v.begin();
|
||||
|
||||
for (;;) {
|
||||
auto id = eatTo(v, i, ',', 64, &eof, &err);
|
||||
if (err) break;
|
||||
trimWhitespace(&id);
|
||||
if (id == "ANYID") id = "*";
|
||||
r.push_back(id);
|
||||
if (eof) break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool isValidSequenceOfAddressExpressions(const string& mes)
|
||||
{
|
||||
vector<string> v = splitSequenceOfAddressExpressionsAtCommas(mes);
|
||||
|
||||
for (string me : v)
|
||||
{
|
||||
AddressExpression ae;
|
||||
if (!ae.parse(me)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vector<AddressExpression> splitAddressExpressions(const string &aes)
|
||||
{
|
||||
vector<string> v = splitSequenceOfAddressExpressionsAtCommas(aes);
|
||||
|
||||
vector<AddressExpression> r;
|
||||
|
||||
for (string me : v)
|
||||
{
|
||||
AddressExpression ae;
|
||||
if (ae.parse(me))
|
||||
{
|
||||
r.push_back(ae);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool doesIdMatchExpression(const string& s, string match)
|
||||
{
|
||||
string id = s;
|
||||
if (id.length() == 0) return false;
|
||||
|
||||
// Here we assume that the match expression has been
|
||||
// verified to be valid.
|
||||
bool can_match = true;
|
||||
|
||||
// Now match bcd/hex until end of id, or '*' in match.
|
||||
while (id.length() > 0 && match.length() > 0 && match.front() != '*')
|
||||
{
|
||||
if (id.front() != match.front())
|
||||
{
|
||||
// We hit a difference, it cannot match.
|
||||
can_match = false;
|
||||
break;
|
||||
}
|
||||
id.erase(0,1);
|
||||
match.erase(0,1);
|
||||
}
|
||||
|
||||
bool wildcard_used = false;
|
||||
if (match.length() && match.front() == '*')
|
||||
{
|
||||
wildcard_used = true;
|
||||
match.erase(0,1);
|
||||
}
|
||||
|
||||
if (can_match)
|
||||
{
|
||||
// Ok, now the match expression should be empty.
|
||||
// If wildcard is true, then the id can still have digits,
|
||||
// otherwise it must also be empty.
|
||||
if (wildcard_used)
|
||||
{
|
||||
can_match = match.length() == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
can_match = match.length() == 0 && id.length() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
return can_match;
|
||||
}
|
||||
|
||||
bool hasWildCard(const string& mes)
|
||||
{
|
||||
return mes.find('*') != string::npos;
|
||||
}
|
||||
|
||||
bool AddressExpression::match(const std::string &i, uint16_t m, uchar v, uchar t)
|
||||
{
|
||||
if (!(mfct == 0xffff || mfct == m)) return false;
|
||||
if (!(version == 0xff || version == v)) return false;
|
||||
if (!(type == 0xff || type == t)) return false;
|
||||
if (!doesIdMatchExpression(i, id)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddressExpression::trimToIdentity(IdentityMode im, Address &a)
|
||||
{
|
||||
switch (im)
|
||||
{
|
||||
case IdentityMode::FULL:
|
||||
id = a.id;
|
||||
mfct = a.mfct;
|
||||
version = a.version;
|
||||
type = a.type;
|
||||
required = true;
|
||||
break;
|
||||
case IdentityMode::ID_MFCT:
|
||||
id = a.id;
|
||||
mfct = a.mfct;
|
||||
version = 0xff;
|
||||
type = 0xff;
|
||||
required = true;
|
||||
break;
|
||||
case IdentityMode::ID:
|
||||
id = a.id;
|
||||
mfct = 0xffff;
|
||||
version = 0xff;
|
||||
type = 0xff;
|
||||
required = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool AddressExpression::parse(const string &in)
|
||||
{
|
||||
string s = in;
|
||||
// Example: 12345678
|
||||
// or 12345678.M=PII.T=1B.V=01
|
||||
// or 1234*
|
||||
// or 1234*.M=PII
|
||||
// or 1234*.V=01
|
||||
// or 12 // mbus primary
|
||||
// or 0 // mbus primary
|
||||
// or 250.MPII.V01.T1B // mbus primary
|
||||
// or !12345678
|
||||
// or !*.M=ABC
|
||||
// or libmbus secondary style:
|
||||
// 123456782941011B
|
||||
id = "";
|
||||
mbus_primary = false;
|
||||
mfct = 0xffff;
|
||||
type = 0xff;
|
||||
version = 0xff;
|
||||
filter_out = false;
|
||||
|
||||
if (s.size() == 0) return false;
|
||||
|
||||
if (s.size() > 1 && s[0] == '!')
|
||||
{
|
||||
filter_out = true;
|
||||
s = s.substr(1);
|
||||
// Double ! not allowed.
|
||||
if (s.size() > 1 && s[0] == '!') return false;
|
||||
}
|
||||
vector<string> parts = splitString(s, '.');
|
||||
|
||||
assert(parts.size() > 0);
|
||||
|
||||
id = parts[0];
|
||||
if (!isValidMatchExpression(id, &has_wildcard))
|
||||
{
|
||||
// Not a long id, so lets check if it is p0 to p250 for primary mbus ids.
|
||||
if (id.size() < 2) return false;
|
||||
if (id[0] != 'p') return false;
|
||||
for (size_t i=1; i < id.length(); ++i)
|
||||
{
|
||||
if (!isdigit(id[i])) return false;
|
||||
}
|
||||
// All digits good.
|
||||
int v = atoi(id.c_str()+1);
|
||||
if (v < 0 || v > 250) return false;
|
||||
// It is 0-250 which means it is an mbus primary address.
|
||||
mbus_primary = true;
|
||||
}
|
||||
|
||||
if (parts.size() == 1 && id.length() == 16)
|
||||
{
|
||||
// This is a secondary libmbus address.
|
||||
string mfct_hex = id.substr(8,4);
|
||||
string version_hex = id.substr(12,2);
|
||||
string type_hex = id.substr(14,2);
|
||||
id = id.substr(0,8);
|
||||
|
||||
vector<uchar> data;
|
||||
bool ok = hex2bin(mfct_hex.c_str(), &data);
|
||||
if (!ok) return false;
|
||||
if (data.size() != 2) return false;
|
||||
mfct = data[1] << 8 | data[0];
|
||||
|
||||
data.clear();
|
||||
ok = hex2bin(version_hex.c_str(), &data);
|
||||
if (!ok) return false;
|
||||
if (data.size() != 1) return false;
|
||||
version = data[0];
|
||||
|
||||
data.clear();
|
||||
ok = hex2bin(type_hex.c_str(), &data);
|
||||
if (!ok) return false;
|
||||
if (data.size() != 1) return false;
|
||||
type = data[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i=1; i<parts.size(); ++i)
|
||||
{
|
||||
if (parts[i].size() == 4) // V=xy or T=xy
|
||||
{
|
||||
if (parts[i][1] != '=') return false;
|
||||
|
||||
vector<uchar> data;
|
||||
bool ok = hex2bin(&parts[i][2], &data);
|
||||
if (!ok) return false;
|
||||
if (data.size() != 1) return false;
|
||||
|
||||
if (parts[i][0] == 'V')
|
||||
{
|
||||
version = data[0];
|
||||
}
|
||||
else if (parts[i][0] == 'T')
|
||||
{
|
||||
type = data[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (parts[i].size() == 5) // M=xyz
|
||||
{
|
||||
if (parts[i][1] != '=') return false;
|
||||
if (parts[i][0] != 'M') return false;
|
||||
|
||||
bool ok = flagToManufacturer(&parts[i][2], &mfct);
|
||||
if (!ok) return false;
|
||||
}
|
||||
else if (parts[i].size() == 6) // M=abcd explicit hex version
|
||||
{
|
||||
if (parts[i][1] != '=') return false;
|
||||
if (parts[i][0] != 'M') return false;
|
||||
|
||||
vector<uchar> data;
|
||||
bool ok = hex2bin(&parts[i][2], &data);
|
||||
if (!ok) return false;
|
||||
if (data.size() != 2) return false;
|
||||
|
||||
mfct = data[1] << 8 | data[0];
|
||||
if (!ok) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flagToManufacturer(const char *s, uint16_t *out_mfct)
|
||||
{
|
||||
if (s[0] == 0 || s[1] == 0 || s[2] == 0 || s[3] != 0) return false;
|
||||
if (s[0] < '@' || s[0] > 'Z' ||
|
||||
s[1] < '@' || s[1] > 'Z' ||
|
||||
s[2] < '@' || s[2] > 'Z') return false;
|
||||
|
||||
*out_mfct = MANFCODE(s[0],s[1],s[2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
string AddressExpression::str()
|
||||
{
|
||||
string s;
|
||||
|
||||
if (filter_out) s = "!";
|
||||
if (required) s = "R";
|
||||
|
||||
s.append(id);
|
||||
if (mfct != 0xffff)
|
||||
{
|
||||
s += ".M="+manufacturerFlag(mfct);
|
||||
}
|
||||
if (version != 0xff)
|
||||
{
|
||||
s += ".V="+tostrprintf("%02x", version);
|
||||
}
|
||||
if (type != 0xff)
|
||||
{
|
||||
s += ".T="+tostrprintf("%02x", type);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
string Address::str()
|
||||
{
|
||||
string s;
|
||||
|
||||
s.append(id);
|
||||
if (mfct != 0xffff)
|
||||
{
|
||||
s += ".M="+manufacturerFlag(mfct);
|
||||
}
|
||||
if (version != 0xff)
|
||||
{
|
||||
s += ".V="+tostrprintf("%02x", version);
|
||||
}
|
||||
if (type != 0xff)
|
||||
{
|
||||
s += ".T="+tostrprintf("%02x", type);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
string Address::concat(std::vector<Address> &addresses)
|
||||
{
|
||||
string s;
|
||||
for (Address& a: addresses)
|
||||
{
|
||||
if (s.size() > 0) s.append(",");
|
||||
s.append(a.str());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
string AddressExpression::concat(std::vector<AddressExpression> &address_expressions)
|
||||
{
|
||||
string s;
|
||||
for (AddressExpression& a: address_expressions)
|
||||
{
|
||||
if (s.size() > 0) s.append(",");
|
||||
s.append(a.str());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
string manufacturerFlag(int m_field) {
|
||||
char a = (m_field/1024)%32+64;
|
||||
char b = (m_field/32)%32+64;
|
||||
char c = (m_field)%32+64;
|
||||
|
||||
string flag;
|
||||
flag += a;
|
||||
flag += b;
|
||||
flag += c;
|
||||
return flag;
|
||||
}
|
||||
|
||||
void Address::decodeMfctFirst(const vector<uchar>::iterator &pos)
|
||||
{
|
||||
mfct = *(pos+1) << 8 | *(pos+0);
|
||||
id = tostrprintf("%02x%02x%02x%02x", *(pos+5), *(pos+4), *(pos+3), *(pos+2));
|
||||
version = *(pos+6);
|
||||
type = *(pos+7);
|
||||
}
|
||||
|
||||
void Address::decodeIdFirst(const vector<uchar>::iterator &pos)
|
||||
{
|
||||
id = tostrprintf("%02x%02x%02x%02x", *(pos+3), *(pos+2), *(pos+1), *(pos+0));
|
||||
mfct = *(pos+5) << 8 | *(pos+4);
|
||||
version = *(pos+6);
|
||||
type = *(pos+7);
|
||||
}
|
||||
|
||||
bool doesTelegramMatchExpressions(std::vector<Address> &addresses,
|
||||
std::vector<AddressExpression>& address_expressions,
|
||||
bool *used_wildcard)
|
||||
{
|
||||
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,
|
||||
&required_found,
|
||||
&required_failed))
|
||||
{
|
||||
match = true;
|
||||
}
|
||||
// Go through all ids even though there is an early match.
|
||||
// This way we can see if theres an exact match later.
|
||||
}
|
||||
// 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 *required_found,
|
||||
bool *required_failed)
|
||||
{
|
||||
bool found_match = false;
|
||||
bool found_negative_match = false;
|
||||
bool exact_match = false;
|
||||
|
||||
// Goes through all possible match expressions.
|
||||
// If no expression matches, neither positive nor negative,
|
||||
// then the result is false. (ie no match)
|
||||
|
||||
// If more than one positive match is found, and no negative,
|
||||
// then the result is true.
|
||||
|
||||
// If more than one negative match is found, irrespective
|
||||
// if there is any positive matches or not, then the result is false.
|
||||
|
||||
// If a positive match is found, using a wildcard not any exact match,
|
||||
// then *used_wildcard is set to true.
|
||||
|
||||
// If an expression is required and it fails, then the match fails.
|
||||
for (AddressExpression &ae : address_expressions)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (m) found_negative_match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
// A match, but the required does not count.
|
||||
if (!is_required)
|
||||
{
|
||||
found_match = true;
|
||||
if (!has_wildcard)
|
||||
{
|
||||
exact_match = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*required_failed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_negative_match)
|
||||
{
|
||||
*filtered_out = true;
|
||||
return false;
|
||||
}
|
||||
if (found_match)
|
||||
{
|
||||
if (exact_match)
|
||||
{
|
||||
*used_wildcard = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*used_wildcard = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *toString(IdentityMode im)
|
||||
{
|
||||
switch (im)
|
||||
{
|
||||
case IdentityMode::ID: return "id";
|
||||
case IdentityMode::ID_MFCT: return "id-mfct";
|
||||
case IdentityMode::FULL: return "full";
|
||||
case IdentityMode::NONE: return "none";
|
||||
case IdentityMode::INVALID: return "invalid";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
IdentityMode toIdentityMode(const char *s)
|
||||
{
|
||||
if (!strcmp(s,"id")) return IdentityMode::ID;
|
||||
if (!strcmp(s,"id-mfct")) return IdentityMode::ID_MFCT;
|
||||
if (!strcmp(s, "full")) return IdentityMode::FULL;
|
||||
if (!strcmp(s, "none")) return IdentityMode::NONE;
|
||||
return IdentityMode::INVALID;
|
||||
}
|
||||
|
||||
void AddressExpression::clear()
|
||||
{
|
||||
id = "";
|
||||
has_wildcard = false;
|
||||
mbus_primary = false;
|
||||
mfct = 0xffff;
|
||||
version = 0xff;
|
||||
type = 0xff;
|
||||
}
|
||||
|
||||
void AddressExpression::appendIdentity(IdentityMode im,
|
||||
AddressExpression *identity_expression,
|
||||
std::vector<Address> &as,
|
||||
std::vector<AddressExpression> &es)
|
||||
{
|
||||
identity_expression->clear();
|
||||
if (im == IdentityMode::NONE) return;
|
||||
|
||||
// Copy id, id-mfct, id-mfct-v-t to identity_expression from the last address.
|
||||
identity_expression->trimToIdentity(im, as.back());
|
||||
|
||||
// Is this identity expression already in the list of address expressions?
|
||||
if (std::find(es.begin(), es.end(), *identity_expression) == es.end())
|
||||
{
|
||||
// No, then add it at the end.
|
||||
es.push_back(*identity_expression);
|
||||
}
|
||||
}
|
||||
|
||||
bool AddressExpression::operator==(const AddressExpression&ae) const
|
||||
{
|
||||
return id == ae.id &&
|
||||
has_wildcard == ae.has_wildcard&&
|
||||
mbus_primary == ae.mbus_primary &&
|
||||
mfct == ae.mfct &&
|
||||
version == ae.version &&
|
||||
type == ae.type &&
|
||||
filter_out == ae.filter_out;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Copyright (C) 2017-2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ADDRESS_H_
|
||||
#define ADDRESS_H_
|
||||
|
||||
#include "util.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
IdentityMode:
|
||||
|
||||
@ID: The default, only the id groups the meter content.
|
||||
@ID_MFCT: Used when you have two meters with the same id but different manufacturers.
|
||||
@FULL: Used when you want to fully separate meter content on id.mft.v.t
|
||||
@NONE: Do not separate any meters! This might lead to telegrams overwriting each others state.
|
||||
Use this when no state is to be kept in the wmbusmeters object.
|
||||
@INVALID: Cannot parse cmdline.
|
||||
*/
|
||||
enum class IdentityMode
|
||||
{
|
||||
ID,
|
||||
ID_MFCT,
|
||||
FULL,
|
||||
NONE,
|
||||
INVALID
|
||||
};
|
||||
|
||||
const char *toString(IdentityMode im);
|
||||
IdentityMode toIdentityMode(const char *s);
|
||||
|
||||
struct Address
|
||||
{
|
||||
std::string id; // p1 or 12345678 or non-compliant hex: 1234abcd
|
||||
uint16_t mfct {};
|
||||
uchar type {};
|
||||
uchar version {};
|
||||
|
||||
void decodeMfctFirst(const std::vector<uchar>::iterator &pos);
|
||||
void decodeIdFirst(const std::vector<uchar>::iterator &pos);
|
||||
|
||||
std::string str();
|
||||
static std::string concat(std::vector<Address> &addresses);
|
||||
};
|
||||
|
||||
struct AddressExpression
|
||||
{
|
||||
// An address expression is used to select which telegrams to decode for a driver.
|
||||
// An address expression is also used to select a specific meter to poll for data.
|
||||
// Example address: 12345678
|
||||
// Or fully qualified: 12345678.M=PII.T=1b.V=01
|
||||
// which means manufacturer triplet PII, type/media=0x1b, version=0x01
|
||||
// Or wildcards in id: 12*.T=16
|
||||
// which matches all cold water meters whose ids start with 12.
|
||||
// Or negated tests: 12345678.V!=66
|
||||
// which will decode all telegrams from 12345678 except those where the version is 0x66.
|
||||
// Or every telegram which is does not start with 12 and is not from ABB:
|
||||
// !12*.M!=ABB
|
||||
|
||||
std::string id; // p1 or 12345678 or non-compliant hex: 1234abcd
|
||||
bool has_wildcard {}; // The id contains a *
|
||||
bool mbus_primary {}; // Signals that the id is 0-250
|
||||
|
||||
uint16_t mfct { 0xffff }; // If 0xffff then any mfct matches this address.
|
||||
uchar version { 0xff }; // If 0xff then any version matches this address.
|
||||
uchar type { 0xff }; // If 0xff then any type matches this address.
|
||||
|
||||
bool filter_out {}; // Telegrams matching this rule should be filtered out!
|
||||
bool required {}; // If true, then this address expression must be matched!
|
||||
|
||||
AddressExpression() {}
|
||||
AddressExpression(Address &a) : id(a.id), mfct(a.mfct), version(a.version), type(a.type) { }
|
||||
bool operator==(const AddressExpression&) const;
|
||||
void clear();
|
||||
void trimToIdentity(IdentityMode im, Address &a);
|
||||
bool parse(const std::string &s);
|
||||
bool match(const std::string &id, uint16_t mfct, uchar version, uchar type);
|
||||
std::string str();
|
||||
static std::string concat(std::vector<AddressExpression> &address_expressions);
|
||||
static void appendIdentity(IdentityMode im,
|
||||
AddressExpression *identity_expression,
|
||||
std::vector<Address> &as,
|
||||
std::vector<AddressExpression> &es);
|
||||
};
|
||||
|
||||
/**
|
||||
isValidSequenceOfAddressExpressions:
|
||||
|
||||
Valid sequenes look like this:
|
||||
12345678
|
||||
12345678,22334455,34*
|
||||
12*.T=16,!*.M=XYZ
|
||||
!*.V=33
|
||||
*/
|
||||
bool isValidSequenceOfAddressExpressions(const std::string& s);
|
||||
std::vector<AddressExpression> splitAddressExpressions(const std::string &aes);
|
||||
bool flagToManufacturer(const char *s, uint16_t *out_mfct);
|
||||
std::string manufacturerFlag(int m_field);
|
||||
bool doesTelegramMatchExpressions(std::vector<Address> &addresses,
|
||||
std::vector<AddressExpression>& address_expressions,
|
||||
bool *used_wildcard);
|
||||
|
||||
#endif
|
|
@ -75,7 +75,6 @@ private:
|
|||
// Then check if the rtl_sdr and/or rtl_wmbus and/or rtl_433 is available.
|
||||
bool rtlsdr_found_ = false;
|
||||
bool rtlwmbus_found_ = false;
|
||||
bool rtl433_found_ = false;
|
||||
|
||||
// Remember devices that were not detected as wmbus devices.
|
||||
// To avoid probing them again and again.
|
||||
|
|
|
@ -617,6 +617,15 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
|
|||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "--identitymode=", 15) && strlen(argv[i]) > 15) {
|
||||
c->identity_mode = toIdentityMode(argv[i]+15);
|
||||
if (c->identity_mode == IdentityMode::INVALID)
|
||||
{
|
||||
error("Not a valid identity mode. \"%s\"\n", argv[i]+15);
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(argv[i], "--resetafter=", 13) && strlen(argv[i]) > 13) {
|
||||
c->resetafter = parseTime(argv[i]+13);
|
||||
if (c->resetafter <= 0) {
|
||||
|
@ -728,50 +737,31 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
|
|||
string bus;
|
||||
string name = argv[m*4+i+0];
|
||||
string driver = argv[m*4+i+1];
|
||||
string id = argv[m*4+i+2];
|
||||
string address_expressions = argv[m*4+i+2];
|
||||
string key = argv[m*4+i+3];
|
||||
|
||||
MeterInfo mi;
|
||||
mi.parse(name, driver, id, key);
|
||||
|
||||
if (!isValidSequenceOfAddressExpressions(address_expressions))
|
||||
{
|
||||
error("Not a valid meter id nor a valid sequence of match expression \"%s\"\n", address_expressions.c_str());
|
||||
}
|
||||
|
||||
mi.parse(name, driver, address_expressions, key);
|
||||
mi.poll_interval = c->pollinterval;
|
||||
mi.identity_mode = c->identity_mode;
|
||||
|
||||
if (!isValidKey(key, mi))
|
||||
{
|
||||
error("Not a valid meter key \"%s\"\n", key.c_str());
|
||||
}
|
||||
|
||||
if (mi.driver_name.str() == "")
|
||||
{
|
||||
error("Not a valid meter driver \"%s\"\n", driver.c_str());
|
||||
}
|
||||
|
||||
//LinkModeSet default_modes = toMeterLinkModeSet(mi.driver);
|
||||
|
||||
/*
|
||||
if (default_modes.has(LinkMode::MBUS))
|
||||
{
|
||||
// MBus primary address 0-250
|
||||
// secondary hex address iiiiiiiimmmmvvmm
|
||||
}
|
||||
else
|
||||
{
|
||||
// WMBus ids are 8 hex digits iiiiiiii
|
||||
if (!isValidMatchExpressions(id, true)) error("Not a valid id nor a valid meter match expression \"%s\"\n", id.c_str());
|
||||
}
|
||||
if (!isValidKey(key, mi)) error("Not a valid meter key \"%s\"\n", key.c_str());
|
||||
*/
|
||||
|
||||
c->meters.push_back(mi);
|
||||
|
||||
// Check if the devices can listen to the meter link mode(s).
|
||||
/*
|
||||
Ignore this check for now until all meters have been refactored.
|
||||
if (!default_modes.hasAll(mi.link_modes))
|
||||
{
|
||||
string want = mi.link_modes.hr();
|
||||
string has = default_modes.hr();
|
||||
error("(cmdline) cannot set link modes to: %s because meter %s only transmits on: %s\n",
|
||||
want.c_str(), mi.driverName().str().c_str(), has.c_str());
|
||||
}
|
||||
string modeshr = mi.link_modes.hr();
|
||||
debug("(cmdline) setting link modes to %s for meter %s\n",
|
||||
mi.link_modes.hr().c_str(), name.c_str());
|
||||
*/
|
||||
}
|
||||
|
||||
return shared_ptr<Configuration>(c);
|
||||
|
|
|
@ -53,10 +53,11 @@ void parseMeterConfig(Configuration *c, vector<char> &buf, string file)
|
|||
string bus;
|
||||
string name;
|
||||
string driver = "auto";
|
||||
string id;
|
||||
string address_expressions;
|
||||
string key = "";
|
||||
string linkmodes;
|
||||
int poll_interval = 0;
|
||||
IdentityMode identity_mode {};
|
||||
vector<string> telegram_shells;
|
||||
vector<string> meter_shells;
|
||||
vector<string> alarm_shells;
|
||||
|
@ -108,7 +109,7 @@ void parseMeterConfig(Configuration *c, vector<char> &buf, string file)
|
|||
else
|
||||
if (p.first == "driver") driver = p.second;
|
||||
else
|
||||
if (p.first == "id") id = p.second;
|
||||
if (p.first == "id") address_expressions = p.second;
|
||||
else
|
||||
if (p.first == "key")
|
||||
{
|
||||
|
@ -129,6 +130,15 @@ void parseMeterConfig(Configuration *c, vector<char> &buf, string file)
|
|||
}
|
||||
}
|
||||
else
|
||||
if (p.first == "identitymode") {
|
||||
identity_mode = toIdentityMode(p.second.c_str());
|
||||
|
||||
if (identity_mode == IdentityMode::INVALID)
|
||||
{
|
||||
error("Invalid identity mode: \"%s\"!\n", p.second.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
if (p.first == "shell") {
|
||||
telegram_shells.push_back(p.second);
|
||||
}
|
||||
|
@ -176,37 +186,28 @@ void parseMeterConfig(Configuration *c, vector<char> &buf, string file)
|
|||
|
||||
MeterInfo mi;
|
||||
|
||||
mi.parse(name, driver, id, key); // sets driver, extras, name, bus, bps, link_modes, ids, name, key
|
||||
mi.poll_interval = poll_interval;
|
||||
|
||||
/*
|
||||
Ignore link mode checking until all drivers have been refactored.
|
||||
LinkModeSet default_modes = toMeterLinkModeSet(mi.driver);
|
||||
if (!default_modes.hasAll(mi.link_modes))
|
||||
if (!isValidSequenceOfAddressExpressions(address_expressions))
|
||||
{
|
||||
string want = mi.link_modes.hr();
|
||||
string has = default_modes.hr();
|
||||
error("(cmdline) cannot set link modes to: %s because meter %s only transmits on: %s\n",
|
||||
want.c_str(), mi.driverName().str().c_str(), has.c_str());
|
||||
}
|
||||
string modeshr = mi.link_modes.hr();
|
||||
debug("(cmdline) setting link modes to %s for meter %s\n",
|
||||
mi.link_modes.hr().c_str(), name.c_str());
|
||||
*/
|
||||
if (!isValidMatchExpressions(id, true)) {
|
||||
warning("Not a valid meter id nor a valid meter match expression \"%s\"\n", id.c_str());
|
||||
warning("In config, not a valid meter id nor a valid sequence of match expression \"%s\"\n", address_expressions.c_str());
|
||||
use = false;
|
||||
}
|
||||
if (!isValidKey(key, mi)) {
|
||||
warning("Not a valid meter key \"%s\"\n", key.c_str());
|
||||
|
||||
mi.parse(name, driver, address_expressions, key); // sets driver, extras, name, bus, bps, link_modes, ids, name, key
|
||||
mi.poll_interval = poll_interval;
|
||||
mi.identity_mode = identity_mode;
|
||||
|
||||
if (!isValidKey(key, mi))
|
||||
{
|
||||
warning("In config, not a valid meter key in config \"%s\"\n", key.c_str());
|
||||
use = false;
|
||||
}
|
||||
if (use) {
|
||||
|
||||
if (use)
|
||||
{
|
||||
mi.extra_constant_fields = extra_constant_fields;
|
||||
mi.extra_calculated_fields = extra_calculated_fields;
|
||||
mi.shells = telegram_shells;
|
||||
mi.meter_shells = meter_shells;
|
||||
mi.idsc = toIdsCommaSeparated(mi.ids);
|
||||
mi.selected_fields = selected_fields;
|
||||
c->meters.push_back(mi);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@ struct Configuration
|
|||
bool json {};
|
||||
bool pretty_print_json {};
|
||||
int pollinterval {}; // Time between polling of mbus meters.
|
||||
IdentityMode identity_mode {}; // How to group meters identities into state objects.
|
||||
bool fields {};
|
||||
char separator { ';' };
|
||||
std::vector<std::string> telegram_shells;
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace
|
|||
"Total cumulative active imported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -58,7 +58,7 @@ namespace
|
|||
"Total cumulative active imported energy per tariff.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -71,7 +71,7 @@ namespace
|
|||
"Total cumulative active exported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -85,7 +85,7 @@ namespace
|
|||
"Total cumulative active exported energy per tariff.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -99,7 +99,7 @@ namespace
|
|||
"Active tariff.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("01FF9300")),
|
||||
Unit::NUMBER
|
||||
|
@ -110,7 +110,7 @@ namespace
|
|||
"Current transformer ratio (numerator).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FFA015")),
|
||||
Unit::FACTOR
|
||||
|
@ -121,7 +121,7 @@ namespace
|
|||
"Voltage transformer ratio (numerator).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FFA115")),
|
||||
Unit::FACTOR
|
||||
|
@ -132,7 +132,7 @@ namespace
|
|||
"Current transformer ratio (denominator).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FFA215")),
|
||||
Unit::FACTOR
|
||||
|
@ -143,7 +143,7 @@ namespace
|
|||
"Voltage transformer ratio (denominator).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FFA315")),
|
||||
Unit::FACTOR
|
||||
|
@ -157,7 +157,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(DifVifKey("07FFA600")),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xffffffffffffffff))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -170,7 +170,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(DifVifKey("07FFA700")),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("WARNING_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("WARNING_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xffffffffffffffff))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -183,7 +183,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(DifVifKey("07FFA800")),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("INFORMATION_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("INFORMATION_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xffffffffffffffff))
|
||||
.set(DefaultMessage(""))
|
||||
));
|
||||
|
@ -196,7 +196,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(DifVifKey("07FFA900")),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ALARM_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ALARM_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xfffffffffffffff))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -209,7 +209,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(DifVifKey("01FFAD00")),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("UNKNOWN", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("UNKNOWN", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xff))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -236,7 +236,7 @@ namespace
|
|||
"Power fail counter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FF9800"))
|
||||
);
|
||||
|
@ -246,7 +246,7 @@ namespace
|
|||
"Instantaneous total active imported power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -258,7 +258,7 @@ namespace
|
|||
"Instantaneous active imported power for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -271,7 +271,7 @@ namespace
|
|||
"Instantaneous active imported power for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -284,7 +284,7 @@ namespace
|
|||
"Instantaneous active imported power for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -297,7 +297,7 @@ namespace
|
|||
"Instantaneous total reactive imported power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -310,7 +310,7 @@ namespace
|
|||
"Instantaneous reactive imported power for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -324,7 +324,7 @@ namespace
|
|||
"Instantaneous reactive imported power for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -338,7 +338,7 @@ namespace
|
|||
"Instantaneous reactive imported power for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -352,7 +352,7 @@ namespace
|
|||
"Instantaneous total apparent imported power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -365,7 +365,7 @@ namespace
|
|||
"Instantaneous apparent imported power for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -379,7 +379,7 @@ namespace
|
|||
"Instantaneous apparent imported power for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -393,7 +393,7 @@ namespace
|
|||
"Instantaneous apparent imported power for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -407,7 +407,7 @@ namespace
|
|||
"Instantaneous voltage between L1 and neutral.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -420,7 +420,7 @@ namespace
|
|||
"Instantaneous voltage between L2 and neutral.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -433,7 +433,7 @@ namespace
|
|||
"Instantaneous voltage between L3 and neutral.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -446,7 +446,7 @@ namespace
|
|||
"Instantaneous voltage between L1 and L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -459,7 +459,7 @@ namespace
|
|||
"Instantaneous voltage between L2 and L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -472,7 +472,7 @@ namespace
|
|||
"Instantaneous voltage between L3 and L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -485,7 +485,7 @@ namespace
|
|||
"Instantaneous current in the L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -498,7 +498,7 @@ namespace
|
|||
"Instantaneous current in the L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -511,7 +511,7 @@ namespace
|
|||
"Instantaneous current in the L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -524,7 +524,7 @@ namespace
|
|||
"Frequency of AC",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Frequency,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0AFFD900")),
|
||||
Unit::HZ,
|
||||
|
@ -536,7 +536,7 @@ namespace
|
|||
"Power factor.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFE000")),
|
||||
Unit::FACTOR,
|
||||
|
@ -548,7 +548,7 @@ namespace
|
|||
"Power factor for phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFE0FF8100")),
|
||||
Unit::FACTOR,
|
||||
|
@ -560,7 +560,7 @@ namespace
|
|||
"Power factor for phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFE0FF8200")),
|
||||
Unit::FACTOR,
|
||||
|
@ -572,7 +572,7 @@ namespace
|
|||
"Power factor.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFE0FF8300")),
|
||||
Unit::FACTOR,
|
||||
|
@ -584,7 +584,7 @@ namespace
|
|||
"Total power phase angle.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Angle,
|
||||
VifScaling::NoneSigned,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFD200")),
|
||||
Unit::DEGREE,
|
||||
|
@ -596,7 +596,7 @@ namespace
|
|||
"Power phase angle for phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Angle,
|
||||
VifScaling::NoneSigned,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFD2FF8100")),
|
||||
Unit::DEGREE,
|
||||
|
@ -608,7 +608,7 @@ namespace
|
|||
"Power phase angle for phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Angle,
|
||||
VifScaling::NoneSigned,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFD2FF8200")),
|
||||
Unit::DEGREE,
|
||||
|
@ -620,7 +620,7 @@ namespace
|
|||
"Power phase angle for phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Angle,
|
||||
VifScaling::NoneSigned,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FFD2FF8300")),
|
||||
Unit::DEGREE,
|
||||
|
@ -632,7 +632,7 @@ namespace
|
|||
"Total cumulative reactive kvarh imported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Reactive_Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -646,7 +646,7 @@ namespace
|
|||
"Total cumulative reactive kvarh imported energy per tariff.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -660,7 +660,7 @@ namespace
|
|||
"Total cumulative reactive kvarh exported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Reactive_Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -674,7 +674,7 @@ namespace
|
|||
"Total cumulative reactive kvarh exported energy per tariff.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -688,7 +688,7 @@ namespace
|
|||
"The quadrant in which the current is measured.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("01FF9700")),
|
||||
Unit::NUMBER
|
||||
|
@ -699,7 +699,7 @@ namespace
|
|||
"The quadrant in which the current is measured for phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("01FF97FF8100")),
|
||||
Unit::NUMBER
|
||||
|
@ -710,7 +710,7 @@ namespace
|
|||
"The quadrant in which the current is measured for phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("01FF97FF8200")),
|
||||
Unit::NUMBER
|
||||
|
@ -721,7 +721,7 @@ namespace
|
|||
"The quadrant in which the current is measured for phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("01FF97FF8300")),
|
||||
Unit::NUMBER
|
||||
|
@ -739,7 +739,7 @@ namespace
|
|||
.set(SubUnitNr(1),SubUnitNr(2))
|
||||
.add(VIFCombinableRaw(0)),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("OUTPUT", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("OUTPUT", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xff))
|
||||
));
|
||||
|
||||
|
@ -753,7 +753,7 @@ namespace
|
|||
.set(SubUnitNr(3),SubUnitNr(4))
|
||||
.add(VIFCombinableRaw(0)),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("INPUT", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("INPUT", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xff))
|
||||
));
|
||||
|
||||
|
@ -768,7 +768,7 @@ namespace
|
|||
.set(SubUnitNr(3),SubUnitNr(4))
|
||||
.add(VIFCombinableRaw(0)),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("INPUT", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("INPUT", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xff))
|
||||
));
|
||||
|
||||
|
@ -777,7 +777,7 @@ namespace
|
|||
"Number of times input 1-2 counted a 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(SubUnitNr(3),SubUnitNr(4))
|
||||
|
@ -790,7 +790,7 @@ namespace
|
|||
"Resettable cumulative active imported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -803,7 +803,7 @@ namespace
|
|||
"Resettable cumulative active exported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -817,7 +817,7 @@ namespace
|
|||
"Resettable cumulative reactive imported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -831,7 +831,7 @@ namespace
|
|||
"Resettable cumulative reactive exported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -845,7 +845,7 @@ namespace
|
|||
"Number of times the resettable energy imported value has been reset.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRaw(0x7f71))
|
||||
|
@ -857,7 +857,7 @@ namespace
|
|||
"Number of times the resettable active energy exported value has been reset.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRaw(0x7f71))
|
||||
|
@ -870,7 +870,7 @@ namespace
|
|||
"Number of times the resettable reactive energy imported value has been reset.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRaw(0x7f71))
|
||||
|
@ -883,7 +883,7 @@ namespace
|
|||
"Number of times the resettable reactive energy exported value has been reset.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRaw(0x7f71))
|
||||
|
@ -896,7 +896,7 @@ namespace
|
|||
"Energy in co2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Mass,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0EFFF9C400")),
|
||||
Unit::KG,
|
||||
|
@ -908,7 +908,7 @@ namespace
|
|||
"CO2 conversion factor (kg * 10-3 /kWh).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FFA400")),
|
||||
Unit::FACTOR
|
||||
|
@ -919,7 +919,7 @@ namespace
|
|||
"Energy in currency.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0EFFF9C900"))
|
||||
);
|
||||
|
@ -929,7 +929,7 @@ namespace
|
|||
"Currency conversion factor (curr * 10-3 /kWh).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FFA500")),
|
||||
Unit::FACTOR
|
||||
|
@ -940,7 +940,7 @@ namespace
|
|||
"Total cumulative apparent kvah imported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Apparent_Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -954,7 +954,7 @@ namespace
|
|||
"Total cumulative apparent kvah exported energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Apparent_Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -968,7 +968,7 @@ namespace
|
|||
"Total imported active energy for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -981,7 +981,7 @@ namespace
|
|||
"Total imported active energy for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -994,7 +994,7 @@ namespace
|
|||
"Total imported active energy for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1007,7 +1007,7 @@ namespace
|
|||
"Total imported reactive energy for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1021,7 +1021,7 @@ namespace
|
|||
"Total imported reactive energy for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1035,7 +1035,7 @@ namespace
|
|||
"Total imported reactive energy for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1049,7 +1049,7 @@ namespace
|
|||
"Total imported apparent energy for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1063,7 +1063,7 @@ namespace
|
|||
"Total imported apparent energy for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1077,7 +1077,7 @@ namespace
|
|||
"Total imported apparent energy for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1091,7 +1091,7 @@ namespace
|
|||
"Total exported active energy for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1105,7 +1105,7 @@ namespace
|
|||
"Total exported active energy for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1119,7 +1119,7 @@ namespace
|
|||
"Total exported active energy for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1133,7 +1133,7 @@ namespace
|
|||
"Total exported reactive energy for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1147,7 +1147,7 @@ namespace
|
|||
"Total exported reactive energy for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1161,7 +1161,7 @@ namespace
|
|||
"Total exported reactive energy for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1175,7 +1175,7 @@ namespace
|
|||
"Total exported apparent energy for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1189,7 +1189,7 @@ namespace
|
|||
"Total exported apparent energy for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1203,7 +1203,7 @@ namespace
|
|||
"Total exported apparent energy for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1217,7 +1217,7 @@ namespace
|
|||
"Active net energy total.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1230,7 +1230,7 @@ namespace
|
|||
"Active net energy total for phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1244,7 +1244,7 @@ namespace
|
|||
"Active net energy total for phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1258,7 +1258,7 @@ namespace
|
|||
"Active net energy total for phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1272,7 +1272,7 @@ namespace
|
|||
"Active net energy total.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1286,7 +1286,7 @@ namespace
|
|||
"Active net reactive energy total for phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1301,7 +1301,7 @@ namespace
|
|||
"Active net reactive energy total for phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1316,7 +1316,7 @@ namespace
|
|||
"Active net reactive energy total for phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1331,7 +1331,7 @@ namespace
|
|||
"Active net energy total.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1345,7 +1345,7 @@ namespace
|
|||
"Active net apparent energy total for phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1360,7 +1360,7 @@ namespace
|
|||
"Active net apparent energy total for phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -1375,7 +1375,7 @@ namespace
|
|||
"Active net apparent energy total for phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace
|
|||
"The total gas consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -53,7 +53,7 @@ namespace
|
|||
"The current gas flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -64,7 +64,7 @@ namespace
|
|||
"The current temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"Date time when previous billing period ended.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
|
@ -87,7 +87,7 @@ namespace
|
|||
"The total gas consumption recorded when the previous billing period ended.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -54,7 +54,7 @@ namespace
|
|||
"Current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::PowerW)
|
||||
|
@ -65,7 +65,7 @@ namespace
|
|||
"The total energy production recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0E833C"))
|
||||
);
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"Current power production.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0BAB3C"))
|
||||
);
|
||||
|
@ -85,7 +85,7 @@ namespace
|
|||
"Voltage at phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0AFDC9FC01"))
|
||||
);
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
"Voltage at phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0AFDC9FC02"))
|
||||
);
|
||||
|
@ -105,7 +105,7 @@ namespace
|
|||
"Voltage at phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0AFDC9FC03"))
|
||||
);
|
||||
|
@ -124,7 +124,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter on tariff 1.",
|
||||
DEFAULT_PRINT_PROPERTIES, // ,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -136,7 +136,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter on tariff 2.",
|
||||
DEFAULT_PRINT_PROPERTIES, // ,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -148,7 +148,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter on tariff 3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -160,7 +160,7 @@ namespace
|
|||
"The total energy production recorded by this meter on tariff 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("8E10833C"))
|
||||
);
|
||||
|
@ -170,7 +170,7 @@ namespace
|
|||
"The total energy production recorded by this meter on tariff 2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("8E20833C"))
|
||||
);
|
||||
|
@ -180,7 +180,7 @@ namespace
|
|||
"The total energy production recorded by this meter on tariff 3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("8E30833C"))
|
||||
);
|
||||
|
@ -190,7 +190,7 @@ namespace
|
|||
"The maximum demand indicator (maximum 15-min average power consumption recorded this month).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"",
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -106,7 +106,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -118,7 +118,7 @@ namespace
|
|||
"The heat cost allocation at set date #.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -80,7 +80,7 @@ namespace
|
|||
"Water consumption at the # billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -100,7 +100,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"",
|
||||
{
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace
|
|||
"The total heat energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -83,7 +83,7 @@ namespace
|
|||
"The total heating media volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -101,7 +101,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::DecimalsToString,
|
||||
Translate::MapType::DecimalsToString,
|
||||
AlwaysTrigger, MaskBits(9999),
|
||||
"OK",
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ namespace
|
|||
"The total heat energy consumption recorded at end of previous month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(32+i))
|
||||
|
@ -169,7 +169,7 @@ namespace
|
|||
tostrprintf("Previous month %d last date.", i+1),
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(32+i))
|
||||
|
@ -184,7 +184,7 @@ namespace
|
|||
"The total heat energy consumption at the due date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(8))
|
||||
|
@ -206,7 +206,7 @@ namespace
|
|||
"The current heat media volume flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -217,7 +217,7 @@ namespace
|
|||
"The current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::PowerW)
|
||||
|
@ -228,7 +228,7 @@ namespace
|
|||
"The total heat energy consumption recorded at end of last month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(32))
|
||||
|
@ -249,7 +249,7 @@ namespace
|
|||
"Maximum power consumption last month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(StorageNr(32))
|
||||
|
@ -262,7 +262,7 @@ namespace
|
|||
"The current forward heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -273,7 +273,7 @@ namespace
|
|||
"The current return heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -284,17 +284,17 @@ namespace
|
|||
// Test: Heat c5isf 55445555 NOKEY
|
||||
|
||||
// telegram=|E544496A55554455880D7A320200002F2F_04060000000004130000000002FD17240084800106000000008280016C2124C480010600000080C280016CFFFF84810106000000808281016CFFFFC481010600000080C281016CFFFF84820106000000808282016CFFFFC482010600000080C282016CFFFF84830106000000808283016CFFFFC483010600000080C283016CFFFF84840106000000808284016CFFFFC484010600000080C284016CFFFF84850106000000808285016CFFFFC485010600000080C285016CFFFF84860106000000808286016CFFFFC486010600000080C286016CFFFF|
|
||||
// {"media":"heat/cooling load","meter":"c5isf","name":"Heat","id":"55445555","total_energy_consumption_kwh":0,"total_volume_m3":0,"status":"ERROR REVERSE_FLOW SUPPLY_SENSOR_INTERRUPTED","prev_1_month":"2017-04-01","prev_2_month":"2127-15-31","prev_3_month":"2127-15-31","prev_4_month":"2127-15-31","prev_5_month":"2127-15-31","prev_6_month":"2127-15-31","prev_7_month":"2127-15-31","prev_8_month":"2127-15-31","prev_9_month":"2127-15-31","prev_10_month":"2127-15-31","prev_11_month":"2127-15-31","prev_12_month":"2127-15-31","prev_13_month":"2127-15-31","prev_14_month":"2127-15-31","prev_1_month_kwh":0,"prev_2_month_kwh":2147483648,"prev_3_month_kwh":2147483648,"prev_4_month_kwh":2147483648,"prev_5_month_kwh":2147483648,"prev_6_month_kwh":2147483648,"prev_7_month_kwh":2147483648,"prev_8_month_kwh":2147483648,"prev_9_month_kwh":2147483648,"prev_10_month_kwh":2147483648,"prev_11_month_kwh":2147483648,"prev_12_month_kwh":2147483648,"prev_13_month_kwh":2147483648,"prev_14_month_kwh":2147483648,"total_energy_consumption_last_month_kwh":0,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"heat/cooling load","meter":"c5isf","name":"Heat","id":"55445555","total_energy_consumption_kwh":0,"total_volume_m3":0,"status":"ERROR REVERSE_FLOW SUPPLY_SENSOR_INTERRUPTED","prev_1_month":"2017-04-01","prev_2_month":"2127-15-31","prev_3_month":"2127-15-31","prev_4_month":"2127-15-31","prev_5_month":"2127-15-31","prev_6_month":"2127-15-31","prev_7_month":"2127-15-31","prev_8_month":"2127-15-31","prev_9_month":"2127-15-31","prev_10_month":"2127-15-31","prev_11_month":"2127-15-31","prev_12_month":"2127-15-31","prev_13_month":"2127-15-31","prev_14_month":"2127-15-31","prev_1_month_kwh":0,"prev_2_month_kwh":-2147483648,"prev_3_month_kwh":-2147483648,"prev_4_month_kwh":-2147483648,"prev_5_month_kwh":-2147483648,"prev_6_month_kwh":-2147483648,"prev_7_month_kwh":-2147483648,"prev_8_month_kwh":-2147483648,"prev_9_month_kwh":-2147483648,"prev_10_month_kwh":-2147483648,"prev_11_month_kwh":-2147483648,"prev_12_month_kwh":-2147483648,"prev_13_month_kwh":-2147483648,"prev_14_month_kwh":-2147483648,"total_energy_consumption_last_month_kwh":0,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Heat;55445555;0;0;ERROR REVERSE_FLOW SUPPLY_SENSOR_INTERRUPTED;1111-11-11 11:11.11
|
||||
|
||||
// Type T1A2 telegram:
|
||||
// telegram=|DA44496A5555445588077A320200002F2F_04140000000084800114000000008280016C2124C480011400000080C280016CFFFF84810114000000808281016CFFFFC481011400000080C281016CFFFF84820114000000808282016CFFFFC482011400000080C282016CFFFF84830114000000808283016CFFFFC483011400000080C283016CFFFF84840114000000808284016CFFFFC484011400000080C284016CFFFF84850114000000808285016CFFFFC485011400000080C285016CFFFF84860114000000808286016CFFFFC486011400000080C286016CFFFF|
|
||||
// {"id": "55445555","media": "water","meter": "c5isf","name": "Heat","prev_10_month": "2127-15-31","prev_10_month_kwh": 2147483648,"prev_10_month_m3": 21474836.48,"prev_11_month": "2127-15-31","prev_11_month_kwh": 2147483648,"prev_11_month_m3": 21474836.48,"prev_12_month": "2127-15-31","prev_12_month_kwh": 2147483648,"prev_12_month_m3": 21474836.48,"prev_13_month": "2127-15-31","prev_13_month_kwh": 2147483648,"prev_13_month_m3": 21474836.48,"prev_14_month": "2127-15-31","prev_14_month_kwh": 2147483648,"prev_14_month_m3": 21474836.48,"prev_1_month": "2017-04-01","prev_1_month_kwh": 0,"prev_1_month_m3": 0,"prev_2_month": "2127-15-31","prev_2_month_kwh": 2147483648,"prev_2_month_m3": 21474836.48,"prev_3_month": "2127-15-31","prev_3_month_kwh": 2147483648,"prev_3_month_m3": 21474836.48,"prev_4_month": "2127-15-31","prev_4_month_kwh": 2147483648,"prev_4_month_m3": 21474836.48,"prev_5_month": "2127-15-31","prev_5_month_kwh": 2147483648,"prev_5_month_m3": 21474836.48,"prev_6_month": "2127-15-31","prev_6_month_kwh": 2147483648,"prev_6_month_m3": 21474836.48,"prev_7_month": "2127-15-31","prev_7_month_kwh": 2147483648,"prev_7_month_m3": 21474836.48,"prev_8_month": "2127-15-31","prev_8_month_kwh": 2147483648,"prev_8_month_m3": 21474836.48,"prev_9_month": "2127-15-31","prev_9_month_kwh": 2147483648,"prev_9_month_m3": 21474836.48,"status": "ERROR","timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 0,"total_energy_consumption_last_month_kwh": 0,"total_volume_m3": 0}
|
||||
// {"id": "55445555","media": "water","meter": "c5isf","name": "Heat","prev_10_month": "2127-15-31","prev_10_month_kwh":-2147483648,"prev_10_month_m3":-21474836.48,"prev_11_month": "2127-15-31","prev_11_month_kwh":-2147483648,"prev_11_month_m3":-21474836.48,"prev_12_month": "2127-15-31","prev_12_month_kwh":-2147483648,"prev_12_month_m3":-21474836.48,"prev_13_month": "2127-15-31","prev_13_month_kwh":-2147483648,"prev_13_month_m3":-21474836.48,"prev_14_month": "2127-15-31","prev_14_month_kwh":-2147483648,"prev_14_month_m3":-21474836.48,"prev_1_month": "2017-04-01","prev_1_month_kwh": 0,"prev_1_month_m3": 0,"prev_2_month": "2127-15-31","prev_2_month_kwh":-2147483648,"prev_2_month_m3":-21474836.48,"prev_3_month": "2127-15-31","prev_3_month_kwh":-2147483648,"prev_3_month_m3":-21474836.48,"prev_4_month": "2127-15-31","prev_4_month_kwh":-2147483648,"prev_4_month_m3":-21474836.48,"prev_5_month": "2127-15-31","prev_5_month_kwh":-2147483648,"prev_5_month_m3":-21474836.48,"prev_6_month": "2127-15-31","prev_6_month_kwh":-2147483648,"prev_6_month_m3":-21474836.48,"prev_7_month": "2127-15-31","prev_7_month_kwh":-2147483648,"prev_7_month_m3":-21474836.48,"prev_8_month": "2127-15-31","prev_8_month_kwh":-2147483648,"prev_8_month_m3":-21474836.48,"prev_9_month": "2127-15-31","prev_9_month_kwh":-2147483648,"prev_9_month_m3":-21474836.48,"status": "ERROR","timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 0,"total_energy_consumption_last_month_kwh": 0,"total_volume_m3": 0}
|
||||
// |Heat;55445555;0;0;ERROR;1111-11-11 11:11.11
|
||||
|
||||
// Type T1B telegram:
|
||||
// telegram=|5E44496A5555445588047A0A0050052F2F_04061A0000000413C20800008404060000000082046CC121043BA4000000042D1900000002591216025DE21002FD17000084800106000000008280016CC121948001AE25000000002F2F2F2F2F2F|
|
||||
// {"due_date": "2022-01-01","due_energy_consumption_kwh": 0,"flow_temperature_c": 56.5,"id": "55445555","max_power_last_month_kw": 0,"media": "heat","meter": "c5isf","name": "Heat","power_kw": 2.5,"prev_10_month": "2127-15-31","prev_10_month_kwh": 2147483648,"prev_10_month_m3": 21474836.48,"prev_11_month": "2127-15-31","prev_11_month_kwh": 2147483648,"prev_11_month_m3": 21474836.48,"prev_12_month": "2127-15-31","prev_12_month_kwh": 2147483648,"prev_12_month_m3": 21474836.48,"prev_13_month": "2127-15-31","prev_13_month_kwh": 2147483648,"prev_13_month_m3": 21474836.48,"prev_14_month": "2127-15-31","prev_14_month_kwh": 2147483648,"prev_14_month_m3": 21474836.48,"prev_1_month": "2022-01-01","prev_1_month_kwh": 0,"prev_1_month_m3": 0,"prev_2_month": "2127-15-31","prev_2_month_kwh": 2147483648,"prev_2_month_m3": 21474836.48,"prev_3_month": "2127-15-31","prev_3_month_kwh": 2147483648,"prev_3_month_m3": 21474836.48,"prev_4_month": "2127-15-31","prev_4_month_kwh": 2147483648,"prev_4_month_m3": 21474836.48,"prev_5_month": "2127-15-31","prev_5_month_kwh": 2147483648,"prev_5_month_m3": 21474836.48,"prev_6_month": "2127-15-31","prev_6_month_kwh": 2147483648,"prev_6_month_m3": 21474836.48,"prev_7_month": "2127-15-31","prev_7_month_kwh": 2147483648,"prev_7_month_m3": 21474836.48,"prev_8_month": "2127-15-31","prev_8_month_kwh": 2147483648,"prev_8_month_m3": 21474836.48,"prev_9_month": "2127-15-31","prev_9_month_kwh": 2147483648,"prev_9_month_m3": 21474836.48,"return_temperature_c": 43.22,"status": "OK","timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 26,"total_energy_consumption_last_month_kwh": 0,"total_volume_m3": 2.242,"volume_flow_m3h": 0.164}
|
||||
// {"due_date": "2022-01-01","due_energy_consumption_kwh": 0,"flow_temperature_c": 56.5,"id": "55445555","max_power_last_month_kw": 0,"media": "heat","meter": "c5isf","name": "Heat","power_kw": 2.5,"prev_10_month": "2127-15-31","prev_10_month_kwh":-2147483648,"prev_10_month_m3":-21474836.48,"prev_11_month": "2127-15-31","prev_11_month_kwh":-2147483648,"prev_11_month_m3":-21474836.48,"prev_12_month": "2127-15-31","prev_12_month_kwh":-2147483648,"prev_12_month_m3":-21474836.48,"prev_13_month": "2127-15-31","prev_13_month_kwh":-2147483648,"prev_13_month_m3":-21474836.48,"prev_14_month": "2127-15-31","prev_14_month_kwh":-2147483648,"prev_14_month_m3":-21474836.48,"prev_1_month": "2022-01-01","prev_1_month_kwh": 0,"prev_1_month_m3": 0,"prev_2_month": "2127-15-31","prev_2_month_kwh":-2147483648,"prev_2_month_m3":-21474836.48,"prev_3_month": "2127-15-31","prev_3_month_kwh":-2147483648,"prev_3_month_m3":-21474836.48,"prev_4_month": "2127-15-31","prev_4_month_kwh":-2147483648,"prev_4_month_m3":-21474836.48,"prev_5_month": "2127-15-31","prev_5_month_kwh":-2147483648,"prev_5_month_m3":-21474836.48,"prev_6_month": "2127-15-31","prev_6_month_kwh":-2147483648,"prev_6_month_m3":-21474836.48,"prev_7_month": "2127-15-31","prev_7_month_kwh":-2147483648,"prev_7_month_m3":-21474836.48,"prev_8_month": "2127-15-31","prev_8_month_kwh":-2147483648,"prev_8_month_m3":-21474836.48,"prev_9_month": "2127-15-31","prev_9_month_kwh":-2147483648,"prev_9_month_m3":-21474836.48,"return_temperature_c": 43.22,"status": "OK","timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 26,"total_energy_consumption_last_month_kwh": 0,"total_volume_m3": 2.242,"volume_flow_m3h": 0.164}
|
||||
// |Heat;55445555;26;2.242;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: Heat c5isf 32002044 NOKEY
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
|||
"The current temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -62,7 +62,7 @@ namespace
|
|||
"The average temperature over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -77,7 +77,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DigitalInput),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("BATTERY", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("BATTERY", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xffff)))
|
||||
);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -30,16 +30,22 @@ void check_detection_triplets(DriverInfo *di, string file);
|
|||
string check_field_name(const char *name, DriverDynamic *dd);
|
||||
Quantity check_field_quantity(const char *quantity_s, DriverDynamic *dd);
|
||||
VifScaling check_vif_scaling(const char *vif_scaling_s, DriverDynamic *dd);
|
||||
DifSignedness check_dif_signedness(const char *dif_signedness_s, DriverDynamic *dd);
|
||||
PrintProperties check_print_properties(const char *print_properties_s, DriverDynamic *dd);
|
||||
string get_translation(XMQDoc *doc, XMQNode *node, string name, string lang);
|
||||
string check_calculate(const char *formula, DriverDynamic *dd);
|
||||
Unit check_display_unit(const char *display_unit, DriverDynamic *dd);
|
||||
|
||||
bool checked_set_difvifkey(const char *difvifkey_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
void checked_set_measurement_type(const char *measurement_type_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
void checked_set_vif_range(const char *vif_range_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
void checked_set_storagenr_range(const char *storagenr_range_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
void checked_set_tariffnr_range(const char *tariffnr_range_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
void checked_set_subunitnr_range(const char *subunitnr_range_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
Translate::MapType checked_map_type(const char *map_type_s, DriverDynamic *dd);
|
||||
uint64_t checked_mask_bits(const char *mask_bits_s, DriverDynamic *dd);
|
||||
uint64_t checked_value(const char *value_s, DriverDynamic *dd);
|
||||
TestBit checked_test_type(const char *test_s, DriverDynamic *dd);
|
||||
void checked_add_vif_combinable(const char *vif_range_s, FieldMatcher *fm, DriverDynamic *dd);
|
||||
|
||||
const char *line = "-------------------------------------------------------------------------------";
|
||||
|
@ -59,12 +65,12 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co
|
|||
|
||||
if (!content)
|
||||
{
|
||||
ok = xmqParseFile(doc, file.c_str(), NULL);
|
||||
ok = xmqParseFile(doc, file.c_str(), NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
file = "builtin";
|
||||
ok = xmqParseBuffer(doc, content, content+strlen(content), NULL);
|
||||
ok = xmqParseBuffer(doc, content, content+strlen(content), NULL, 0);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
|
@ -78,13 +84,13 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co
|
|||
|
||||
try
|
||||
{
|
||||
string name = check_driver_name(xmqGetString(doc, NULL, "/driver/name"), file);
|
||||
string name = check_driver_name(xmqGetString(doc, "/driver/name"), file);
|
||||
di->setName(name);
|
||||
|
||||
MeterType meter_type = check_meter_type(xmqGetString(doc, NULL, "/driver/meter_type"), file);
|
||||
MeterType meter_type = check_meter_type(xmqGetString(doc, "/driver/meter_type"), file);
|
||||
di->setMeterType(meter_type);
|
||||
|
||||
string default_fields = check_default_fields(xmqGetString(doc, NULL, "/driver/default_fields"), file);
|
||||
string default_fields = check_default_fields(xmqGetString(doc, "/driver/default_fields"), file);
|
||||
di->setDefaultFields(default_fields);
|
||||
|
||||
if (!content)
|
||||
|
@ -94,7 +100,7 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co
|
|||
|
||||
di->setDynamic(file, doc);
|
||||
|
||||
xmqForeach(doc, NULL, "/driver/detect/mvt", (XMQNodeCallback)add_detect, di);
|
||||
xmqForeach(doc, "/driver/detect/mvt", (XMQNodeCallback)add_detect, di);
|
||||
|
||||
check_detection_triplets(di, file);
|
||||
|
||||
|
@ -104,6 +110,8 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co
|
|||
}
|
||||
catch (...)
|
||||
{
|
||||
xmqFreeDoc(doc);
|
||||
di->setDynamic(file, NULL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -111,20 +119,22 @@ bool DriverDynamic::load(DriverInfo *di, const string &file_name, const char *co
|
|||
DriverDynamic::DriverDynamic(MeterInfo &mi, DriverInfo &di) :
|
||||
MeterCommonImplementation(mi, di), file_name_(di.getDynamicFileName())
|
||||
{
|
||||
XMQDoc *doc = NULL;
|
||||
try
|
||||
{
|
||||
XMQDoc *doc = di.getDynamicDriver();
|
||||
doc = di.getDynamicDriver();
|
||||
assert(doc);
|
||||
|
||||
verbose("(driver) constructing driver %s from already loaded file %s\n",
|
||||
di.name().str().c_str(),
|
||||
fileName().c_str());
|
||||
|
||||
xmqForeach(doc, NULL, "/driver/use", (XMQNodeCallback)add_use, this);
|
||||
xmqForeach(doc, NULL, "/driver/field", (XMQNodeCallback)add_field, this);
|
||||
xmqForeach(doc, "/driver/use", (XMQNodeCallback)add_use, this);
|
||||
xmqForeach(doc, "/driver/field", (XMQNodeCallback)add_field, this);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
xmqFreeDoc(doc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +144,7 @@ DriverDynamic::~DriverDynamic()
|
|||
|
||||
XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *di)
|
||||
{
|
||||
string mvt = xmqGetString(doc, detect, ".");
|
||||
string mvt = xmqGetStringRel(doc, ".", detect);
|
||||
|
||||
auto fields = splitString(mvt, ',');
|
||||
if (fields.size() != 3)
|
||||
|
@ -147,7 +157,7 @@ XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *d
|
|||
mvt.c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
||||
string mfct = fields[0];
|
||||
|
@ -172,7 +182,7 @@ XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *d
|
|||
mfct.c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
mfct_code = toMfctCode(a, b, c);
|
||||
}
|
||||
|
@ -190,7 +200,7 @@ XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *d
|
|||
mfct.c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,7 +214,7 @@ XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *d
|
|||
version,
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
||||
if (type > 255 || type < 0)
|
||||
|
@ -217,7 +227,7 @@ XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *d
|
|||
type,
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
||||
string mfct_flag = manufacturerFlag(mfct_code);
|
||||
|
@ -233,7 +243,7 @@ XMQProceed DriverDynamic::add_detect(XMQDoc *doc, XMQNode *detect, DriverInfo *d
|
|||
|
||||
XMQProceed DriverDynamic::add_use(XMQDoc *doc, XMQNode *field, DriverDynamic *dd)
|
||||
{
|
||||
string name = xmqGetString(doc, field, ".");
|
||||
string name = xmqGetStringRel(doc, ".", field);
|
||||
bool ok = dd->addOptionalLibraryFields(name);
|
||||
if (!ok)
|
||||
{
|
||||
|
@ -248,37 +258,55 @@ XMQProceed DriverDynamic::add_use(XMQDoc *doc, XMQNode *field, DriverDynamic *dd
|
|||
XMQProceed DriverDynamic::add_field(XMQDoc *doc, XMQNode *field, DriverDynamic *dd)
|
||||
{
|
||||
// The field name must be supplied without a unit ie total (not total_m3) since units are managed by wmbusmeters.
|
||||
string name = check_field_name(xmqGetString(doc, field, "name"), dd);
|
||||
string name = check_field_name(xmqGetStringRel(doc, "name", field), dd);
|
||||
|
||||
// The quantity ie Volume, gives the default unit (m3) for the field. The unit can be overriden with display_unit.
|
||||
Quantity quantity = check_field_quantity(xmqGetString(doc, field, "quantity"), dd);
|
||||
Quantity quantity = check_field_quantity(xmqGetStringRel(doc, "quantity", field), dd);
|
||||
|
||||
// Text fields are either version strings or lookups from status bits.
|
||||
// All other fields are numeric, ie they have a unit. This also includes date and datetime.
|
||||
bool is_numeric = quantity != Quantity::Text;
|
||||
|
||||
// The vif scaling is by default Auto but can be overriden for pesky fields.
|
||||
VifScaling vif_scaling = check_vif_scaling(xmqGetString(doc, field, "vif_scaling"), dd);
|
||||
VifScaling vif_scaling = check_vif_scaling(xmqGetStringRel(doc, "vif_scaling", field), dd);
|
||||
|
||||
// The dif signedness is by default Signed but can be overriden for pesky fields.
|
||||
DifSignedness dif_signedness = check_dif_signedness(xmqGetStringRel(doc, "dif_signedness", field), dd);
|
||||
|
||||
// The properties are by default empty but can be specified for specific fields.
|
||||
PrintProperties properties = check_print_properties(xmqGetString(doc, field, "attributes"), dd);
|
||||
PrintProperties properties = check_print_properties(xmqGetStringRel(doc, "attributes", field), dd);
|
||||
|
||||
// The about fields explains what the value is for. Ie. is storage 1 the previous day or month value etc.
|
||||
string info = get_translation(doc, field, "about", language());
|
||||
|
||||
// The calculate formula is optional.
|
||||
string calculate = check_calculate(xmqGetString(doc, field, "calculate"), dd);
|
||||
string calculate = check_calculate(xmqGetStringRel(doc, "calculate", field), dd);
|
||||
|
||||
// The display unit is usually based on the quantity. But you can override it.
|
||||
Unit display_unit = check_display_unit(xmqGetString(doc, field, "display_unit"), dd);
|
||||
Unit display_unit = check_display_unit(xmqGetStringRel(doc, "display_unit", field), dd);
|
||||
|
||||
// Now find all matchers.
|
||||
FieldMatcher match = FieldMatcher::build();
|
||||
dd->tmp_matcher_ = &match;
|
||||
int num_matches = xmqForeach(doc, field, "match", (XMQNodeCallback)add_match, dd);
|
||||
int num_matches = xmqForeachRel(doc, "match", (XMQNodeCallback)add_match, dd, field);
|
||||
// Check if there were any matches at all, if not, then disable the matcher.
|
||||
match.active = num_matches > 0;
|
||||
|
||||
// Now find all matchers.
|
||||
Translate::Lookup lookup = Translate::Lookup();
|
||||
/*
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.set(MaskBits(0x000f))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x01 ,"DRY", TestBit::Set))
|
||||
.add(Translate::Map(0x02 ,"REVERSE", TestBit::Set))
|
||||
.add(Translate::Map(0x04 ,"LEAK", TestBit::Set))
|
||||
.add(Translate::Map(0x08 ,"BURST", TestBit::Set))
|
||||
));
|
||||
*/
|
||||
dd->tmp_lookup_ = &lookup;
|
||||
int num_lookups = xmqForeachRel(doc, "lookup", (XMQNodeCallback)add_lookup, dd, field);
|
||||
|
||||
if (is_numeric)
|
||||
{
|
||||
if (calculate == "")
|
||||
|
@ -289,6 +317,7 @@ XMQProceed DriverDynamic::add_field(XMQDoc *doc, XMQNode *field, DriverDynamic *
|
|||
properties,
|
||||
quantity,
|
||||
vif_scaling,
|
||||
dif_signedness,
|
||||
match,
|
||||
display_unit
|
||||
);
|
||||
|
@ -322,12 +351,25 @@ XMQProceed DriverDynamic::add_field(XMQDoc *doc, XMQNode *field, DriverDynamic *
|
|||
}
|
||||
else
|
||||
{
|
||||
dd->addStringFieldWithExtractor(
|
||||
name,
|
||||
info,
|
||||
properties,
|
||||
match
|
||||
);
|
||||
if (num_lookups > 0)
|
||||
{
|
||||
dd->addStringFieldWithExtractorAndLookup(
|
||||
name,
|
||||
info,
|
||||
properties,
|
||||
match,
|
||||
lookup
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
dd->addStringFieldWithExtractor(
|
||||
name,
|
||||
info,
|
||||
properties,
|
||||
match
|
||||
);
|
||||
}
|
||||
}
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
@ -336,13 +378,17 @@ XMQProceed DriverDynamic::add_match(XMQDoc *doc, XMQNode *match, DriverDynamic *
|
|||
{
|
||||
FieldMatcher *fm = dd->tmp_matcher_;
|
||||
|
||||
checked_set_measurement_type(xmqGetString(doc, match, "measurement_type"), fm, dd);
|
||||
if (checked_set_difvifkey(xmqGetStringRel(doc, "difvifkey", match), fm, dd)) return XMQ_CONTINUE;
|
||||
|
||||
checked_set_vif_range(xmqGetString(doc, match, "vif_range"), fm, dd);
|
||||
checked_set_measurement_type(xmqGetStringRel(doc, "measurement_type", match), fm, dd);
|
||||
|
||||
checked_set_storagenr_range(xmqGetString(doc, match, "storage_nr"), fm, dd);
|
||||
checked_set_vif_range(xmqGetStringRel(doc, "vif_range", match), fm, dd);
|
||||
|
||||
xmqForeach(doc, match, "add_combinable", (XMQNodeCallback)add_combinable, dd);
|
||||
checked_set_storagenr_range(xmqGetStringRel(doc, "storage_nr", match), fm, dd);
|
||||
checked_set_tariffnr_range(xmqGetStringRel(doc, "tariff_nr", match), fm, dd);
|
||||
checked_set_subunitnr_range(xmqGetStringRel(doc, "subunit_nr", match), fm, dd);
|
||||
|
||||
xmqForeachRel(doc, "add_combinable", (XMQNodeCallback)add_combinable, dd, match);
|
||||
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
@ -351,7 +397,62 @@ XMQProceed DriverDynamic::add_combinable(XMQDoc *doc, XMQNode *match, DriverDyna
|
|||
{
|
||||
FieldMatcher *fm = dd->tmp_matcher_;
|
||||
|
||||
checked_add_vif_combinable(xmqGetString(doc, match, "."), fm, dd);
|
||||
checked_add_vif_combinable(xmqGetStringRel(doc, ".", match), fm, dd);
|
||||
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
add_map:
|
||||
Add a mapping from a value (bits,index,decimal) to a string name.
|
||||
|
||||
map {
|
||||
name = SURGE
|
||||
info = 'Unexpected increase in pressure in relation to average pressure.'
|
||||
value = 0x02
|
||||
test = set
|
||||
}
|
||||
*/
|
||||
XMQProceed DriverDynamic::add_map(XMQDoc *doc, XMQNode *map, DriverDynamic *dd)
|
||||
{
|
||||
const char *name = xmqGetStringRel(doc, "name", map);
|
||||
uint64_t value = checked_value(xmqGetStringRel(doc, "value", map), dd);
|
||||
TestBit test_type = checked_test_type(xmqGetStringRel(doc, "test", map), dd);
|
||||
|
||||
dd->tmp_rule_->add(Translate::Map(value, name, test_type));
|
||||
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
add_lookup:
|
||||
Add a lookup from bits,index or decimal to a sequence of string tokens.
|
||||
Or fallback to the name (ERROR_FLAGS_8) suffixed by the untranslateable bits.
|
||||
|
||||
lookup {
|
||||
name = ERROR_FLAGS
|
||||
map_type = BitToString
|
||||
mask_bits = 0xffff
|
||||
default_message = OK
|
||||
map { } map {}
|
||||
}
|
||||
*/
|
||||
XMQProceed DriverDynamic::add_lookup(XMQDoc *doc, XMQNode *lookup, DriverDynamic *dd)
|
||||
{
|
||||
const char *name = xmqGetStringRel(doc, "name", lookup);
|
||||
Translate::MapType map_type = checked_map_type(xmqGetStringRel(doc, "map_type", lookup), dd);
|
||||
uint64_t mask_bits = checked_mask_bits(xmqGetStringRel(doc, "mask_bits", lookup), dd);
|
||||
const char *default_message = xmqGetStringRel(doc, "default_message", lookup);
|
||||
|
||||
Translate::Rule rule = Translate::Rule(name, map_type);
|
||||
dd->tmp_rule_ = &rule;
|
||||
|
||||
rule.set(MaskBits(mask_bits));
|
||||
rule.set(DefaultMessage(default_message));
|
||||
|
||||
xmqForeachRel(doc, "map", (XMQNodeCallback)add_map, dd, lookup);
|
||||
|
||||
dd->tmp_lookup_->add(rule);
|
||||
|
||||
return XMQ_CONTINUE;
|
||||
}
|
||||
|
@ -541,12 +642,12 @@ VifScaling check_vif_scaling(const char *vif_scaling_s, DriverDynamic *dd)
|
|||
warning("(driver) error in %s, bad vif scaling: %s\n",
|
||||
"%s\n"
|
||||
"Available vif scalings:\n"
|
||||
"%s\n"
|
||||
"Auto\n"
|
||||
"None\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
vif_scaling_s,
|
||||
line,
|
||||
"???",
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
@ -554,6 +655,33 @@ VifScaling check_vif_scaling(const char *vif_scaling_s, DriverDynamic *dd)
|
|||
return vif_scaling;
|
||||
}
|
||||
|
||||
DifSignedness check_dif_signedness(const char *dif_signedness_s, DriverDynamic *dd)
|
||||
{
|
||||
if (!dif_signedness_s)
|
||||
{
|
||||
return DifSignedness::Signed;
|
||||
}
|
||||
|
||||
DifSignedness dif_signedness = toDifSignedness(dif_signedness_s);
|
||||
|
||||
if (dif_signedness == DifSignedness::Unknown)
|
||||
{
|
||||
warning("(driver) error in %s, bad dif signedness: %s\n",
|
||||
"%s\n"
|
||||
"Available dif signedness:\n"
|
||||
"Signed\n"
|
||||
"Unsigned\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
dif_signedness_s,
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
return dif_signedness;
|
||||
}
|
||||
|
||||
PrintProperties check_print_properties(const char *print_properties_s, DriverDynamic *dd)
|
||||
{
|
||||
if (!print_properties_s)
|
||||
|
@ -576,11 +704,11 @@ PrintProperties check_print_properties(const char *print_properties_s, DriverDyn
|
|||
string get_translation(XMQDoc *doc, XMQNode *node, string name, string lang)
|
||||
{
|
||||
string xpath = name+"/"+lang;
|
||||
const char *txt = xmqGetString(doc, node, xpath.c_str());
|
||||
const char *txt = xmqGetStringRel(doc, xpath.c_str(), node);
|
||||
if (!txt)
|
||||
{
|
||||
xpath = name+"/en";
|
||||
txt = xmqGetString(doc, node, xpath.c_str());
|
||||
txt = xmqGetStringRel(doc, xpath.c_str(), node);
|
||||
if (!txt)
|
||||
{
|
||||
txt = "";
|
||||
|
@ -619,6 +747,31 @@ Unit check_display_unit(const char *display_unit_s, DriverDynamic *dd)
|
|||
return u;
|
||||
}
|
||||
|
||||
bool checked_set_difvifkey(const char *difvifkey_s, FieldMatcher *fm, DriverDynamic *dd)
|
||||
{
|
||||
if (!difvifkey_s) return false;
|
||||
|
||||
bool invalid_hex = false;
|
||||
bool hex = isHexStringStrict(difvifkey_s, &invalid_hex);
|
||||
|
||||
if (!hex || invalid_hex)
|
||||
{
|
||||
warning("(driver) error in %s, bad divfikey: %s\n"
|
||||
"%s\n"
|
||||
"Should be all hex.\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
difvifkey_s,
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
fm->set(DifVifKey(difvifkey_s));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void checked_set_measurement_type(const char *measurement_type_s, FieldMatcher *fm, DriverDynamic *dd)
|
||||
{
|
||||
if (!measurement_type_s)
|
||||
|
@ -730,6 +883,69 @@ void checked_set_storagenr_range(const char *storagenr_range_s, FieldMatcher *fm
|
|||
}
|
||||
}
|
||||
|
||||
void checked_set_tariffnr_range(const char *tariffnr_range_s, FieldMatcher *fm, DriverDynamic *dd)
|
||||
{
|
||||
if (!tariffnr_range_s) return;
|
||||
|
||||
auto fields = splitString(tariffnr_range_s, ',');
|
||||
bool ok = isNumber(fields[0]);
|
||||
if (fields.size() > 1)
|
||||
{
|
||||
ok &= isNumber(fields[1]);
|
||||
}
|
||||
if (!ok || fields.size() > 2)
|
||||
{
|
||||
warning("(driver) error in %s, bad tariffnr_range: %s\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
tariffnr_range_s,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
if (fields.size() == 1)
|
||||
{
|
||||
fm->set(TariffNr(atoi(fields[0].c_str())));
|
||||
}
|
||||
else
|
||||
{
|
||||
fm->set(TariffNr(atoi(fields[0].c_str())),
|
||||
TariffNr(atoi(fields[1].c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
void checked_set_subunitnr_range(const char *subunitnr_range_s, FieldMatcher *fm, DriverDynamic *dd)
|
||||
{
|
||||
if (!subunitnr_range_s) return;
|
||||
|
||||
auto fields = splitString(subunitnr_range_s, ',');
|
||||
bool ok = isNumber(fields[0]);
|
||||
if (fields.size() > 1)
|
||||
{
|
||||
ok &= isNumber(fields[1]);
|
||||
}
|
||||
if (!ok || fields.size() > 2)
|
||||
{
|
||||
warning("(driver) error in %s, bad subunitnr_range: %s\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
subunitnr_range_s,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
if (fields.size() == 1)
|
||||
{
|
||||
fm->set(SubUnitNr(atoi(fields[0].c_str())));
|
||||
}
|
||||
else
|
||||
{
|
||||
fm->set(SubUnitNr(atoi(fields[0].c_str())),
|
||||
SubUnitNr(atoi(fields[1].c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checked_add_vif_combinable(const char *vif_combinable_s, FieldMatcher *fm, DriverDynamic *dd)
|
||||
{
|
||||
if (!vif_combinable_s) return;
|
||||
|
@ -753,3 +969,118 @@ void checked_add_vif_combinable(const char *vif_combinable_s, FieldMatcher *fm,
|
|||
|
||||
fm->add(vif_combinable);
|
||||
}
|
||||
|
||||
Translate::MapType checked_map_type(const char *map_type_s, DriverDynamic *dd)
|
||||
{
|
||||
if (!map_type_s)
|
||||
{
|
||||
warning("(driver) error in %s, cannot find: driver/field/lookup/map_type\n"
|
||||
"%s\n"
|
||||
"Remember to add for example: lookup { map_type = BitToString ... }\n"
|
||||
"Available map types:\n"
|
||||
"BitToString\n"
|
||||
"IndexToString\n"
|
||||
"DecimalsToString\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
Translate::MapType map_type = toMapType(map_type_s);
|
||||
|
||||
if (map_type == Translate::MapType::Unknown)
|
||||
{
|
||||
warning("(driver) error in %s, bad map_type: %s\n"
|
||||
"%s\n"
|
||||
"Available map types:\n"
|
||||
"BitToString\n"
|
||||
"IndexToString\n"
|
||||
"DecimalToString\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
map_type_s,
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
return map_type;
|
||||
}
|
||||
|
||||
|
||||
uint64_t checked_mask_bits(const char *mask_bits_s, DriverDynamic *dd)
|
||||
{
|
||||
if (!mask_bits_s)
|
||||
{
|
||||
warning("(driver) error in %s, cannot find: driver/field/lookup/mask_bitse\n"
|
||||
"%s\n"
|
||||
"Remember to add for example: lookup { mask_bits = 0x00ff ... }\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
uint64_t mask = strtol(mask_bits_s, NULL, 16);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
uint64_t checked_value(const char *value_s, DriverDynamic *dd)
|
||||
{
|
||||
if (!value_s)
|
||||
{
|
||||
warning("(driver) error in %s, cannot find: driver/field/lookup/map/value\n"
|
||||
"%s\n"
|
||||
"Remember to add for example: lookup { map { ... value = 0x01 ... }}\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
uint64_t value = strtol(value_s, NULL, 16);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
TestBit checked_test_type(const char *test_s, DriverDynamic *dd)
|
||||
{
|
||||
if (!test_s)
|
||||
{
|
||||
warning("(driver) error in %s, cannot find: driver/field/lookup/map/test\n"
|
||||
"%s\n"
|
||||
"Remember to add for example: lookup { map { test = Set } }\n"
|
||||
"Available test types:\n"
|
||||
"Set\n"
|
||||
"NotSet\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
TestBit test_type = toTestBit(test_s);
|
||||
|
||||
if (test_type == TestBit::Unknown)
|
||||
{
|
||||
warning("(driver) error in %s, bad test: %s\n"
|
||||
"%s\n"
|
||||
"Available test types:\n"
|
||||
"Set\n"
|
||||
"NotSet\n"
|
||||
"%s\n",
|
||||
dd->fileName().c_str(),
|
||||
test_s,
|
||||
line,
|
||||
line);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
return test_type;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2023 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
Copyright (C) 2023-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -31,12 +31,17 @@ struct DriverDynamic : public virtual MeterCommonImplementation
|
|||
static XMQProceed add_match(XMQDoc *doc, XMQNode *match, DriverDynamic *dd);
|
||||
static XMQProceed add_combinable(XMQDoc *doc, XMQNode *match, DriverDynamic *dd);
|
||||
|
||||
static XMQProceed add_lookup(XMQDoc *doc, XMQNode *lookup, DriverDynamic *dd);
|
||||
static XMQProceed add_map(XMQDoc *doc, XMQNode *map, DriverDynamic *dd);
|
||||
|
||||
const string &fileName() { return file_name_; }
|
||||
|
||||
private:
|
||||
|
||||
string file_name_;
|
||||
FieldMatcher *tmp_matcher_;
|
||||
Translate::Lookup *tmp_lookup_;
|
||||
Translate::Rule *tmp_rule_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -52,7 +52,7 @@ namespace
|
|||
"Current power consumption at phase 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04A9FF01"))
|
||||
);
|
||||
|
@ -62,7 +62,7 @@ namespace
|
|||
"Current power consumption at phase 2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04A9FF02"))
|
||||
);
|
||||
|
@ -72,7 +72,7 @@ namespace
|
|||
"Current power consumption at phase 3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04A9FF03"))
|
||||
);
|
||||
|
@ -92,7 +92,7 @@ namespace
|
|||
"Calculated sum of power consumption of all phases.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -58,7 +58,7 @@ namespace
|
|||
"Current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"The total energy production recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace
|
|||
{
|
||||
setMfctTPLStatusBits(
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("TPL_STS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x04 ,"RTC_INVALID", TestBit::Set))));
|
||||
|
@ -54,7 +54,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ namespace
|
|||
"Number of times the smoke alarm has triggered.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(SubUnitNr(1))
|
||||
|
@ -121,7 +121,7 @@ namespace
|
|||
"Time the smoke alarm has been removed.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(SubUnitNr(1))
|
||||
|
@ -145,7 +145,7 @@ namespace
|
|||
"Number of times the smoke alarm has been removed.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(SubUnitNr(1))
|
||||
|
@ -169,7 +169,7 @@ namespace
|
|||
"Number of times the test button has been pressed.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(SubUnitNr(1))
|
||||
|
@ -208,7 +208,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"DUST",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x1f),
|
||||
"",
|
||||
{
|
||||
|
@ -228,7 +228,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"BATTERY_VOLTAGE",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x0f00),
|
||||
"",
|
||||
{
|
||||
|
@ -267,7 +267,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"OBSTACLE_DISTANCE",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x700000),
|
||||
"",
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"HEAD_STATUS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff8ff0e0),
|
||||
"OK",
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -80,7 +80,7 @@ namespace
|
|||
"Current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::PowerW)
|
||||
|
@ -91,7 +91,7 @@ namespace
|
|||
"Total volume of heat media.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -102,7 +102,7 @@ namespace
|
|||
"The total energy consumption recorded at the target date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -114,7 +114,7 @@ namespace
|
|||
"The flow temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -125,7 +125,7 @@ namespace
|
|||
"The return temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -136,7 +136,7 @@ namespace
|
|||
"The external temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -147,7 +147,7 @@ namespace
|
|||
"How long the meter has been collecting data.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::OperatingTime)
|
||||
|
@ -167,7 +167,7 @@ namespace
|
|||
"Battery voltage.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"",
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -112,7 +112,7 @@ namespace
|
|||
"Power measured by this meter at the moment.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -123,7 +123,7 @@ namespace
|
|||
"The total energy backward (production) recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -135,7 +135,7 @@ namespace
|
|||
"The reactive total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Reactive_Energy,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FB8275"))
|
||||
);
|
||||
|
@ -145,7 +145,7 @@ namespace
|
|||
"The total reactive energy backward (production) recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Reactive_Energy,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(DifVifKey("04FB82F53C"))
|
||||
|
@ -177,7 +177,7 @@ namespace
|
|||
"Amperage at phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FDD9FC01"))
|
||||
);
|
||||
|
@ -187,7 +187,7 @@ namespace
|
|||
"Amperage at phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FDD9FC02"))
|
||||
);
|
||||
|
@ -197,7 +197,7 @@ namespace
|
|||
"Amperage at phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FDD9FC03"))
|
||||
);
|
||||
|
@ -207,7 +207,7 @@ namespace
|
|||
"Voltage at phase L1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FDC8FC01"))
|
||||
);
|
||||
|
@ -217,7 +217,7 @@ namespace
|
|||
"Voltage at phase L2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FDC8FC02"))
|
||||
);
|
||||
|
@ -227,7 +227,7 @@ namespace
|
|||
"Voltage at phase L3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FDC8FC03"))
|
||||
);
|
||||
|
@ -237,7 +237,7 @@ namespace
|
|||
"Frequency in 0.1 Hz",
|
||||
DEFAULT_PRINT_PROPERTIES | PrintProperty::HIDE,
|
||||
Quantity::Frequency,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FB2E"))
|
||||
);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -53,7 +53,7 @@ namespace
|
|||
"The target water consumption recorded at previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -56,7 +56,7 @@ namespace
|
|||
"The energy consumption recorded by this meter at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -68,7 +68,7 @@ namespace
|
|||
"The active power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -79,7 +79,7 @@ namespace
|
|||
"The flow of water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -90,7 +90,7 @@ namespace
|
|||
"The maximum forward flow of water since the last set date?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -101,7 +101,7 @@ namespace
|
|||
"The forward temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -112,7 +112,7 @@ namespace
|
|||
"The return temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -123,7 +123,7 @@ namespace
|
|||
"The temperature difference forward-return for the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::TemperatureDifference)
|
||||
|
@ -134,7 +134,7 @@ namespace
|
|||
"The total amount of water that has passed through this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -145,7 +145,7 @@ namespace
|
|||
"The amount of water that had passed through this meter at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -157,7 +157,7 @@ namespace
|
|||
"The amount of water that has passed through subunit 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -169,7 +169,7 @@ namespace
|
|||
"The amount of water that had passed through the subunit 1 at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -182,7 +182,7 @@ namespace
|
|||
"The current heat cost allocation for subunit 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -194,7 +194,7 @@ namespace
|
|||
"The heat cost allocation for subunit 1 at the target date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -207,7 +207,7 @@ namespace
|
|||
"The current heat cost allocation for subunit 2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -219,7 +219,7 @@ namespace
|
|||
"The heat cost allocation for subunit 2 at the target date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ namespace
|
|||
"The water consumption at the last billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
info,
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -64,7 +64,7 @@ namespace
|
|||
"Calculated sum of power consumption of all phases.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"The total energy production recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -87,7 +87,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter on tariff 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -99,7 +99,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter on tariff 2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -111,7 +111,7 @@ namespace
|
|||
"Current power consumption phase 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04A9FF01"))
|
||||
);
|
||||
|
@ -121,7 +121,7 @@ namespace
|
|||
"Current power consumption phase 2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04A9FF02"))
|
||||
);
|
||||
|
@ -131,7 +131,7 @@ namespace
|
|||
"Current power consumption phase 3.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04A9FF03"))
|
||||
);
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -98,7 +98,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -109,7 +109,7 @@ namespace
|
|||
"The heat cost allocation at set date #.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -121,7 +121,7 @@ namespace
|
|||
"Deprecated field.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -53,7 +53,7 @@ namespace
|
|||
"The target water consumption recorded at previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ namespace
|
|||
"The total water consumption at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
"The total water consumption at the second most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -111,7 +111,7 @@ namespace
|
|||
"Maximum water flow since date time.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -133,7 +133,7 @@ namespace
|
|||
"The total water consumption at the historic date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -145,7 +145,7 @@ namespace
|
|||
"Reference date for history.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
);
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(1))
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(1))
|
||||
|
@ -109,7 +109,7 @@ namespace
|
|||
"Heat cost allocation at the 8 billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(8))
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -82,7 +82,7 @@ namespace
|
|||
"The total water consumption recorded at the beginning of this month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -104,7 +104,7 @@ namespace
|
|||
"The current flow of water through the meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -115,7 +115,7 @@ namespace
|
|||
"The water temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -127,7 +127,7 @@ namespace
|
|||
"The maximum water temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -139,7 +139,7 @@ namespace
|
|||
"The external temperature outside of the meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -151,7 +151,7 @@ namespace
|
|||
"The maximum flow recorded during previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -163,7 +163,7 @@ namespace
|
|||
"The minimum flow recorded during previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -175,7 +175,7 @@ namespace
|
|||
"The maximum temperature recorded during previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -187,7 +187,7 @@ namespace
|
|||
"The minimum flow recorded during previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -199,7 +199,7 @@ namespace
|
|||
"The maximum flow recorded during previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -216,7 +216,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"DRY",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x0070),
|
||||
"",
|
||||
{
|
||||
|
@ -243,7 +243,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"REVERSED",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x0380),
|
||||
"",
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"LEAKING",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x1c00),
|
||||
"",
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"BURSTING",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0xe000),
|
||||
"",
|
||||
{
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger,
|
||||
AutoMask,
|
||||
"OK",
|
||||
|
@ -85,7 +85,7 @@ namespace
|
|||
},
|
||||
{
|
||||
"ERROR_FLAGS_SINGLE_PHASE",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
TriggerBits(0x01020000),
|
||||
AutoMask,
|
||||
"OK",
|
||||
|
@ -99,7 +99,7 @@ namespace
|
|||
},
|
||||
{
|
||||
"ERROR_FLAGS_THREE_PHASE",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
TriggerBits(0x01010000),
|
||||
AutoMask,
|
||||
"OK",
|
||||
|
@ -124,7 +124,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"INFO_FLAGS",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger,
|
||||
AutoMask,
|
||||
"",
|
||||
|
@ -141,7 +141,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -152,7 +152,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -164,7 +164,7 @@ namespace
|
|||
"Last day?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
|
@ -176,7 +176,7 @@ namespace
|
|||
"Last day energy consumption?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -188,7 +188,7 @@ namespace
|
|||
"Last day energy consumption for tariff?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -201,7 +201,7 @@ namespace
|
|||
"Device date time when telegram was sent.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
|
@ -212,7 +212,7 @@ namespace
|
|||
"Voltage for single phase meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -224,7 +224,7 @@ namespace
|
|||
"Voltage at phase L#.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -236,7 +236,7 @@ namespace
|
|||
"Amperage for single phase meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -248,7 +248,7 @@ namespace
|
|||
"Amperage at phase L#.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -260,7 +260,7 @@ namespace
|
|||
"Raw input to frequency.",
|
||||
DEFAULT_PRINT_PROPERTIES | PrintProperty::HIDE,
|
||||
Quantity::Frequency,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FB2D"))
|
||||
);
|
||||
|
|
|
@ -100,5 +100,5 @@ namespace
|
|||
|
||||
// Test: Wateroo gwfwater 20221031 NOKEY
|
||||
// telegram=|3144E61E31102220010E8C04F47ABE0420452F2F_037410000004133E0000004413FFFFFFFF426CFFFF0F0120012F2F2F2F2F|
|
||||
// {"actuality_duration_s": 16,"battery_y": 0,"id": "20221031","media": "bus/system component","meter": "gwfwater","name": "Wateroo","power_mode": "SAVING","status": "BATTERY_LOW POWER_LOW","target_date": "2128-03-31","target_m3": 4294967.295,"timestamp": "1111-11-11T11:11:11Z","total_m3": 0.062}
|
||||
// {"actuality_duration_s": 16,"battery_y": 0,"id": "20221031","media": "bus/system component","meter": "gwfwater","name": "Wateroo","power_mode": "SAVING","status": "BATTERY_LOW POWER_LOW","target_date": "2128-03-31","target_m3": -0.001,"timestamp": "1111-11-11T11:11:11Z","total_m3": 0.062}
|
||||
// |Wateroo;20221031;0.062;1111-11-11 11:11.11
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -80,7 +80,7 @@ namespace
|
|||
"The heat cost allocation at set date #.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -92,7 +92,7 @@ namespace
|
|||
"Deprecated field.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace
|
|||
{
|
||||
setMfctTPLStatusBits(
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("TPL_STS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x80 ,"SABOTAGE_ENCLOSURE", TestBit::Set))));
|
||||
|
@ -55,7 +55,7 @@ namespace
|
|||
"The total heating energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -67,7 +67,7 @@ namespace
|
|||
"The date time when the recording was made.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
|
@ -78,7 +78,7 @@ namespace
|
|||
"The total cooling energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -90,7 +90,7 @@ namespace
|
|||
"Total heating volume of media.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -102,7 +102,7 @@ namespace
|
|||
"Total cooling volume of media.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -114,7 +114,7 @@ namespace
|
|||
"Supply c1 volume.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -126,7 +126,7 @@ namespace
|
|||
"Return c2 volume.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -138,7 +138,7 @@ namespace
|
|||
"The supply t1 pipe temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -150,7 +150,7 @@ namespace
|
|||
"The return t2 pipe temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -55,7 +55,7 @@ namespace
|
|||
"Meter timestamp for measurement.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime),
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -68,7 +68,7 @@ namespace
|
|||
"The total water consumption recorded on tariff # by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -80,7 +80,7 @@ namespace
|
|||
"The total water consumption recorded on tariff # by this meter at billing date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -93,7 +93,7 @@ namespace
|
|||
"The current water flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow));
|
||||
|
@ -103,7 +103,7 @@ namespace
|
|||
"The total water consumption recorded at date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -115,7 +115,7 @@ namespace
|
|||
"The last billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
@ -128,7 +128,7 @@ namespace
|
|||
"The total water consumption recorded at the end of last month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -140,7 +140,7 @@ namespace
|
|||
"The end of last month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
|
@ -152,7 +152,7 @@ namespace
|
|||
"Remaining battery life in years.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RemainingBattery),
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -60,7 +60,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"The total water consumption recorded at the end of previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -102,7 +102,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"WOOTA",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffffff),
|
||||
"",
|
||||
{
|
||||
|
@ -122,7 +122,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"WOOTB",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"",
|
||||
{
|
||||
|
@ -156,4 +156,3 @@ namespace
|
|||
// telegram=|3A4497269820362300167AF60020A52F2F_04132E100000066D03260DE12B007413FEFEFEFE426C1F01047F1600060C027F9A2A0E79187103002300|
|
||||
// {"enhanced_id": "002300037118", "id": "23362098", "media": "cold water", "meter": "itron", "meter_datetime": "2023-11-01 13:38:03", "name": "ColdWaterMeter", "status": "OK", "target_date": "2000-01-31", "timestamp": "1111-11-11T11:11:11Z", "total_m3": 4.142,"unknown_a": "WOOTA_C060016","unknown_b": "WOOTB_2A9A" }
|
||||
// |ColdWaterMeter;23362098;4.142;null;1111-11-11 11:11.11
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2018-2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
Copyright (C) 2018-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
Copyright (C) 2020 Eric Bus (gpl-3.0-or-later)
|
||||
Copyright (C) 2022 thecem (gpl-3.0-or-later)
|
||||
|
||||
|
@ -74,7 +74,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -131,7 +131,7 @@ namespace
|
|||
"The volume of water (3/68/Volume V1).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -142,7 +142,7 @@ namespace
|
|||
"The actual amount of water that pass through this meter (8/74/Flow V1 actual).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -153,7 +153,7 @@ namespace
|
|||
"The current power flowing.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -164,7 +164,7 @@ namespace
|
|||
"The maximum power supplied.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -175,7 +175,7 @@ namespace
|
|||
"The forward temperature of the water (6/86/t2 actual 2 decimals).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -186,7 +186,7 @@ namespace
|
|||
"The return temperature of the water (7/87/t2 actual 2 decimals).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -197,7 +197,7 @@ namespace
|
|||
"The maximum flow of water that passed through this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -208,7 +208,7 @@ namespace
|
|||
"The forward energy of the water (4/97/Energy E8).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FF07")),
|
||||
Unit::M3C);
|
||||
|
@ -218,7 +218,7 @@ namespace
|
|||
"The return energy of the water (5/110/Energy E9).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04FF08")),
|
||||
Unit::M3C);
|
||||
|
@ -237,7 +237,7 @@ namespace
|
|||
"The energy consumption recorded by this meter at the set date (11/60/Heat energy E1/026C).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -249,7 +249,7 @@ namespace
|
|||
"The amount of water that had passed through this meter at the set date (13/68/Volume V1).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -271,7 +271,7 @@ namespace
|
|||
"How long the meter has been collecting data.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::OperatingTime)
|
||||
|
@ -314,11 +314,11 @@ namespace
|
|||
|
||||
// Test: My403Cooling multical403 78780102 NOKEY
|
||||
// telegram=|88442D2C02017878340A8D208D529C132037FC78_040E2D0A000004FF07F8FF000004FF08401801000413C1900500844014000000008480401400000000043BED0000000259BC06025DCD07142DE7FFFFFF84100E0000000084200E0000000004FF2200000000026C9228440E5F0300004413960D0200C4401400000000C480401400000000426C8128|
|
||||
// {"forward_energy_m3c": 65528,"id": "78780102","max_power_kw": 429496727.1,"media": "cooling load volume at outlet","meter": "kamheat","meter_date": "2020-08-18","name": "My403Cooling","return_energy_m3c": 71744,"status": "OK","t1_temperature_c": 17.24,"t2_temperature_c": 19.97,"target_date": "2020-08-01","target_energy_kwh": 239.722222,"target_volume_m3": 134.55,"timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 723.611111,"total_volume_m3": 364.737,"volume_flow_m3h": 0.237}
|
||||
// {"forward_energy_m3c": 65528,"id": "78780102","max_power_kw": -2.5,"media": "cooling load volume at outlet","meter": "kamheat","meter_date": "2020-08-18","name": "My403Cooling","return_energy_m3c": 71744,"status": "OK","t1_temperature_c": 17.24,"t2_temperature_c": 19.97,"target_date": "2020-08-01","target_energy_kwh": 239.722222,"target_volume_m3": 134.55,"timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 723.611111,"total_volume_m3": 364.737,"volume_flow_m3h": 0.237}
|
||||
// |My403Cooling;78780102;723.611111;364.737;OK;1111-11-11 11:11.11
|
||||
|
||||
// telegram=|5B442D2C02017878340A8D2096809C1320EF2B7934147ED7_2D0A0000FAFF000043180100CE9005000000000000000000EE000000BA06CB07E7FFFFFF00000000000000000000000092285F030000960D020000000000000000008128|
|
||||
// {"forward_energy_m3c": 65530,"id": "78780102","max_power_kw": 429496727.1,"media": "cooling load volume at outlet","meter": "kamheat","meter_date": "2020-08-18","name": "My403Cooling","return_energy_m3c": 71747,"status": "OK","t1_temperature_c": 17.22,"t2_temperature_c": 19.95,"target_date": "2020-08-01","target_energy_kwh": 239.722222,"target_volume_m3": 134.55,"timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 723.611111,"total_volume_m3": 364.75,"volume_flow_m3h": 0.238}
|
||||
// {"forward_energy_m3c": 65530,"id": "78780102","max_power_kw": -2.5,"media": "cooling load volume at outlet","meter": "kamheat","meter_date": "2020-08-18","name": "My403Cooling","return_energy_m3c": 71747,"status": "OK","t1_temperature_c": 17.22,"t2_temperature_c": 19.95,"target_date": "2020-08-01","target_energy_kwh": 239.722222,"target_volume_m3": 134.55,"timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 723.611111,"total_volume_m3": 364.75,"volume_flow_m3h": 0.238}
|
||||
// |My403Cooling;78780102;723.611111;364.75;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: Heato multical602 78152801 NOKEY
|
||||
|
@ -354,3 +354,8 @@ namespace
|
|||
// telegram=|68c9c96808e672323232322d2c35041900000004fB006083000004ff074006010004ff08299400000416984e010084401400000000848040140000000004225043000034221c0000000259c91f025d4f1102617a0e042e30020000142e65030000043c24050000143ce308000004ff2200000000046d2e2B0f3144fB00007d000044ff07Bdf9000044ff08308d00004416B73f0100c4401400000000c480401400000000542ed9020000543ce8090000426c013102ff1a011B0c783032858404ff16e5841e0004ff17c1d5B400a516|
|
||||
// {"fabrication_no": "84853230", "flow_return_temperature_difference_c": 37.06, "forward_energy_m3c": 67136, "id": "32323232", "max_flow_m3h": 22.75, "max_power_kw": 869, "media": "heat", "meter": "kamheat", "meter_datetime": "2024-01-15 11:46", "name": "Kamstrup_MC603_mbus", "on_time_at_error_h": 28, "on_time_h": 17232, "power_kw": 560, "return_energy_m3c": 37929, "status": "OK", "t1_temperature_c": 81.37, "t2_temperature_c": 44.31, "target_date": "2024-01-01", "target_energy_kwh": 3200000, "target_volume_m3": 81847, "timestamp": "1111-11-11T11:11:11Z", "total_energy_consumption_kwh": 3363200, "total_volume_m3": 85656, "volume_flow_m3h": 13.16}
|
||||
// |Kamstrup_MC603_mbus;32323232;3363200;85656;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: KMHEAT kamheat 85412440 NOKEY
|
||||
// telegram=|5e442d2c4024418535047ae10050252f2f04fB091300000004167500000004ff2200000000043ca301000002599c1d025dB00e844014000000008480401400000000042eB9000000026c0534426c013444fB0900000000543c000000002f2f|
|
||||
// {"id": "85412440","media": "heat","meter": "kamheat","meter_date": "2024-04-05","name": "KMHEAT","power_kw": 185,"status": "OK","t1_temperature_c": 75.8,"t2_temperature_c": 37.6,"target_date": "2024-04-01","target_energy_kwh": 0,"timestamp": "1111-11-11T11:11:11Z","total_energy_consumption_kwh": 5277.777778,"total_volume_m3": 117,"volume_flow_m3h": 4.19}
|
||||
// |KMHEAT;85412440;5277.777778;117;OK;1111-11-11 11:11.11
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include"meters_common_implementation.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Driver : public virtual MeterCommonImplementation
|
||||
{
|
||||
Driver(MeterInfo &mi, DriverInfo &di);
|
||||
};
|
||||
|
||||
static bool ok = registerDriver([](DriverInfo&di)
|
||||
{
|
||||
di.setName("kampress");
|
||||
di.setDefaultFields("name,id,status,pressure_bar,max_pressure_bar,min_pressure_bar,timestamp");
|
||||
di.setMeterType(MeterType::PressureSensor);
|
||||
di.addLinkMode(LinkMode::C1);
|
||||
di.addDetection(MANUFACTURER_KAM, 0x18, 0x01);
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
|
||||
{
|
||||
addStringFieldWithExtractorAndLookup(
|
||||
"status",
|
||||
"Status and error flags.",
|
||||
DEFAULT_PRINT_PROPERTIES | INCLUDE_TPL_STATUS,
|
||||
FieldMatcher::build()
|
||||
.set(VIFRange::ErrorFlags),
|
||||
{
|
||||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
{ 0x01, "DROP" }, // Unexpected drop in pressure in relation to average pressure.
|
||||
{ 0x02, "SURGE" }, // Unexpected increase in pressure in relation to average pressure.
|
||||
{ 0x04, "HIGH" }, // Average pressure has reached configurable limit. Default 15 bar
|
||||
{ 0x08, "LOW" }, // Average pressure has reached configurable limit. Default 1.5 bar
|
||||
{ 0x10, "TRANSIENT" }, // Pressure changes quickly over short timeperiods. Average is fluctuating.
|
||||
{ 0x20, "COMM_ERROR" } // Cannot measure properly or bad internal communication.
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"pressure",
|
||||
"The measured pressure.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Pressure,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Pressure)
|
||||
);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"max_pressure",
|
||||
"The maximum pressure measured during ?.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Pressure,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::Pressure)
|
||||
);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"min_pressure",
|
||||
"The minimum pressure measured during ?.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Pressure,
|
||||
VifScaling::Auto,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::Pressure)
|
||||
);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"alfa",
|
||||
"We do not know what this is.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("05FF09"))
|
||||
);
|
||||
|
||||
addNumericFieldWithExtractor(
|
||||
"beta",
|
||||
"We do not know what this is.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("05FF0A"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Test: Pressing kampress 77000317 NOKEY
|
||||
// telegram=|32442D2C1703007701188D280080E39322DB8F78_22696600126967000269660005FF091954A33A05FF0A99BD823A02FD170800|
|
||||
// {"media":"pressure","meter":"kampress","name":"Pressing","id":"77000317","status":"LOW","pressure_bar":1.02,"max_pressure_bar":1.03,"min_pressure_bar":1.02,"alfa_counter":0.001246,"beta_counter":0.000997,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Pressing;77000317;LOW;1.02;1.03;1.02;1111-11-11 11:11.11
|
||||
|
||||
// telegram=|27442D2C1703007701188D280194E393226EC679DE735657_660067006600962B913A21B9423A0800|
|
||||
// {"media":"pressure","meter":"kampress","name":"Pressing","id":"77000317","status":"LOW","pressure_bar":1.02,"max_pressure_bar":1.03,"min_pressure_bar":1.02,"alfa_counter":0.001108,"beta_counter":0.000743,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Pressing;77000317;LOW;1.02;1.03;1.02;1111-11-11 11:11.11
|
||||
|
||||
// telegram=|27442D2C1703007701188D289554F295224ED579DE73188A_650066006600E80EA43A6B97A3BA0800|
|
||||
// {"media":"pressure","meter":"kampress","name":"Pressing","id":"77000317","status":"LOW","pressure_bar":1.02,"max_pressure_bar":1.02,"min_pressure_bar":1.01,"alfa_counter":0.001252,"beta_counter":-0.001248,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Pressing;77000317;LOW;1.02;1.02;1.01;1111-11-11 11:11.11
|
|
@ -44,7 +44,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DigitalInput),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("INPUT_BITS", Translate::Type::IndexToString)
|
||||
.add(Translate::Rule("INPUT_BITS", Translate::MapType::IndexToString)
|
||||
.set(MaskBits(0xffff))
|
||||
.add(Translate::Map(0x11 ,"CLOSED", TestBit::Set))
|
||||
.add(Translate::Map(0x55 ,"OPEN", TestBit::Set))
|
||||
|
@ -58,7 +58,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ErrorFlags),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xffff))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -68,7 +68,7 @@ namespace
|
|||
"How many times the door/window has been opened or closed.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -79,7 +79,7 @@ namespace
|
|||
"The current number of counted pulses from counter b.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace
|
|||
{
|
||||
setMfctTPLStatusBits(
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("TPL_STS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x40 ,"SABOTAGE_ENCLOSURE", TestBit::Set))));
|
||||
|
@ -60,7 +60,7 @@ namespace
|
|||
"The current number of counted pulses from counter a.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("0EFD3A"))
|
||||
);
|
||||
|
@ -70,7 +70,7 @@ namespace
|
|||
"The current number of counted pulses from counter b.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("8E40FD3A"))
|
||||
);
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace
|
|||
{
|
||||
setMfctTPLStatusBits(
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("TPL_STS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x04 ,"LOW_BATTERY", TestBit::Set))));
|
||||
|
@ -56,7 +56,7 @@ namespace
|
|||
"Number of total routed messages since power up",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -67,7 +67,7 @@ namespace
|
|||
"Used router slots (maximum 936)",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -92,7 +92,7 @@ namespace
|
|||
.set(VIFRange::Dimensionless)
|
||||
.set(SubUnitNr(2)),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("INPUT_BITS", Translate::Type::IndexToString)
|
||||
.add(Translate::Rule("INPUT_BITS", Translate::MapType::IndexToString)
|
||||
.set(MaskBits(0x01))
|
||||
.add(Translate::Map(0x00, "NO", TestBit::Set))
|
||||
.add(Translate::Map(0x01, "YES", TestBit::Set))
|
||||
|
@ -103,7 +103,7 @@ namespace
|
|||
"Seconds to mode change (Listen -> Sleep or Sleep -> Listen). Maximum 32767 seconds",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -115,7 +115,7 @@ namespace
|
|||
"Value on parameter 'Listen timer'",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -127,7 +127,7 @@ namespace
|
|||
"Value on parameter 'Pause timer'",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -143,7 +143,7 @@ namespace
|
|||
.set(VIFRange::Dimensionless)
|
||||
.set(StorageNr(3)),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("INPUT_BITS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("INPUT_BITS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xffff))
|
||||
.add(Translate::Map(0x01 ,"SU", TestBit::Set))
|
||||
.add(Translate::Map(0x02 ,"MO", TestBit::Set))
|
||||
|
@ -159,7 +159,7 @@ namespace
|
|||
"Value on parameter 'Start time', shown as minusted after midnight (-1=Not used)",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -180,7 +180,7 @@ namespace
|
|||
"Battery voltage.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"Unique asynchronous message number.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AccessNumber)
|
||||
|
@ -80,7 +80,7 @@ namespace
|
|||
"Minutes since last manual test.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace
|
|||
addOptionalLibraryFields("on_time_h");
|
||||
setMfctTPLStatusBits(
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("TPL_STS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("TPL_STS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xe0))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x40 ,"SABOTAGE_ENCLOSURE", TestBit::Set))));
|
||||
|
@ -55,7 +55,7 @@ namespace
|
|||
"The current temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -66,7 +66,7 @@ namespace
|
|||
"The current humidity.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -77,7 +77,7 @@ namespace
|
|||
"The average temperature over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
"The average humidity over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -101,7 +101,7 @@ namespace
|
|||
"The average temperature over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -113,7 +113,7 @@ namespace
|
|||
"The average humidity over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2021-2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
Copyright (C) 2021-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -34,6 +34,7 @@ namespace
|
|||
di.addDetection(MANUFACTURER_LSE, 0x07, 0x18);
|
||||
di.addDetection(MANUFACTURER_LSE, 0x07, 0x16);
|
||||
di.addDetection(MANUFACTURER_LSE, 0x07, 0x17);
|
||||
di.addDetection(MANUFACTURER_LSE, 0x07, 0xd8);
|
||||
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
||||
});
|
||||
|
||||
|
@ -44,7 +45,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -55,7 +56,7 @@ namespace
|
|||
"The water consumption at the due date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -77,7 +78,7 @@ namespace
|
|||
"The water consumption at the what date?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -105,7 +106,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -207,3 +208,8 @@ namespace
|
|||
// telegram=|2D4465329933961318067ADA000000_0C13567100004C1300000000426CFFFF02BB560000326CFFFF046D2307A12C|
|
||||
// {"media":"warm water","meter":"lse_07_17","name":"Water","id":"13963399","total_m3":7.156,"due_date_m3":0,"due_date":"2127-15-31","what_date_m3":7,"what_date":"2021-11-30","error_code":"OK","error_date":"2127-15-31","device_date_time":"2021-12-01 07:35","meter_version":"11","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Water;13963399;7.156;0;2127-15-31;OK;2127-15-31;2021-12-01 07:35;1111-11-11 11:11.11
|
||||
|
||||
// Test: Water2 lse_07_17 09993623 NOKEY
|
||||
// telegram=|2d44653223369909d8077a80000000046d130aed2B0c13233332004c1351762700426cdf2c326cffff02BB560000|
|
||||
// {"device_date_time": "2023-11-13 10:19","due_date": "2022-12-31","due_date_m3": 277.651,"error_code": "OK","error_date": "2127-15-31","id": "09993623","media": "water","meter": "lse_07_17","name": "Water2","timestamp": "1111-11-11T11:11:11Z","total_m3": 323.323}
|
||||
// |Water2;09993623;323.323;277.651;2022-12-31;OK;2127-15-31;2023-11-13 10:19;1111-11-11 11:11.11
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -87,7 +87,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -108,7 +108,7 @@ namespace
|
|||
"Duration since last measurement.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DurationSinceReadout)
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ namespace
|
|||
"The total heat energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -77,7 +77,7 @@ namespace
|
|||
"The total heating media volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -88,7 +88,7 @@ namespace
|
|||
"The current heat media volume flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -99,7 +99,7 @@ namespace
|
|||
"The current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::PowerW)
|
||||
|
@ -110,7 +110,7 @@ namespace
|
|||
"The difference between flow and return media temperatures.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::TemperatureDifference)
|
||||
|
@ -121,7 +121,7 @@ namespace
|
|||
"The most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES | PrintProperty::HIDE,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
@ -134,7 +134,7 @@ namespace
|
|||
"The total water consumption at the historic date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
|||
"The total water consumption recorded at the beginning of this month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -74,7 +74,7 @@ namespace
|
|||
"The total water consumption recorded at the beginning of this month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -130,7 +130,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -212,8 +212,8 @@ namespace
|
|||
|
||||
// Test: Minowired minomess 57575757 NOKEY
|
||||
// telegram=|6874746808007257575757496A000712000000_0C7857575757046D2414DE280413000000000C943C000000004413FFFFFFFF426CFFFF840113FFFFFFFF82016CFFFFC40113FFFFFFFFC2016CFFFF840213FFFFFFFF82026CFFFF043B000000000422E62F000004260000000034220000000002FD1700001F5716|
|
||||
// {"media":"water","meter":"minomess","name":"Minowired","id":"57575757","fabrication_no":"57575757","operating_time_h":0,"on_time_h":12262,"on_time_at_error_h":0,"meter_datetime":"2022-08-30 20:36","total_m3":0,"total_backward_m3":0,"volume_flow_m3h":0,"target_m3":4294967.295,"target_date":"2127-15-31","status":"OK","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Minowired;57575757;0;4294967.295;OK;1111-11-11 11:11.11
|
||||
// {"media":"water","meter":"minomess","name":"Minowired","id":"57575757","fabrication_no":"57575757","operating_time_h":0,"on_time_h":12262,"on_time_at_error_h":0,"meter_datetime":"2022-08-30 20:36","total_m3":0,"total_backward_m3":0,"volume_flow_m3h":0,"target_m3":-0.001,"target_date":"2127-15-31","status":"OK","timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Minowired;57575757;0;-0.001;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: Zenner_cold minomess 21314151 NOKEY
|
||||
// telegram=|6644496A4425155518377251413121496A0116360050052F2F_0C1355000000026CEC2182046CE1218C0413000000808D0493132C33FE00008000008000008000008000008000008000008000008000008000008000008000008000008000008002FD1700002F2F|
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace
|
|||
"The total water consumption recorded at the end of previous year.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -58,7 +58,7 @@ namespace
|
|||
"Date when previous year ended.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace
|
|||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FF20")),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0x000f))
|
||||
.set(DefaultMessage("OK"))
|
||||
.add(Translate::Map(0x01 ,"DRY", TestBit::Set))
|
||||
|
@ -60,7 +60,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -71,7 +71,7 @@ namespace
|
|||
"The total water consumption recorded at the beginning of this month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -83,7 +83,7 @@ namespace
|
|||
"The water temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
"The external temperature outside of the meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Any)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -108,7 +108,7 @@ namespace
|
|||
"The lowest external temperature outside of the meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -119,7 +119,7 @@ namespace
|
|||
"The maximum flow recorded during previous period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -136,7 +136,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0x000f),
|
||||
"",
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"DRY",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x0070),
|
||||
"",
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"REVERSED",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x0380),
|
||||
"",
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"LEAKING",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0x1c00),
|
||||
"",
|
||||
{
|
||||
|
@ -240,7 +240,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"BURSTING",
|
||||
Translate::Type::IndexToString,
|
||||
Translate::MapType::IndexToString,
|
||||
AlwaysTrigger, MaskBits(0xe000),
|
||||
"",
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ namespace
|
|||
"The current temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -73,7 +73,7 @@ namespace
|
|||
"The current relative humidity.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace
|
|||
"Et+ the total 3-phase active positive energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -61,7 +61,7 @@ namespace
|
|||
"P+ the 3-phase active positive power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"Er+ the total 3-phase reactive positive energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
"Q+ the 3-phase reactive positive power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -103,7 +103,7 @@ namespace
|
|||
"Part Et+ the total 3-phase active partial energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -117,7 +117,7 @@ namespace
|
|||
"P- the 3-phase active negative power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -131,7 +131,7 @@ namespace
|
|||
"Part Er+ the total 3-phase reactive partial energy.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -145,7 +145,7 @@ namespace
|
|||
"Q- the 3-phase reactive negative power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -159,7 +159,7 @@ namespace
|
|||
"PF the power factor.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless),
|
||||
|
@ -174,7 +174,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ErrorFlags),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0xff))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -186,7 +186,7 @@ namespace
|
|||
"I1 Amperage for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -198,7 +198,7 @@ namespace
|
|||
"I2 Amperage for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -210,7 +210,7 @@ namespace
|
|||
"I3 Amperage for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -222,7 +222,7 @@ namespace
|
|||
"L1-N Voltage for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -234,7 +234,7 @@ namespace
|
|||
"L2-N Voltagefor L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -246,7 +246,7 @@ namespace
|
|||
"L3-N Voltage for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -260,7 +260,7 @@ namespace
|
|||
"P1 Power for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -273,7 +273,7 @@ namespace
|
|||
"P2 Power for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -286,7 +286,7 @@ namespace
|
|||
"P3 Power for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -299,7 +299,7 @@ namespace
|
|||
"Q1 Power for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -312,7 +312,7 @@ namespace
|
|||
"Q2 Power for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -325,7 +325,7 @@ namespace
|
|||
"Q3 Power for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -338,7 +338,7 @@ namespace
|
|||
"PF1 the power factor for L1 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -351,7 +351,7 @@ namespace
|
|||
"PF2 the power factor for L2 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -364,7 +364,7 @@ namespace
|
|||
"PF3 the power factor for L3 phase.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Dimensionless)
|
||||
|
@ -377,7 +377,7 @@ namespace
|
|||
"L1-L2 Voltage between phases.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -389,7 +389,7 @@ namespace
|
|||
"L2-L3 Voltage between phases.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -401,7 +401,7 @@ namespace
|
|||
"L3-L1 Voltage between phases.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Voltage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Voltage)
|
||||
|
@ -413,7 +413,7 @@ namespace
|
|||
"I Neutral amperage.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Amperage,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Amperage)
|
||||
|
@ -426,7 +426,7 @@ namespace
|
|||
"Frequency in 0.1 Hz",
|
||||
DEFAULT_PRINT_PROPERTIES | PrintProperty::HIDE,
|
||||
Quantity::Frequency,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("05FF5A"))
|
||||
);
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"The total energy backward (production) recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -87,7 +87,7 @@ namespace
|
|||
"The current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -98,7 +98,7 @@ namespace
|
|||
"The current power production.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace
|
|||
"The current temperature.",
|
||||
PrintProperty::REQUIRED,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -59,7 +59,7 @@ namespace
|
|||
"The average temperature over the last hour.",
|
||||
PrintProperty::REQUIRED,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -71,7 +71,7 @@ namespace
|
|||
"The average temperature over the last 24 hours.",
|
||||
PrintProperty::REQUIRED,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -83,7 +83,7 @@ namespace
|
|||
"The current relative humidity.",
|
||||
PrintProperty::REQUIRED,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -94,7 +94,7 @@ namespace
|
|||
"The average relative humidity over the last hour.",
|
||||
PrintProperty::REQUIRED,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -106,7 +106,7 @@ namespace
|
|||
"The average relative humidity over the last 24 hours.",
|
||||
PrintProperty::REQUIRED,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -59,7 +59,7 @@ namespace
|
|||
"The total amount of water that has passed through this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -70,7 +70,7 @@ namespace
|
|||
"The active power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -81,7 +81,7 @@ namespace
|
|||
"The flow of water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -92,7 +92,7 @@ namespace
|
|||
"The forward temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -103,7 +103,7 @@ namespace
|
|||
"The return temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -124,7 +124,7 @@ namespace
|
|||
"The energy consumption recorded by this meter at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -136,7 +136,7 @@ namespace
|
|||
"The amount of water that had passed through this meter at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -148,7 +148,7 @@ namespace
|
|||
"The maximum forward temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -160,7 +160,7 @@ namespace
|
|||
"The maximum return temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -172,7 +172,7 @@ namespace
|
|||
"The maximum forward flow of water through this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace
|
|||
"The total water consumption at the end of the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -71,7 +71,7 @@ namespace
|
|||
"The total media volume flowing forward at the end of previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -84,7 +84,7 @@ namespace
|
|||
"The total media volume flowing backward at the end of the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -97,7 +97,7 @@ namespace
|
|||
"Percentage of battery remaining.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("01FD74")),
|
||||
Unit::PERCENTAGE
|
||||
|
@ -118,5 +118,5 @@ namespace
|
|||
|
||||
// Test: M q400 05829163 NOKEY
|
||||
// telegram=|544409076391820510077ABF100000046D2A0DC62C0420E80F430104130000000004933B0000000004933C00000000023B00000259F0D8446D0000C12C44130000000044933B0000000044933C0000000001FD7461|
|
||||
// {"backward_at_set_date_m3": 0,"battery_pct": 97,"consumption_at_set_date_m3": 0,"flow_temperature_c": 555.36,"forward_at_set_date_m3": 0,"id": "05829163","media": "water","meter": "q400","meter_datetime": "2022-12-06 13:42","name": "M","on_time_h": 5881.166667,"set_datetime": "2022-12-01 00:00","status": "TEMPORARY_ERROR","timestamp": "1111-11-11T11:11:11Z","total_backward_m3": 0,"total_forward_m3": 0,"total_m3": 0,"volume_flow_m3h": 0}
|
||||
// {"backward_at_set_date_m3": 0,"battery_pct": 97,"consumption_at_set_date_m3": 0,"flow_temperature_c": -100,"forward_at_set_date_m3": 0,"id": "05829163","media": "water","meter": "q400","meter_datetime": "2022-12-06 13:42","name": "M","on_time_h": 5881.166667,"set_datetime": "2022-12-01 00:00","status": "TEMPORARY_ERROR","timestamp": "1111-11-11T11:11:11Z","total_backward_m3": 0,"total_forward_m3": 0,"total_m3": 0,"volume_flow_m3h": 0}
|
||||
// |M;05829163;0;1111-11-11 11:11.11
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ namespace
|
|||
"The current heat cost allocation.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -117,7 +117,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -139,7 +139,7 @@ namespace
|
|||
"Heat cost allocation at the 8 billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -161,7 +161,7 @@ namespace
|
|||
"Heat cost allocation at the 17 billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -200,7 +200,7 @@ namespace
|
|||
"Forward media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -106,7 +106,7 @@ namespace
|
|||
"The total energy consumption recorded at the last day of the previous month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(17))
|
||||
|
@ -128,7 +128,7 @@ namespace
|
|||
"The total energy consumption recorded at the last day of the previous year.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(StorageNr(1))
|
||||
|
@ -160,8 +160,11 @@ namespace
|
|||
vector<uchar> v;
|
||||
auto entry = it->second.second;
|
||||
hex2bin(entry.value.substr(0, 8), &v);
|
||||
t->addId(v.begin());
|
||||
std::string info = "*** " + entry.value.substr(0, 8) + " tpl-id (" + t->ids.back() + ")";
|
||||
// FIXME PROBLEM
|
||||
Address a;
|
||||
a.id = tostrprintf("%02x%02x%02x%02x", v[3], v[2], v[1], v[0]);
|
||||
t->addresses.push_back(a);
|
||||
std::string info = "*** " + entry.value.substr(0, 8) + " tpl-id (" + t->addresses.back().id + ")";
|
||||
t->addSpecialExplanation(entry.offset, 4, KindOfData::CONTENT, Understanding::FULL, info.c_str());
|
||||
|
||||
v.clear();
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
"The total energy consumption recorded at key (billing) date",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -121,7 +121,7 @@ namespace
|
|||
info,
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -136,7 +136,7 @@ namespace
|
|||
"The time between the measurement and the sending of this telegram.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ActualityDuration)
|
||||
|
@ -147,7 +147,7 @@ namespace
|
|||
"How long the meter has been in an error state and unable to measure values, while powered up.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::AtError)
|
||||
.set(VIFRange::OnTime)
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ namespace
|
|||
"Number of times the smoke alarm has triggered.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Unsigned,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("81037C034C4123"))
|
||||
);
|
||||
|
@ -102,7 +102,7 @@ namespace
|
|||
"Number of times the test button has been pressed.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("81027C03495523"))
|
||||
);
|
||||
|
@ -112,7 +112,7 @@ namespace
|
|||
"Transmission counter?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Dimensionless,
|
||||
VifScaling::None,
|
||||
VifScaling::None, DifSignedness::Unsigned,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AccessNumber)
|
||||
|
@ -132,7 +132,7 @@ namespace
|
|||
"What does this mean?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("02FDAC7E"))
|
||||
);
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -69,7 +69,7 @@ namespace
|
|||
"The total heating energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -81,7 +81,7 @@ namespace
|
|||
"The total cooling energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -93,7 +93,7 @@ namespace
|
|||
"The current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -114,7 +114,7 @@ namespace
|
|||
"The heating energy consumption recorded at the end of the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -127,7 +127,7 @@ namespace
|
|||
"The cooling energy consumption recorded at the end of the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2022 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
Copyright (C) 2022-2024 Fredrik Öhrström (gpl-3.0-or-later)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -42,6 +42,7 @@ namespace
|
|||
di.addDetection(MANUFACTURER_QDS, 0x07, 0x16);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x06, 0x18);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x07, 0x18);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x07, 0x19);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x06, 0x35);
|
||||
di.addDetection(MANUFACTURER_QDS, 0x07, 0x35);
|
||||
di.usesProcessContent();
|
||||
|
@ -65,7 +66,7 @@ namespace
|
|||
"The water consumption at the due date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -77,7 +78,7 @@ namespace
|
|||
"The due date for billing date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
@ -90,7 +91,7 @@ namespace
|
|||
"The water consumption at the 17 due date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -102,7 +103,7 @@ namespace
|
|||
"The due date for billing date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
@ -115,7 +116,7 @@ namespace
|
|||
"Media volume flow when duration exceeds lower last.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -127,7 +128,7 @@ namespace
|
|||
"The date the error occurred at. If no error, reads 2127-15-31 (FFFF).",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::AtError)
|
||||
.set(VIFRange::Date),
|
||||
|
@ -195,3 +196,9 @@ void Driver::processContent(Telegram *t) {
|
|||
// telegram=|49449344123456781606780DFF5F3500824E00007F0007C113FFFF63961300DF2C82731200FE2463811300A400F200D100A900DD00E000E90006011601EA0027010F012F046D0211F225|
|
||||
// {"due_17_date": "2023-04-30","due_17_date_m3": 138.163,"due_date": "2022-12-31","due_date_m3": 127.382,"id": "78563412","media": "warm water","meter": "qwater","meter_datetime": "2023-05-18 17:02","name": "QWooo","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 139.663}
|
||||
// |QWooo;78563412;139.663;127.382;2022-12-31;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: QWaaa qwater 51220588 NOKEY
|
||||
// Comment:
|
||||
// telegram=|4944934488052251190778_0DFF5F350082930000810007C113FFFF91670400FF2C265402001E34332204000000EE00F201A501DB01C1015401B70178019701B901C9012F046D06091D35|
|
||||
// {"due_17_date": "2024-04-30","due_17_date_m3": 42.233,"due_date": "2023-12-31","due_date_m3": 25.426,"id": "51220588","media": "water","meter": "qwater","meter_datetime": "2024-05-29 09:06","name": "QWaaa","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 46.791}
|
||||
// |QWaaa;51220588;46.791;25.426;2023-12-31;OK;1111-11-11 11:11.11
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace
|
|||
"The current temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -58,7 +58,7 @@ namespace
|
|||
"The average temperature over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -70,7 +70,7 @@ namespace
|
|||
"The average temperature over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -82,7 +82,7 @@ namespace
|
|||
"The maximum temperature over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -93,7 +93,7 @@ namespace
|
|||
"The maximum temperature over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -105,7 +105,7 @@ namespace
|
|||
"The minimum temperature over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -116,7 +116,7 @@ namespace
|
|||
"The minimum temperature over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -128,7 +128,7 @@ namespace
|
|||
"The current relative humidity.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -139,7 +139,7 @@ namespace
|
|||
"The average relative humidity over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -151,7 +151,7 @@ namespace
|
|||
"The average relative humidity over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -163,7 +163,7 @@ namespace
|
|||
"The maximum relative humidity over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -174,7 +174,7 @@ namespace
|
|||
"The maximum relative humidity over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -186,7 +186,7 @@ namespace
|
|||
"The minimum relative humidity over the last hour.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -197,7 +197,7 @@ namespace
|
|||
"The minimum relative humidity over the last 24 hours.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::RelativeHumidity,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Minimum)
|
||||
.set(VIFRange::RelativeHumidity)
|
||||
|
@ -209,7 +209,7 @@ namespace
|
|||
"The meters date time.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::DateTime)
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -62,7 +62,7 @@ namespace
|
|||
"The active power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -73,7 +73,7 @@ namespace
|
|||
"The maximum power consumption over ?period?.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -84,7 +84,7 @@ namespace
|
|||
"The flow of water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
"The maximum forward flow of water over a ?period?.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -106,7 +106,7 @@ namespace
|
|||
"The forward temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -117,7 +117,7 @@ namespace
|
|||
"The return temperature of the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -128,7 +128,7 @@ namespace
|
|||
"The temperature difference forward-return for the water.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::TemperatureDifference)
|
||||
|
@ -139,7 +139,7 @@ namespace
|
|||
"The total amount of water that has passed through this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -155,7 +155,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ namespace
|
|||
"The energy consumption at the last billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -205,7 +205,7 @@ namespace
|
|||
info,
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -220,8 +220,14 @@ namespace
|
|||
// {"media":"heat","meter":"sensostar","name":"Heat","id":"20480057","meter_timestamp":"2022-04-28 13:44","total_kwh":0,"power_kw":0,"power_max_kw":0,"flow_water_m3h":0,"flow_water_max_m3h":0,"forward_c":20,"return_c":21,"difference_c":-0.38,"total_water_m3":0,"current_status":"ERROR_FLOW_MEASUREMENT_SYSTEM_ERROR","reporting_date":"2000-00-00","energy_consumption_at_reporting_date_kwh":0,"consumption_1_months_ago_kwh":0,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Heat;20480057;0;0;ERROR_FLOW_MEASUREMENT_SYSTEM_ERROR;2000-00-00;0;1111-11-11 11:11.11
|
||||
|
||||
// Test: WMZ sensostar 02752560 NOKEY
|
||||
// Comment: from "Sensostar U"
|
||||
//Test: WMZ sensostar 02752560 NOKEY
|
||||
//Comment: from "Sensostar U"
|
||||
//telegram=a444c5146025750200047ac20000202f2f046d2e26c62a040643160000041310f0050001fd1700426cbf2c4406570e00008401061f160000840206f6150000840306f5150000840406f3150000840506ea150000840606bf1500008407065214000084080692120000840906c5100000840a06570e0000840b06ca0b0000840c06da090000840d06ca080000840e06c8080000840f06c608000003fd0c05010002fd0b2111
|
||||
//{"media":"heat","meter":"sensostar","name":"WMZ","id":"02752560","meter_timestamp":"2022-10-06 06:46","total_kwh":5699,"total_water_m3":389.136,"current_status":"OK","reporting_date":"2021-12-31","energy_consumption_at_reporting_date_kwh":3671,"consumption_1_months_ago_kwh":5663,"consumption_2_months_ago_kwh":5622,"consumption_3_months_ago_kwh":5621,"consumption_4_months_ago_kwh":5619,"consumption_5_months_ago_kwh":5610,"consumption_6_months_ago_kwh":5567,"consumption_7_months_ago_kwh":5202,"consumption_8_months_ago_kwh":4754,"consumption_9_months_ago_kwh":4293,"consumption_10_months_ago_kwh":3671,"consumption_11_months_ago_kwh":3018,"consumption_12_months_ago_kwh":2522,"consumption_13_months_ago_kwh":2250,"consumption_14_months_ago_kwh":2248,"consumption_15_months_ago_kwh":2246,"timestamp":"1111-11-11 11:11.11"}
|
||||
//WMZ;02752560;5699;389.136000;OK;1111-11-11 11:11.11
|
||||
|
||||
// Test: ABC sensostar 21750444 NOKEY
|
||||
// Comment: Test negative flow values
|
||||
// telegram=4944C5144404752100047AC1000020_2F2F046D142D073404068847000001FD170004138E8A4000043BF7FFFFFF042B00000000025B3E00025F360002612F0303FD0C05010002FD0B2011
|
||||
// {"current_status": "OK","difference_c": 8.15,"flow_water_m3h": -0.009,"forward_c": 62,"id": "21750444","media": "heat","meter": "sensostar","meter_timestamp": "2024-04-07 13:20","name": "ABC","power_kw": 0,"return_c": 54,"timestamp": "1111-11-11T11:11:11Z","total_kwh": 18312,"total_water_m3": 4229.774}
|
||||
// |ABC;21750444;18312;4229.774;OK;null;null;1111-11-11 11:11.11
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ErrorFlags),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0x0000))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
@ -61,7 +61,7 @@ namespace
|
|||
"The total heat energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -72,7 +72,7 @@ namespace
|
|||
"The total heat energy consumption recorded by this meter on tariff 1.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -84,7 +84,7 @@ namespace
|
|||
"The total heating media volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -95,7 +95,7 @@ namespace
|
|||
"The total heating media volume recorded by this meter on tariff 2.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -107,7 +107,7 @@ namespace
|
|||
"The current heat media volume flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -118,7 +118,7 @@ namespace
|
|||
"The current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::PowerW)
|
||||
|
@ -129,7 +129,7 @@ namespace
|
|||
"The current forward heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -140,7 +140,7 @@ namespace
|
|||
"The current return heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -151,7 +151,7 @@ namespace
|
|||
"The current return heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::TemperatureDifference)
|
||||
|
@ -162,7 +162,7 @@ namespace
|
|||
"The total heat energy consumption recorded by this meter at the end of the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -174,7 +174,7 @@ namespace
|
|||
"The total heating media volume recorded by this meter at the end of the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -186,7 +186,7 @@ namespace
|
|||
"The last billing period end date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -59,7 +59,7 @@ namespace
|
|||
"The total cooling energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -71,7 +71,7 @@ namespace
|
|||
"The total volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyVolumeVIF)
|
||||
|
@ -82,7 +82,7 @@ namespace
|
|||
"The total cooling volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyVolumeVIF)
|
||||
|
@ -94,7 +94,7 @@ namespace
|
|||
"The current flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -105,7 +105,7 @@ namespace
|
|||
"The power.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyPowerVIF)
|
||||
|
@ -116,7 +116,7 @@ namespace
|
|||
"The flow temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -127,7 +127,7 @@ namespace
|
|||
"The return temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -138,7 +138,7 @@ namespace
|
|||
"How long the meter has been collecting data.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::OperatingTime)
|
||||
|
@ -149,7 +149,7 @@ namespace
|
|||
"How long the meter has been in an error state and not collected data.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::OperatingTime)
|
||||
|
@ -161,7 +161,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -173,7 +173,7 @@ namespace
|
|||
"The total cooling energy consumption recorded by this meter at the set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -186,7 +186,7 @@ namespace
|
|||
"The last billing set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace
|
|||
"The current heat cost allocation for this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -64,7 +64,7 @@ namespace
|
|||
"Heat cost allocation at the most recent billing period date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::HCA,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::HeatCostAllocation)
|
||||
|
@ -76,7 +76,7 @@ namespace
|
|||
"The current temperature of the heating element.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -87,7 +87,7 @@ namespace
|
|||
"The current room temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ExternalTemperature)
|
||||
|
@ -98,7 +98,7 @@ namespace
|
|||
"The maximum temperature so far during this billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -110,7 +110,7 @@ namespace
|
|||
"The maximum temperature during the previous billing period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Maximum)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace
|
|||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ErrorFlags),
|
||||
Translate::Lookup()
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::Type::BitToString)
|
||||
.add(Translate::Rule("ERROR_FLAGS", Translate::MapType::BitToString)
|
||||
.set(MaskBits(0x000f))
|
||||
.set(DefaultMessage("OK"))
|
||||
));
|
||||
|
|
|
@ -49,8 +49,8 @@ namespace
|
|||
di.setName("topaseskr");
|
||||
di.setDefaultFields(
|
||||
"name,id,total_m3,temperature_c,current_flow_m3h,volume_year_period_m3,"
|
||||
"reverse_volume_year_period_m3,meter_year_period_start_date,volume_month_period_m3,"
|
||||
"meter_month_period_start_datetime,timestamp");
|
||||
"reverse_volume_year_period_m3,meter_year_period_end_date,volume_month_period_m3,"
|
||||
"meter_month_period_end_datetime,timestamp");
|
||||
di.setMeterType(MeterType::WaterMeter);
|
||||
di.addLinkMode(LinkMode::T1);
|
||||
di.addDetection(MANUFACTURER_AMT, 0x06, 0xf1);
|
||||
|
@ -67,7 +67,7 @@ namespace
|
|||
"Current water temperature recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature));
|
||||
|
@ -77,7 +77,7 @@ namespace
|
|||
"The current water flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow));
|
||||
|
@ -87,7 +87,7 @@ namespace
|
|||
"Volume up to end of last year-period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -99,7 +99,7 @@ namespace
|
|||
"Reverse volume in this year-period (?)",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -109,8 +109,8 @@ namespace
|
|||
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"meter_year_period_start_date",
|
||||
"Meter date for year-period start.",
|
||||
"meter_year_period_end_date",
|
||||
"Meter date for year-period end.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
|
@ -123,7 +123,7 @@ namespace
|
|||
"Volume up to end of last month-period.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -131,8 +131,8 @@ namespace
|
|||
);
|
||||
|
||||
addStringFieldWithExtractor(
|
||||
"meter_month_period_start_datetime",
|
||||
"Meter timestamp for month-period start.",
|
||||
"meter_month_period_end_datetime",
|
||||
"Meter timestamp for month-period end.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
|
@ -145,7 +145,7 @@ namespace
|
|||
"Remaining battery life in years.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Time,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::RemainingBattery),
|
||||
|
@ -155,10 +155,10 @@ namespace
|
|||
|
||||
// Test: Witer topaseskr 78563412 NOKEY
|
||||
// telegram=|4E44B40512345678F1077A310040052F2F_01FD08040C13991848004C1359423500CC101300000000CC201359423500426C7F2C0B3B00000002FD74DA10025AD300C4016D3B179F27CC011387124600|
|
||||
// {"media":"water","meter":"topaseskr","name":"Witer","id":"78563412","total_m3":481.899,"access_counter":4,"temperature_c":21.1,"current_flow_m3h":0,"volume_year_period_m3":354.259,"reverse_volume_year_period_m3":0,"meter_year_period_start_date":"2019-12-31","volume_month_period_m3":461.287,"meter_month_period_start_datetime":"2020-07-31 23:59","battery_y":11.811331,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// {"media":"water","meter":"topaseskr","name":"Witer","id":"78563412","total_m3":481.899,"access_counter":4,"temperature_c":21.1,"current_flow_m3h":0,"volume_year_period_m3":354.259,"reverse_volume_year_period_m3":0,"meter_year_period_end_date":"2019-12-31","volume_month_period_m3":461.287,"meter_month_period_end_datetime":"2020-07-31 23:59","battery_y":11.811331,"timestamp":"1111-11-11T11:11:11Z"}
|
||||
// |Witer;78563412;481.899;21.1;0;354.259;0;2019-12-31;461.287;2020-07-31 23:59;1111-11-11 11:11.11
|
||||
|
||||
// Test: Woter topaseskr 69190253 NOKEY
|
||||
// telegram=|4E44B40553021969F1077A0C0040052F2F_01FD08800C13914544004C1393673500CC101300000000CC201393673500426CDF2C0B3B0100F002FD747912025AAE00C4016D3B17FF25CC011325584100|
|
||||
// {"access_counter": 128,"battery_y": 12.947562,"current_flow_m3h": -0.001,"id": "69190253","media": "water","meter": "topaseskr","meter_month_period_start_datetime": "2023-05-31 23:59","meter_year_period_start_date": "2022-12-31","name": "Woter","reverse_volume_year_period_m3": 0,"temperature_c": 17.4,"timestamp": "1111-11-11T11:11:11Z","total_m3": 444.591,"volume_month_period_m3": 415.825,"volume_year_period_m3": 356.793}
|
||||
// {"access_counter": 128,"battery_y": 12.947562,"current_flow_m3h": -0.001,"id": "69190253","media": "water","meter": "topaseskr","meter_month_period_end_datetime": "2023-05-31 23:59","meter_year_period_end_date": "2022-12-31","name": "Woter","reverse_volume_year_period_m3": 0,"temperature_c": 17.4,"timestamp": "1111-11-11T11:11:11Z","total_m3": 444.591,"volume_month_period_m3": 415.825,"volume_year_period_m3": 356.793}
|
||||
// |Woter;69190253;444.591;17.4;-0.001;356.793;0;2022-12-31;415.825;2023-05-31 23:59;1111-11-11 11:11.11
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace
|
|||
"The total heat energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -53,7 +53,7 @@ namespace
|
|||
"The total heating media volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -64,7 +64,7 @@ namespace
|
|||
"The current power consumption.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Power,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::PowerW)
|
||||
|
@ -75,7 +75,7 @@ namespace
|
|||
"The current heat media volume flow.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Flow,
|
||||
VifScaling::AutoSigned,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::VolumeFlow)
|
||||
|
@ -86,7 +86,7 @@ namespace
|
|||
"The current forward heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::FlowTemperature)
|
||||
|
@ -97,7 +97,7 @@ namespace
|
|||
"The current return heat media temperature.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Temperature,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::ReturnTemperature)
|
||||
|
@ -114,7 +114,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace
|
|||
"The total water consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -51,7 +51,7 @@ namespace
|
|||
"The total water consumption recorded at the beginning of this month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -68,7 +68,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"ERROR_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ namespace
|
|||
"The total backward water volume recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(DifVifKey("04933C"))
|
||||
);
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"STATUS_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xffff),
|
||||
"OK",
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ namespace
|
|||
{
|
||||
{
|
||||
"OTHER_FLAGS",
|
||||
Translate::Type::BitToString,
|
||||
Translate::MapType::BitToString,
|
||||
AlwaysTrigger, MaskBits(0xff),
|
||||
"",
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ namespace
|
|||
"The total gas consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
@ -114,7 +114,7 @@ namespace
|
|||
"The total gas consumption recorded by this meter at the beginning of this month.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Volume,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Volume)
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace
|
|||
"Total energy consumption at the end of the year",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -56,7 +56,7 @@ namespace
|
|||
"Date when previous year ended.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -53,7 +53,7 @@ namespace
|
|||
"The total energy consumption recorded when?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -65,7 +65,7 @@ namespace
|
|||
"The last billing old date?",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
@ -77,7 +77,7 @@ namespace
|
|||
"The total energy consumption recorded by this meter at the due date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::Energy,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::AnyEnergyVIF)
|
||||
|
@ -89,7 +89,7 @@ namespace
|
|||
"The last billing set date.",
|
||||
DEFAULT_PRINT_PROPERTIES,
|
||||
Quantity::PointInTime,
|
||||
VifScaling::Auto,
|
||||
VifScaling::Auto, DifSignedness::Signed,
|
||||
FieldMatcher::build()
|
||||
.set(MeasurementType::Instantaneous)
|
||||
.set(VIFRange::Date)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Ładowanie…
Reference in New Issue