/* Copyright (C) 2025 obidobi (gpl-3.0-or-later)
   Copyright (C) 2025 Fredrik Öhrström (gpl-3.0-or-later)

   Elvaco Sense 100W,200W,300W

   Datasheet (V1.0, 2023-11):
     • C = 0x44, Manufacturer = ELV (0x1596), Version = 0x50..0x54
     • Medium = 0x1B (Room sensor), App header = 0x7A (short)
     • Battery: DIF 0x02 / VIF 0xFD / VIFE 0x46  → u16 mV (bytes 20..21)
     • Temperature: DIF 0x02 / VIF 0x65         → s16/100 °C (bytes 24..25)

   Notes:
     • Designed for unencrypted C1a; will decode C1b/T1 unencrypted too.
     • Built/tested against wmbusmeters 1.17.1-29-g3af7a4c. */
driver {
    name           = elvsense
    default_fields = name,id,temperature_c,humidity_rh,co2_ppm,battery_v,status,timestamp
    meter_type     = TempHygroMeter
    detect {
        // Manufacturer ELV (0x1596), VERSION 0x50..0x54, TYPE 0x1B (room sensor 100W)
        mvt = ELV,50,1b
        mvt = ELV,51,1b
        mvt = ELV,52,1b
        mvt = ELV,53,1b
        mvt = ELV,54,1b
        // Manufacturer ELV (0x1596), VERSION 85d..89d, TYPE 0x1B (room sensor 200W)
        // Manufacturer ELV (0x1596), VERSION 90d..94d, TYPE 0x1B (room sensor 300W)
    }
    fields {
        field {
            name     = temperature
            quantity = Temperature
            info     = 'Instantaneous room temperature.'
            match {
                measurement_type = Instantaneous
                vif_range        = ExternalTemperature
            }
        }
        field {
            name     = battery
            quantity = Voltage
            info     = 'Battery voltage.'
            // unit is added automatically from quantity/VIF (Volts)
            match {
                measurement_type = Instantaneous
                vif_range        = Voltage
            }
        }
        field {
            name     = humidity
            quantity = RelativeHumidity
            info     = 'Relative humidity for 200W and 300W meters'
            match {
                measurement_type = Instantaneous
                vif_range        = RelativeHumidity
            }
        }
        field {
            name         = co2
            quantity     = Dimensionless
            info         = 'CO2 concentration ppm for 300W meters'
            vif_scaling  = None
            display_unit = ppm
            match {
                difvifkey = 027C03324F43
            }
        }
        field {
            name       = status
            quantity   = Text
            info       = 'Sensor status and error flags.'
            attributes = STATUS,INCLUDE_TPL_STATUS
        }
    }
    tests {
        test {
            args     = 'ES1 elvsense 80008957 NOKEY'
            telegram = 1844961557890080501B7aea00012002656f0802fd46610e0f
            json     = '{"_": "telegram","battery_v": 3.681,"id": "80008957","media": "room sensor","meter": "elvsense","name": "ES1","status": "OK","temperature_c": 21.59,"timestamp": "1111-11-11T11:11:11Z"}'
            fields   = 'ES1;80008957;21.59;null;null;3.681;OK;1111-11-11 11:11.11'
        }
        test {
            args     = 'ES2 elvsense 80008957 NOKEY'
            telegram = 1e44961557890080501B7aff0010252f2f0265680802fd46630e0f2f2f2f2f
            json     = '{"_": "telegram","battery_v": 3.683,"id": "80008957","media": "room sensor","meter": "elvsense","name": "ES2","status": "OK","temperature_c": 21.52,"timestamp": "1111-11-11T11:11:11Z"}'
            fields   = 'ES2;80008957;21.52;null;null;3.683;OK;1111-11-11 11:11.11'
        }
        test {
            args     = 'FAKE elvsense 80008958 NOKEY'
            comment  = 'This is a fake meter to test ppm and named vif CO2. But 300W probably looks similar.'
            telegram = 2b44961558890080501B7aff0010252f2f_02656808_02fd46630e_02fb1a0700_027c03324f430001_0f2f2f2f2f
            json     = '{"_": "telegram","battery_v": 3.683,"co2_ppm": 256,"humidity_rh": 0.7,"id": "80008958","media": "room sensor","meter": "elvsense","name": "FAKE","status": "OK","temperature_c": 21.52,"timestamp": "1111-11-11T11:11:11Z"}'
            fields   = 'FAKE;80008958;21.52;0.7;256;3.683;OK;1111-11-11 11:11.11'
        }
    }
}