// Copyright (C) 2026 Fredrik Öhrström (gpl-3.0-or-later)
driver {
name = qwaterv2
meter_type = WaterMeter
default_fields = name,id,status,total_m3,timestamp
manufacturer = Qundis
detect {
mvt = QDS,33,37
mvt = QDS,35,37
mvt = QDS,16,06
mvt = QDS,16,07
mvt = QDS,17,06
mvt = QDS,17,07
mvt = QDS,18,06
mvt = QDS,18,07
mvt = QDS,19,07
mvt = QDS,1A,06
mvt = QDS,1A,07
mvt = QDS,1D,06
mvt = QDS,1D,07
mvt = QDS,36,06
mvt = QDS,36,07
mvt = LSE,19,07
mvt = LSE,1A,06
mvt = LSE,1A,07
mvt = LSE,1D,06
mvt = LSE,1D,07
mvt = LSE,33,37
mvt = LSE,35,37
mvt = LSE,36,06
mvt = LSE,36,07
}
library {
use = total_m3
use = meter_datetime
use = enhanced_id
}
fields {
field {
name = status
quantity = Text
info = 'Status and error flags'
attributes = STATUS,INCLUDE_TPL_STATUS
match {
measurement_type = Instantaneous
vif_range = ErrorFlags
}
lookup {
name = ERROR_FLAGS
map_type = BitToString
mask_bits = 0xffff
default_message = OK
map {
name = NO_FLOW
// F0
value = 0x0001
test = Set
}
map {
name = SUPPLY_SENSOR_INTERRUPTED
// F1
value = 0x0002
test = Set
}
map {
name = RETURN_SENSOR_INTERRUPTED
// F2
value = 0x0004
test = Set
}
map {
name = TEMPERATURE_ELECTRONICS_ERROR
// F3
value = 0x0008
test = Set
}
map {
name = BATTERY_VOLTAGE_ERROR
// F4
value = 0x0010
test = Set
}
map {
name = SHORT_CIRCUIT_SUPPLY_SENSOR
// F5
value = 0x0020
test = Set
}
map {
name = SHORT_CIRCUIT_RETURN_SENSOR
// F6
value = 0x0040
test = Set
}
map {
name = MEMORY_ERROR
// F7
value = 0x0080
test = Set
}
map {
name = SABOTAGE
// F8 - F1,2,3,5,6 longer than 8 hours, latching error, no more measurements performed.
value = 0x0100
test = Set
}
map {
name = ELECTRONICS_ERROR
// F9
value = 0x0200
test = Set
}
}
}
field {
name = target
quantity = Volume
match {
measurement_type = Instantaneous
vif_range = AnyVolumeVIF
storage_nr = 17
}
}
field {
name = volume_flow
quantity = Flow
match {
measurement_type = Instantaneous
vif_range = VolumeFlow
add_combinable = DurationExceedsLowerLast
}
}
field {
name = target
quantity = PointInTime
display_unit = date
match {
measurement_type = Instantaneous
vif_range = Date
storage_nr = 17
}
}
field {
name = target_year
quantity = Volume
match {
measurement_type = Instantaneous
vif_range = AnyVolumeVIF
storage_nr = 1
}
}
field {
name = target_year
quantity = PointInTime
display_unit = date
match {
measurement_type = Instantaneous
vif_range = Date
storage_nr = 1
}
}
field {
name = device_error
quantity = PointInTime
display_unit = date
match {
measurement_type = AtError
vif_range = Date
}
}
field {
name = mfct_specific_data
quantity = Text
attributes = HIDE
match {
difvifkey = 0DFF5F
}
// Siemens/Qundis WalkByDataSet block: DIF=0D (variable-len), VIF=FF (mfct), VIFE=5F, 53 bytes.
// 9-byte proprietary header (skipped as quad, quad, byte):
// [0] 0x00 reserved
// [1] 0x82 wbdsId: Type 2 WalkByDataSet
// [2] counter rolling transmission counter (increments each send)
// [3] 0x00 reserved
// [4] 0x00 reserved
// [5] flags device-specific status/flags (format unknown)
// [6] 0x00/01 extra flag
// [7] 0x07 constant (possibly number of data records)
// [8] 0xC1 meter type: 0xB0=HCA, 0xC0=heat, 0xC1=warm/cold water
// Byte [9] is the VIF (0x13 = volume in liters), which is matched below.
ixml = "decode = quad, quad, byte, volume_l.
volume_l = '13', error_date, total_l, target_year_date, target_year_l, target_date, target_l, delta1, delta2, delta3, delta4, delta5, delta6, delta7, delta8, delta9, delta10, delta11, delta12, -pad.
error_date = word, @DV_426C.
target_year_date = word, @DV_426C.
target_date = word, @DV_C2086C.
total_l = quad, @DV_0C13.
target_year_l = quad, @DV_4C13.
target_l = quad, @DV_CC0813.
delta1 = word, @DV_820113.
delta2 = word, @DV_C20113.
delta3 = word, @DV_820213.
delta4 = word, @DV_C20213.
delta5 = word, @DV_820313.
delta6 = word, @DV_C20313.
delta7 = word, @DV_820413.
delta8 = word, @DV_C20413.
delta9 = word, @DV_820513.
delta10 = word, @DV_C20513.
delta11 = word, @DV_820613.
delta12 = word, @DV_C20613.
-pad = byte.
-hex = ['A'-'F';'0'-'9'].
-byte = hex, hex.
-word = byte, byte.
-triplet = byte, byte, byte.
-quad = byte, byte, byte, byte.
DV_0C13>dvk = +'0C13'.
DV_4C13>dvk = +'4C13'.
DV_CC0813>dvk = +'CC0813'.
DV_426C>dvk = +'426C'.
DV_C2086C>dvk = +'C2086C'.
DV_820113>dvk = +'820113'.
DV_C20113>dvk = +'C20113'.
DV_820213>dvk = +'820213'.
DV_C20213>dvk = +'C20213'.
DV_820313>dvk = +'820313'.
DV_C20313>dvk = +'C20313'.
DV_820413>dvk = +'820413'.
DV_C20413>dvk = +'C20413'.
DV_820513>dvk = +'820513'.
DV_C20513>dvk = +'C20513'.
DV_820613>dvk = +'820613'.
DV_C20613>dvk = +'C20613'."
}
field {
name = 'volume_delta_{storage_counter}'
quantity = Volume
info = 'Monthly volume delta.'
vif_scaling = Auto
dif_signedness = Signed
match {
measurement_type = Instantaneous
vif_range = AnyVolumeVIF
storage_nr = 2,13
}
}
}
tests {
test {
args = 'MyQWater qwaterv2 12353648 NOKEY'
telegram = 3b4493444836351218067ac70000200c13911900004c1391170000426cbf2ccc081391170000c2086cbf2c02bb560000326cffff046d1e02de21fed0
json = '{"_": "telegram","device_error_date": "2128-03-31","id": "12353648","media": "warm water","meter": "qwaterv2","meter_datetime": "2022-01-30 02:30","name": "MyQWater","status": "OK","target_date": "2021-12-31","target_m3": 1.791,"target_year_date": "2021-12-31","target_year_m3": 1.791,"timestamp": "1111-11-11T11:11:11Z","total_m3": 1.991,"volume_flow_m3h": 0}'
fields = 'MyQWater;12353648;OK;1.991;1111-11-11 11:11.11'
}
test {
args = 'MyQWater qwaterv2 12353648 NOKEY'
comment = 'A walk by telegram with mfct data.'
telegram = 4b449344483635121806780dff5f350082da0000600107c113ffff48200000bf2c91170000df2120200000008001000000060019001000160018000d001300350017002f046d370cc422c759
json = '{"_": "telegram","id": "12353648","media": "warm water","meter": "qwaterv2","meter_datetime": "2022-02-04 12:55","name": "MyQWater","status": "OK","target_date": "2022-01-31","target_m3":2.02,"target_year_date": "2021-12-31","target_year_m3": 1.791,"timestamp": "1111-11-11T11:11:11Z","total_m3": 2.048,"volume_delta_2_m3":-32.768,"volume_delta_3_m3":0.001,"volume_delta_4_m3":0,"volume_delta_5_m3":0.006,"volume_delta_6_m3":0.025,"volume_delta_7_m3":0.016,"volume_delta_8_m3":0.022,"volume_delta_9_m3":0.024,"volume_delta_10_m3":0.013,"volume_delta_11_m3":0.019,"volume_delta_12_m3":0.053,"volume_delta_13_m3":0.023}'
fields = 'MyQWater;12353648;OK;2.048;1111-11-11 11:11.11'
}
test {
args = 'AnotherQWater qwaterv2 66666666 NOKEY'
telegram = 3C449344682268363537726666666693443507720000200C13670512004C1361100300426CBF2CCC081344501100C2086CDF28326CFFFF046D0813CF29
json = '{"_":"telegram","media":"water","meter":"qwaterv2","name":"AnotherQWater","id":"66666666","device_error_date":"2128-03-31","target_m3":115.044,"target_date":"2022-08-31","target_year_m3":31.061,"target_year_date":"2021-12-31","total_m3":120.567,"meter_datetime":"2022-09-15 19:08","status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'AnotherQWater;66666666;OK;120.567;1111-11-11 11:11.11'
}
test {
args = 'YetAnoter qwaterv2 33333333 NOKEY'
telegram = 3C449344333333333537723333333393443506B8000020_0C13350000004C1300000000426CBF2CCC081300000000C2086CDF25326CFFFF046D0516CE262
json = '{"_":"telegram","media":"warm water","meter":"qwaterv2","name":"YetAnoter","id":"33333333","status":"OK","total_m3":0.035,"target_year_m3":0,"target_year_date":"2021-12-31","target_m3":0,"target_date":"2022-05-31","device_error_date":"2128-03-31","meter_datetime":"2022-06-14 22:05","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'YetAnoter;33333333;OK;0.035;1111-11-11 11:11.11'
}
test {
args = 'QWater-7-18 qwaterv2 12230094 NOKEY'
telegram = 394493449400231218077ad30000200c13536712004c1307920500426cBf2ccc081373621200c2086cde2B02BB560000326cffff046d3714c32c
json = '{"_":"telegram","media":"water","meter":"qwaterv2","name":"QWater-7-18","id":"12230094","status":"OK","total_m3":126.753,"target_year_m3":59.207,"target_year_date":"2021-12-31","target_m3":126.273,"target_date":"2022-11-30","device_error_date":"2128-03-31","volume_flow_m3h":0,"meter_datetime":"2022-12-03 20:55","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'QWater-7-18;12230094;OK;126.753;1111-11-11 11:11.11'
}
test {
args = 'QWoo qwaterv2 13144514 NOKEY'
coment = 'Warm water'
telegram = 394493441445141316067A31000020_0C13671605004C1348160500426CDF2CCC081348160500C2086CDF2C02BB560000326CFFFF046D3414E121
json = '{"_":"telegram","target_date": "2022-12-31","target_m3": 51.648,"target_year_date": "2022-12-31","target_year_m3": 51.648,"device_error_date": "2128-03-31","id": "13144514","media": "warm water","meter": "qwaterv2","meter_datetime": "2023-01-01 20:52","name": "QWoo","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 51.667,"volume_flow_m3h": 0}'
fields = 'QWoo;13144514;OK;51.667;1111-11-11 11:11.11'
}
test {
args = 'QWooo qwaterv2 13176890 NOKEY'
comment = 'Cold water'
telegram = 394493449068171316077A0B000020_0C13358612004C1307851200426CDF2CCC081307851200C2086CDF2C02BB560000326CFFFF046D3014E121
json = '{"_":"telegram","target_date": "2022-12-31","target_m3": 128.507,"target_year_date": "2022-12-31","target_year_m3": 128.507,"device_error_date": "2128-03-31","id": "13176890","media": "water","meter": "qwaterv2","meter_datetime": "2023-01-01 20:48","name": "QWooo","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 128.635,"volume_flow_m3h": 0}'
fields = 'QWooo;13176890;OK;128.635;1111-11-11 11:11.11'
}
test {
args = 'QWooo qwaterv2 78563412 NOKEY'
comment = 'Proprietary Q walk-by message'
telegram = 49449344123456781606780DFF5F3500824E00007F0007C113FFFF63961300DF2C82731200FE2463811300A400F200D100A900DD00E000E90006011601EA0027010F012F046D0211F225
json = '{"_":"telegram","id": "78563412","media": "warm water","meter": "qwaterv2","meter_datetime": "2023-05-18 17:02","name": "QWooo","status": "OK","target_date": "2023-04-30","target_m3": 138.163,"target_year_date": "2022-12-31","target_year_m3": 127.382,"timestamp": "1111-11-11T11:11:11Z","total_m3": 139.663,"volume_delta_2_m3":0.164,"volume_delta_3_m3":0.242,"volume_delta_4_m3":0.209,"volume_delta_5_m3":0.169,"volume_delta_6_m3":0.221,"volume_delta_7_m3":0.224,"volume_delta_8_m3":0.233,"volume_delta_9_m3":0.262,"volume_delta_10_m3":0.278,"volume_delta_11_m3":0.234,"volume_delta_12_m3":0.295,"volume_delta_13_m3":0.271}'
fields = 'QWooo;78563412;OK;139.663;1111-11-11 11:11.11'
}
test {
args = 'QWaaa qwater 51220588 NOKEY'
telegram = 4944934488052251190778_0DFF5F350082930000810007C113FFFF91670400FF2C265402001E34332204000000EE00F201A501DB01C1015401B70178019701B901C9012F046D06091D35
json = '{"_":"telegram","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}'
fields = 'QWaaa;51220588;46.791;25.426;2023-12-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QWccc qwater 13492674 NOKEY'
telegram = 394493447426491317077ADD0000200C13975710004C1330970700426CFF2CCC081387471000C2086C1E3B02BB560000326CFFFF046D1E0F113C
json = '{"_": "telegram","due_17_date": "2024-11-30","due_17_date_m3": 104.787,"due_date": "2023-12-31","due_date_m3": 79.73,"error_date": "2128-03-31","id": "13492674","media": "water","meter": "qwater","meter_datetime": "2024-12-17 15:30","name": "QWccc","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 105.797,"volume_flow_m3h": 0}'
fields = 'QWccc;13492674;105.797;79.73;2023-12-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QWddd qwater 13334995 NOKEY'
telegram = 49449344954933131706780DFF5F3500823A0000600107C113FFFF29970300FF2C580303001E3B269703000A006500750073005B0070007D0061005B004200160000002F046D1E0F113C
json = '{"_": "telegram","due_17_date": "2024-11-30","due_17_date_m3": 39.726,"due_date": "2023-12-31","due_date_m3": 30.358,"id": "13334995","media": "warm water","meter": "qwater","meter_datetime": "2024-12-17 15:30","name": "QWddd","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 39.729}'
fields = 'QWddd;13334995;39.729;30.358;2023-12-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ1 qwater 37439212 NOKEY'
telegram = 5344934412924337353778077912924337934435070DFF5F3500828A0000100007C113FFFF966600001F3C000000003E3419580000008000800080008000800080008000005A0094009C00BB002F046D010F3235
json = '{"_": "telegram","due_17_date": "2025-04-30","due_17_date_m3": 5.819,"due_date": "2024-12-31","due_date_m3": 0,"id": "37439212","media": "radio converter (meter side)","meter": "qwater","meter_datetime": "2025-05-18 15:01","name": "QQ1","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 6.696}'
fields = 'QQ1;37439212;6.696;0;2024-12-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ2 qwater 37432649 NOKEY'
telegram = 5344934449264337353778077949264337934435070DFF5F350082560000110007C113FFFF245300001F3C210400003E348946000000800080008000800080008000002A0066005F00730072002F046D000F3235
json = '{"_": "telegram","due_17_date": "2025-04-30","due_17_date_m3": 4.689,"due_date": "2024-12-31","due_date_m3": 0.421,"id": "37432649","media": "radio converter (meter side)","meter": "qwater","meter_datetime": "2025-05-18 15:00","name": "QQ2","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 5.324}'
fields = 'QQ2;37432649;5.324;0.421;2024-12-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ3 qwater 60101441 NOKEY'
telegram = 39449344411410601A067ADB000020_0C13780000004C1300000000426CFFFFCC081335000000C2086C3F3502BB560000326CFFFF046D14173136
json = '{"_": "telegram","due_17_date": "2025-05-31","due_17_date_m3": 0.035,"due_date": "2128-03-31","due_date_m3": 0,"error_date": "2128-03-31","id": "60101441","media": "warm water","meter": "qwater","meter_datetime": "2025-06-17 23:20","name": "QQ3","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 0.078,"volume_flow_m3h": 0}'
fields = 'QQ3;60101441;0.078;0;2128-03-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ4 qwater 60113189 NOKEY'
telegram = 39449344893111601a077a580000200c13200300004c1300000000426cffffcc081334000000c2086c3f3502BB560000326cffff046d13173136
json = '{"_": "telegram","due_17_date": "2025-05-31","due_17_date_m3": 0.034,"due_date": "2128-03-31","due_date_m3": 0,"error_date": "2128-03-31","id": "60113189","media": "water","meter": "qwater","meter_datetime": "2025-06-17 23:19","name": "QQ4","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 0.32,"volume_flow_m3h": 0}'
fields = 'QQ4;60113189;0.32;0;2128-03-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ5 qwater 61193115 NOKEY'
comment = 'Qundis Qwater5.5 Model 2026 (warm water)'
telegram = 39449344153119611D067A870000200C13370000004C1300000000426CFFFFCC081300000000C2086CFFFF02BB560000326CFFFF046D320D5E31
json = '{"_": "telegram","due_17_date": "2128-03-31","due_17_date_m3": 0,"due_date": "2128-03-31","due_date_m3": 0,"error_date": "2128-03-31","id": "61193115","media": "warm water","meter": "qwater","meter_datetime": "2026-01-30 13:50","name": "QQ5","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 0.037,"volume_flow_m3h": 0}'
fields = 'QQ5;61193115;0.037;0;2128-03-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ5 qwater 61193115 NOKEY'
telegram = 49449344153119611D06780DFF5F3500826E0000F00007C113FFFF66000000FFFF00000000FFFF000000000080008000800080008000800080008000800080008000802F046D33125F31
json = '{"_": "telegram","due_17_date": "2128-03-31","due_17_date_m3": 0,"due_date": "2128-03-31","due_date_m3": 0,"id": "61193115","media": "warm water","meter": "qwater","meter_datetime": "2026-01-31 18:51","name": "QQ5","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 0.066}'
fields = 'QQ5;61193115;0.066;0;2128-03-31;OK;1111-11-11 11:11.11'
}
test {
args = 'QQ5 qwater 61193115 NOKEY'
telegram = 49449344153119611D06780DFF5F350082EC0000F10007C113FFFF69000000FFFF000000005F31680000000080008000800080008000800080008000800080008006002F046D1C0A4132
json = '{"_": "telegram","due_17_date": "2026-01-31","due_17_date_m3": 0.068,"due_date": "2128-03-31","due_date_m3": 0,"id": "61193115","media": "warm water","meter": "qwater","meter_datetime": "2026-02-01 10:28","name": "QQ5","status": "OK","timestamp": "1111-11-11T11:11:11Z","total_m3": 0.069}'
fields = 'QQ5;61193115;0.069;0;2128-03-31;OK;1111-11-11 11:11.11'
}
}
}