/* Copyright (C) 2022-2026 Fredrik Öhrström (gpl-3.0-or-later)
   Copyright (C) 2022 Alexander Streit (gpl-3.0-or-later) */
driver {
    name           = c5isf
    meter_type     = HeatMeter
    default_fields = name,id,total_energy_consumption_kwh,total_volume_m3,status,timestamp
    detect {
        mvt = ZRI,88,0d
        mvt = ZRI,88,07
        mvt = ZRI,88,04
    }
    fields {
        // Common fields for T1A1, T1A2, T1B
        field {
            name     = total_energy_consumption
            quantity = Energy
            info     = 'The total heat energy consumption recorded by this meter.'
            match {
                measurement_type = Instantaneous
                vif_range        = AnyEnergyVIF
            }
        }
        field {
            name     = total_cooling_consumption
            quantity = Energy
            info     = 'The total cooling energy consumption recorded by this meter.'
            match {
                measurement_type = Instantaneous
                vif_range        = AnyEnergyVIF
                tariff_nr        = 1
            }
        }
        field {
            name     = total_volume
            quantity = Volume
            info     = 'The total heating media volume recorded by this meter.'
            match {
                measurement_type = Instantaneous
                vif_range        = Volume
            }
        }
        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        = DecimalsToString
                mask_bits       = 9999
                default_message = OK
                map {
                    name  = VERIFICATION_EXPIRED
                    value = 2000
                    test  = Set
                }
                map {
                    name  = BATTERY_EXPIRED
                    value = 1000
                    test  = Set
                }
                map {
                    name  = WIRELESS_ERROR
                    value = 800
                    test  = Set
                }
                map {
                    name  = HARDWARE_ERROR3
                    value = 100
                    test  = Set
                }
                map {
                    name  = VALUE_OVERLOAD
                    value = 50
                    test  = Set
                }
                map {
                    name  = AIR_INSIDE
                    value = 40
                    test  = Set
                }
                map {
                    name  = REVERSE_FLOW
                    value = 30
                    test  = Set
                }
                map {
                    name  = DRY
                    value = 20
                    test  = Set
                }
                map {
                    name  = ERROR_MEASURING
                    value = 10
                    test  = Set
                }
                map {
                    name  = HARDWARE_ERROR2
                    value = 9
                    test  = Set
                }
                map {
                    name  = HARDWARE_ERROR1
                    value = 8
                    test  = Set
                }
                map {
                    name  = LOW_BATTERY
                    value = 7
                    test  = Set
                }
                map {
                    name  = SUPPLY_SENSOR_INTERRUPTED
                    value = 6
                    test  = Set
                }
                map {
                    name  = SHORT_CIRCUIT_SUPPLY_SENSOR
                    value = 5
                    test  = Set
                }
                map {
                    name  = RETURN_SENSOR_INTERRUPTED
                    value = 4
                    test  = Set
                }
                map {
                    name  = SHORT_CIRCUIT_RETURN_SENSOR
                    value = 3
                    test  = Set
                }
                map {
                    name  = TEMP_ABOVE_RANGE
                    value = 2
                    test  = Set
                }
                map {
                    name  = TEMP_BELOW_RANGE
                    value = 1
                    test  = Set
                }
            }
        }
        // Previous month dates (T1A1 and T1A2, storage 32-45)
        field {
            name         = 'prev_{storage_counter-31counter}_month'
            quantity     = PointInTime
            info         = 'Previous month date.'
            display_unit = date
            match {
                measurement_type = Instantaneous
                vif_range        = Date
                storage_nr       = 32,45
            }
        }
        // Previous month energy (T1A1, storage 32-45)
        field {
            name     = 'prev_{storage_counter-31counter}_month'
            quantity = Energy
            info     = 'Previous month energy.'
            match {
                measurement_type = Instantaneous
                vif_range        = AnyEnergyVIF
                storage_nr       = 32,45
            }
        }
        // Previous month volume (T1A2, storage 32-45)
        field {
            name     = 'prev_{storage_counter-31counter}_month'
            quantity = Volume
            info     = 'Previous month volume.'
            match {
                measurement_type = Instantaneous
                vif_range        = Volume
                storage_nr       = 32,45
            }
        }
        // T1B billing fields
        field {
            name     = due_energy_consumption
            quantity = Energy
            info     = 'The total heat energy consumption at the due date.'
            match {
                measurement_type = Instantaneous
                vif_range        = AnyEnergyVIF
                storage_nr       = 8
            }
        }
        field {
            name         = due
            quantity     = PointInTime
            info         = 'The due date.'
            display_unit = date
            match {
                measurement_type = Instantaneous
                vif_range        = Date
                storage_nr       = 8
            }
        }
        field {
            name     = volume_flow
            quantity = Flow
            info     = 'The current heat media volume flow.'
            match {
                measurement_type = Instantaneous
                vif_range        = VolumeFlow
            }
        }
        field {
            name     = power
            quantity = Power
            info     = 'The current power consumption.'
            match {
                measurement_type = Instantaneous
                vif_range        = PowerW
            }
        }
        field {
            name     = total_energy_consumption_last_month
            quantity = Energy
            info     = 'The total heat energy consumption recorded at end of last month.'
            match {
                measurement_type = Instantaneous
                vif_range        = AnyEnergyVIF
                storage_nr       = 32
            }
        }
        field {
            name     = last_month
            quantity = PointInTime
            info     = 'Last month date and time.'
            match {
                measurement_type = Instantaneous
                vif_range        = DateTime
            }
        }
        field {
            name     = max_power_last_month
            quantity = Power
            info     = 'Maximum power consumption last month.'
            match {
                measurement_type = Maximum
                vif_range        = PowerW
                storage_nr       = 32
                add_combinable   = PerMonth
            }
        }
        field {
            name     = flow_temperature
            quantity = Temperature
            info     = 'The current forward heat media temperature.'
            match {
                measurement_type = Instantaneous
                vif_range        = FlowTemperature
            }
        }
        field {
            name     = return_temperature
            quantity = Temperature
            info     = 'The current return heat media temperature.'
            match {
                measurement_type = Instantaneous
                vif_range        = ReturnTemperature
            }
        }
    }
    tests {
        test {
            args     = 'Heat c5isf 55445555 NOKEY'
            telegram = E544496A55554455880D7A320200002F2F_04060000000004130000000002FD17240084800106000000008280016C2124C480010600000080C280016CFFFF84810106000000808281016CFFFFC481010600000080C281016CFFFF84820106000000808282016CFFFFC482010600000080C282016CFFFF84830106000000808283016CFFFFC483010600000080C283016CFFFF84840106000000808284016CFFFFC484010600000080C284016CFFFF84850106000000808285016CFFFFC485010600000080C285016CFFFF84860106000000808286016CFFFFC486010600000080C286016CFFFF
            json     = '{"_":"telegram","media":"heat/cooling load","meter":"c5isf","name":"Heat","id":"55445555","prev_10_month_kwh":-2147483648,"prev_10_month_date":"2128-03-31","prev_11_month_kwh":-2147483648,"prev_11_month_date":"2128-03-31","prev_12_month_kwh":-2147483648,"prev_12_month_date":"2128-03-31","prev_13_month_kwh":-2147483648,"prev_13_month_date":"2128-03-31","prev_14_month_kwh":-2147483648,"prev_14_month_date":"2128-03-31","prev_1_month_kwh":0,"prev_1_month_date":"2017-04-01","prev_2_month_kwh":-2147483648,"prev_2_month_date":"2128-03-31","prev_3_month_kwh":-2147483648,"prev_3_month_date":"2128-03-31","prev_4_month_kwh":-2147483648,"prev_4_month_date":"2128-03-31","prev_5_month_kwh":-2147483648,"prev_5_month_date":"2128-03-31","prev_6_month_kwh":-2147483648,"prev_6_month_date":"2128-03-31","prev_7_month_kwh":-2147483648,"prev_7_month_date":"2128-03-31","prev_8_month_kwh":-2147483648,"prev_8_month_date":"2128-03-31","prev_9_month_kwh":-2147483648,"prev_9_month_date":"2128-03-31","total_energy_consumption_kwh":0,"total_energy_consumption_last_month_kwh":0,"total_volume_m3":0,"status":"DRY ERROR RETURN_SENSOR_INTERRUPTED","timestamp":"1111-11-11T11:11:11Z"}'
            fields   = 'Heat;55445555;0;0;DRY ERROR RETURN_SENSOR_INTERRUPTED;1111-11-11 11:11.11'
        }
        test {
            args     = 'Heat c5isf 32002044 NOKEY'
            telegram = 5E44496A4420003288047AFC0050052F2F_0406D00E00000413B28A05008404060000000082046CC121043B00000000042D000000000259E719025D051402FD17000084800106C00C00008280016CC125948001AE25090000002F2F2F2F2F2F
            json     = '{"_":"telegram","media":"heat","meter":"c5isf","name":"Heat","id":"32002044","due_date":"2022-01-01","due_energy_consumption_kwh":0,"flow_temperature_c":66.31,"max_power_last_month_kw":9,"power_kw":0,"prev_1_month_kwh":3264,"prev_1_month_date":"2022-05-01","return_temperature_c":51.25,"total_energy_consumption_kwh":3792,"total_energy_consumption_last_month_kwh":3264,"total_volume_m3":363.186,"volume_flow_m3h":0,"status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
            fields   = 'Heat;32002044;3792;363.186;OK;1111-11-11 11:11.11'
        }
        test {
            args     = 'HeatCool c5isf 32022703 NOKEY'
            telegram = 8E44496A03270232880D7AED0080052F2F0406050200008410069A1700000413BC6F2E00840406E701000082046C2131841406C20B000082146C2131043B00000000042D0000000002595D09025D240802FD17000084800106050200008280016C213C948001AE2501000000849001069A1700008290016C213C849001AE25000000002F2F2F2F2F2F2F2F2F2F2F2F
            json     = '{"_":"telegram","media":"heat/cooling load","meter":"c5isf","name":"HeatCool","id":"32022703","due_date":"2025-01-01","due_energy_consumption_kwh":487,"flow_temperature_c":23.97,"max_power_last_month_kw":1,"power_kw":0,"prev_1_month_kwh":517,"prev_1_month_date":"2025-12-01","return_temperature_c":20.84,"total_cooling_consumption_kwh":6042,"total_energy_consumption_kwh":517,"total_energy_consumption_last_month_kwh":517,"total_volume_m3":3043.26,"volume_flow_m3h":0,"status":"OK","timestamp":"1111-11-11T11:11:11Z"}'
            fields   = 'HeatCool;32022703;517;3043.26;OK;1111-11-11 11:11.11'
        }
    }
}