// Copyright (C) 2019 Jacek Tomasiak (gpl-3.0-or-later)
// Copyright (C) 2020-2025 Fredrik Öhrström (gpl-3.0-or-later)
// Copyright (C) 2021 Vincent Privat (gpl-3.0-or-later)
driver {
name = izarv2
meter_type = WaterMeter
default_fields = name,id,status,total_m3,target_m3,timestamp
manufacturer = Diehl
transform_payload = diehl_prios
detect {
mvt = HYD,85,07
mvt = SAP,*,15
mvt = SAP,*,04
mvt = SAP,00,07
mvt = DME,78,07
mvt = DME,78,06
mvt = HYD,86,07
}
fields {
field {
name = prefix
quantity = Text
info = 'The alphanumeric prefix printed before serial number on device.'
}
field {
name = serial_number
quantity = Text
info = 'The meter serial number.'
}
field {
name = manufacture_y
quantity = Text
info = 'The year during which the meter was manufactured.'
}
field {
name = prios_decoder
quantity = Text
attributes = HIDE
match_entire_payload = true
ixml = "decode = with_billing | without_billing.
with_billing = alarms_hdr, -skip_byte, -check, volume, billing_block, -byte*.
without_billing = alarms_hdr, -skip_byte, -check, volume.
alarms_hdr = byte, byte, byte, @DV_alarms.
-skip_byte = byte.
-check = byte.
volume = byte, byte, byte, byte, @DV_total.
billing_block = last_month, date.
last_month = byte, byte, byte, byte, @DV_last_month.
date = byte, byte, @DV_date.
-hex = ['A'-'F'; '0'-'9'].
-byte = hex, hex.
DV_alarms>dvk = +'036C'.
DV_total>dvk = +'0413'.
DV_last_month>dvk = +'4413'.
DV_date>dvk = +'026C'."
}
field {
name = total
quantity = Volume
info = 'The total water consumption recorded by this meter.'
match {
difvifkey = 0413
}
}
field {
name = target
quantity = Volume
info = 'The total water consumption recorded at the end of last month.'
match {
difvifkey = 4413
}
}
field {
name = status_raw
quantity = Dimensionless
attributes = HIDE
match {
difvifkey = 036C
}
}
field {
name = tx_raw
quantity = Dimensionless
attributes = HIDE
calculate = 'status_raw_counter & 15counter'
}
field {
name = bat_raw
quantity = Dimensionless
attributes = HIDE
calculate = '(status_raw_counter >> 8counter) & 31counter'
}
field {
name = target_date_raw
quantity = Dimensionless
attributes = HIDE
match {
difvifkey = 026C
}
}
field {
name = target_date_day
quantity = Dimensionless
attributes = HIDE
calculate = 'target_date_raw_counter % 32counter'
match {
difvifkey = 026C
}
}
field {
name = target_date_month
quantity = Dimensionless
attributes = HIDE
calculate = '(target_date_raw_counter >> 8counter) % 16counter'
match {
difvifkey = 026C
}
}
field {
name = target_date_year_offset
quantity = Dimensionless
attributes = HIDE
calculate = '((((target_date_raw_counter >> 8counter) & 240counter) >> 1counter) + ((target_date_raw_counter >> 5counter) % 8counter))'
match {
difvifkey = 026C
}
}
field {
name = target_date_year_adjusted
quantity = Dimensionless
attributes = HIDE
calculate = 'target_date_year_offset_counter - ((target_date_year_offset_counter > 80counter) * 100counter)'
match {
difvifkey = 026C
}
}
field {
name = target_date_month_offset
quantity = Dimensionless
attributes = HIDE
calculate = '(target_date_year_adjusted_counter * 12counter) + target_date_month_counter - 1counter'
match {
difvifkey = 026C
}
}
field {
name = target
quantity = PointInTime
display_unit = date
info = 'The date when the meter recorded the most recent billing value.'
calculate = "'2000-01-01' +
(target_date_month_offset_counter * 1month) +
((target_date_day_counter - 1counter) * 24h)"
match {
difvifkey = 026C
}
}
field {
name = battery
quantity = Time
display_unit = y
info = 'How many more years the battery is expected to last.'
calculate = 'bat_raw_counter * 0.5y'
}
field {
name = transmit_period
quantity = Time
display_unit = s
info = 'The period at which the meter transmits its data.'
calculate = '(1counter << (tx_raw_counter + 2counter)) * 1s'
}
field {
name = status
quantity = Text
info = 'Current and previous alarms reported by the meter.'
match {
difvifkey = 036C
}
lookup {
name = ALARMS
map_type = BitToString
mask_bits = 0xFFE000
default_message = OK
map {
name = LEAKAGE
value = 0x008000
test = Set
}
map {
name = METER_BLOCKED
value = 0x002000
test = Set
}
map {
name = BACK_FLOW
value = 0x800000
test = Set
}
map {
name = UNDERFLOW
value = 0x400000
test = Set
}
map {
name = OVERFLOW
value = 0x200000
test = Set
}
map {
name = SUBMARINE
value = 0x100000
test = Set
}
map {
name = SENSOR_FRAUD
value = 0x080000
test = Set
}
map {
name = MECHANICAL_FRAUD
value = 0x020000
test = Set
}
map {
name = PREV_LEAKAGE
value = 0x004000
test = Set
}
map {
name = PREV_SENSOR_FRAUD
value = 0x040000
test = Set
}
map {
name = PREV_MECHANICAL_FRAUD
value = 0x010000
test = Set
}
}
}
}
tests {
test {
comment = 'HYD meter with SAP_PRIOS encoding: prefix, serial, manufacture_y present'
args = 'IzarWater izarv2 21242472 NOKEY'
telegram = 1944304C72242421D401A2_013D4013DD8B46A4999C1293E582CC
json = '{"_":"telegram","media":"water","meter":"izarv2","name":"IzarWater","id":"21242472","prefix":"C19UA","serial_number":"145842","manufacture_y":"2019","total_m3":3.488,"target_m3":3.486,"target_date":"2019-09-30","battery_y":14.5,"transmit_period_s":8,"status":"METER_BLOCKED UNDERFLOW","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'IzarWater;21242472;METER_BLOCKED UNDERFLOW;3.488;3.486;1111-11-11 11:11.11'
}
test {
comment = 'SAP meter with PRIOS encoding: no prefix/serial/manufacture_y'
args = 'IzarWater2 izarv2 66236629 NOKEY'
telegram = 2944A511780729662366A20118001378D3B3DB8CEDD77731F25832AAF3DA8CADF9774EA673172E8C61F2
json = '{"_":"telegram","media":"water","meter":"izarv2","name":"IzarWater2","id":"66236629","total_m3":16.76,"target_m3":11.84,"target_date":"2019-11-30","battery_y":12,"transmit_period_s":8,"status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'IzarWater2;66236629;OK;16.76;11.84;1111-11-11 11:11.11'
}
test {
comment = 'SAP meter version 0x78'
args = 'IzarWater3 izarv2 20481979 NOKEY'
telegram = 1944A511780779194820A1_21170013355F8EDB2D03C6912B1E37
json = '{"_":"telegram","media":"water","meter":"izarv2","name":"IzarWater3","id":"20481979","total_m3":4.366,"target_m3":0,"target_date":"2020-12-31","battery_y":11.5,"transmit_period_s":8,"status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'IzarWater3;20481979;OK;4.366;0;1111-11-11 11:11.11'
}
test {
comment = 'HYD meter with mfct specific tpl ci field a3'
args = 'IzarWater4 izarv2 2124589c NOKEY'
telegram = 1944304c9c5824210c04a363140013716577ec59e8663ab0d31c
json = '{"_":"telegram","media":"water","meter":"izarv2","name":"IzarWater4","id":"2124589c","prefix":"H19CA","serial_number":"159196","manufacture_y":"2019","total_m3":38.944,"target_m3":38.691,"target_date":"2021-02-01","battery_y":10,"transmit_period_s":32,"status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'IzarWater4;2124589c;OK;38.944;38.691;1111-11-11 11:11.11'
}
test {
comment = 'Ensure non-regression on manufacture year parsing'
args = 'IzarWater5 izarv2 20e4ffde NOKEY'
telegram = 1944304CDEFFE420CC01A2_63120013258F907B0AFF12529AC33B
json = '{"_":"telegram","media":"water","meter":"izarv2","name":"IzarWater5","id":"20e4ffde","prefix":"C15SA","serial_number":"007710","manufacture_y":"2015","total_m3":159.832,"target_m3":157.76,"target_date":"2021-02-01","battery_y":9,"transmit_period_s":32,"status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'IzarWater5;20e4ffde;OK;159.832;157.76;1111-11-11 11:11.11'
}
test {
comment = 'SAP meter with previous leakage alarm'
args = 'IzarWater6 izarv2 48500375 NOKEY'
telegram = 19442423860775035048A251520015BEB6B2E1ED623A18FC74A5
json = '{"_":"telegram","media":"water","meter":"izarv2","name":"IzarWater6","id":"48500375","total_m3":521.602,"target_m3":519.147,"target_date":"2021-11-15","battery_y":9,"transmit_period_s":8,"status":"PREV_LEAKAGE","timestamp":"1111-11-11T11:11:11Z"}'
fields = 'IzarWater6;48500375;PREV_LEAKAGE;521.602;519.147;1111-11-11 11:11.11'
}
}
}