"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.specificDeviceClass = exports.genericDeviceClass = exports.genericDeviceClassAttributes = exports.commandClass = exports.sensorType = exports._sensorMap = exports.meterType = exports.productionType = exports.deviceClass = void 0;
const core_1 = require("@zwave-js/core");
// https://github.com/OpenZWave/open-zwave/blob/0d94c9427bbd19e47457578bccc60b16c6679b49/config/Localization.xml#L606
const _productionMap = {
    0: 'instant',
    1: 'total',
    2: 'today',
    3: 'time',
};
exports.deviceClass = {
    sensor_binary: {
        BATTERY: 'battery',
        COLD: 'cold',
        CONNECTIVITY: 'connectivity',
        DOOR: 'door',
        GARAGE_DOOR: 'garage_door',
        GAS: 'gas',
        HEAT: 'heat',
        LIGHT: 'light',
        LOCK: 'lock',
        MOISTURE: 'moisture',
        MOTION: 'motion',
        MOVING: 'moving',
        OCCUPANCY: 'occupancy',
        OPENING: 'opening',
        PLUG: 'plug',
        POWER: 'power',
        PRESENCE: 'presence',
        PROBLEM: 'problem',
        SAFETY: 'safety',
        SMOKE: 'smoke',
        SOUND: 'sound',
        VIBRATION: 'vibration',
        WINDOW: 'window',
    },
    sensor: {
        BATTERY: 'battery',
        HUMIDITY: 'humidity',
        ILLUMINANCE: 'illuminance',
        SIGNAL_STRENGTH: 'signal_strength',
        TEMPERATURE: 'temperature',
        POWER: 'power',
        POWER_FACTOR: 'power_factor',
        PRESSURE: 'pressure',
        TIMESTAMP: 'timestamp',
        CURRENT: 'current',
        ENERGY: 'energy',
        VOLTAGE: 'voltage',
    },
    cover: {
        AWNING: 'awning',
        BLIND: 'blind',
        CURTAIN: 'curtain',
        DAMPER: 'damper',
        DOOR: 'door',
        GARAGE: 'garage',
        GATE: 'gate',
        SHADE: 'shade',
        SHUTTER: 'shutter',
        WINDOW: 'window',
    },
};
function productionType(index) {
    return {
        sensor: 'energy_production',
        objectId: _productionMap[index] || 'unknown',
        props: {
            device_class: index === 3 ? 'timestamp' : 'power',
        },
    };
}
exports.productionType = productionType;
function meterType(ccSpecific) {
    const meter = (0, core_1.getMeter)(ccSpecific.meterType);
    const scale = (0, core_1.getMeterScale)(ccSpecific.meterType, ccSpecific.scale);
    const cfg = {
        sensor: meter?.name || 'unknown',
        objectId: scale?.label || `unknown${ccSpecific.scale}`,
        props: {},
    };
    // https://github.com/zwave-js/node-zwave-js/blob/master/packages/config/config/meters.json
    switch (ccSpecific.meterType) {
        case 0x01: // electric
            switch (ccSpecific.scale) {
                case 0x00: // kWh
                    cfg.props = {
                        state_class: 'total_increasing',
                        device_class: 'energy',
                    };
                    break;
                case 0x02: // W
                    cfg.props = {
                        state_class: 'measurement',
                        device_class: 'power',
                    };
                    break;
                case 0x04: // V
                    cfg.props = {
                        state_class: 'measurement',
                        device_class: 'voltage',
                    };
                    break;
                case 0x05: // A
                    cfg.props = {
                        state_class: 'measurement',
                        device_class: 'current',
                    };
                    break;
                default:
                    cfg.props = {
                        device_class: 'power',
                    };
                    break;
            }
            break;
        case 0x02: // gas
            cfg.props = {
                icon: 'mdi:thought-bubble',
                device_class: 'gas',
            };
            break;
        case 0x03: // water
            cfg.props = {
                icon: 'mdi:water',
            };
            break;
        case 0x04: // heating
            cfg.props = {
                icon: 'mdi:fire',
            };
            break;
        case 0x05: // cooling
            cfg.props = {
                icon: 'mdi:snowflake',
            };
            break;
    }
    return cfg;
}
exports.meterType = meterType;
exports._sensorMap = {
    temperature: {
        1: 'air',
        11: 'dew_point',
        23: 'water',
        24: 'soil',
        34: 'target',
        62: 'boiler_water',
        63: 'domestic_hot_water',
        64: 'outside',
        65: 'exhaust',
        72: 'return_air',
        73: 'supply_air',
        74: 'condenser_coil',
        75: 'evaporator_coil',
        76: 'liquid_line',
        77: 'discharge_line',
        80: 'defrost',
        props: {
            state_class: 'measurement',
            device_class: 'temperature',
        },
    },
    illuminance: {
        3: '', // illuminance
        props: {
            state_class: 'measurement',
            device_class: 'illuminance',
            unit_of_measurement: 'lx',
        },
    },
    power: {
        4: 'power',
        props: {
            state_class: 'measurement',
            device_class: 'power',
        },
    },
    voltage: {
        15: 'voltage',
        props: {
            state_class: 'measurement',
            device_class: 'voltage',
        },
    },
    current: {
        16: 'current',
        props: {
            state_class: 'measurement',
            device_class: 'current',
        },
    },
    electricity: {
        28: 'resistivity',
        29: 'conductivity',
        props: {
            state_class: 'measurement',
            device_class: 'power',
        },
    },
    humidity: {
        5: 'air', // humidity
        41: 'soil',
        props: {
            state_class: 'measurement',
            device_class: 'humidity',
        },
    },
    speed: {
        6: 'velocity', // ?
        52: 'x_acceleration',
        53: 'y_acceleration',
        54: 'z_acceleration',
        props: {
            icon: 'mdi:speedometer',
        },
    },
    direction: {
        7: '', // direction
        21: 'angle_position', // ?
        props: {
            icon: 'mdi:compass',
        },
    },
    pressure: {
        8: 'atmospheric',
        9: 'barometric',
        57: 'water',
        props: {
            state_class: 'measurement',
            device_class: 'pressure',
        },
    },
    sun: {
        10: 'solar_radiation',
        27: 'ultraviolet',
        props: {
            icon: 'mdi:white-balance-sunny',
        },
    },
    water: {
        12: 'rain_rate',
        13: 'tide_level',
        19: 'tank_capacity',
        56: 'flow',
        props: {
            icon: 'mdi:water',
        },
    },
    weight: {
        14: '', // weight
        46: 'muscle_mass',
        47: 'bone_mass',
        48: 'fat_mass',
        49: 'total_body_water',
        51: 'body_mass_index',
        66: 'water_chlorine',
        67: 'water_acidity',
        68: 'water_oxidation_potential',
        props: {
            icon: 'mdi:weight',
        },
    },
    gas: {
        17: 'carbon_dioxide',
        40: 'carbon_monoxide',
        55: 'smoke_density',
        props: {
            icon: 'mdi:thought-bubble',
        },
    },
    air: {
        18: 'flow',
        props: {
            icon: 'mdi:air-filter',
        },
    },
    frequency: {
        22: 'rotation',
        32: '',
        props: {},
    },
    sound: {
        30: 'loudness',
        props: {
            icon: 'mdi:volume-high',
        },
    },
    signal: {
        58: 'strength',
        props: {
            state_class: 'measurement',
            device_class: 'signal_strength',
        },
    },
    timestamp: {
        33: '', // time,
        props: {
            device_class: 'timestamp',
        },
    },
    heart: {
        44: 'rate',
        45: 'blood_pressure',
        50: 'basic_metabolic_rate',
        60: 'respiratory_rate',
        69: 'lf_lh_ratio',
        props: {
            icon: 'mdi:heart',
        },
    },
    generic: {
        2: 'general_purpose',
        20: 'distance',
        25: 'seismic_intensity',
        26: 'seismic_magnitude',
        31: 'moisture',
        35: 'particulate_matter_25',
        36: 'formaldehyde',
        37: 'radon_concentration',
        38: 'methane_density',
        39: 'volatile_organic_compound',
        42: 'soil_reactivity',
        43: 'soil_salinity',
        59: 'particulate_matter',
        61: 'relative_modulation',
        70: 'motion_direction',
        71: 'applied_force',
        78: 'suction',
        79: 'discharge',
        81: 'ozone',
        82: 'sulfur_dioxide',
        83: 'nitrogen_dioxide',
        84: 'ammonia',
        85: 'lead',
        86: 'particulate_matter',
    },
};
function sensorType(index) {
    const sensorType = {
        sensor: 'generic',
        objectId: 'unknown_' + index,
        props: {},
    };
    for (const sensor in exports._sensorMap) {
        const objectId = exports._sensorMap[sensor][index];
        if (objectId !== undefined) {
            sensorType.sensor = sensor;
            sensorType.objectId = objectId;
            sensorType.props = exports._sensorMap[sensor].props || {};
            break;
        }
    }
    return sensorType;
}
exports.sensorType = sensorType;
const _commandClassMap = {
    0x00: 'no_operation',
    0x20: 'basic',
    0x21: 'controller_replication',
    0x22: 'application_status',
    0x23: 'zip_services',
    0x24: 'zip_server',
    0x25: 'switch_binary',
    0x26: 'switch_multilevel',
    0x27: 'switch_all',
    0x28: 'switch_toggle_binary',
    0x29: 'switch_toggle_multilevel',
    0x2a: 'chimney_fan',
    0x2b: 'scene_activation',
    0x2c: 'scene_actuator_conf',
    0x2d: 'scene_controller_conf',
    0x2e: 'zip_client',
    0x2f: 'zip_adv_services',
    0x30: 'sensor_binary',
    0x31: 'sensor_multilevel',
    0x32: 'meter',
    0x33: 'color',
    0x34: 'zip_adv_client',
    0x35: 'meter_pulse',
    0x3c: 'meter_tbl_config',
    0x3d: 'meter_tbl_monitor',
    0x3e: 'meter_tbl_pulse',
    0x38: 'thermostat_heating',
    0x40: 'thermostat_mode',
    0x42: 'thermostat_operating_state',
    0x43: 'thermostat_setpoint',
    0x44: 'thermostat_fan_mode',
    0x45: 'thermostat_fan_state',
    0x46: 'climate_control_schedule',
    0x47: 'thermostat_setback',
    0x4c: 'door_lock_logging',
    0x4e: 'schedule_entry_lock',
    0x50: 'basic_window_covering',
    0x51: 'mtp_window_covering',
    0x56: 'crc16_encap',
    0x5a: 'device_reset_locally',
    0x5b: 'central_scene',
    0x5e: 'zwave_plus_info',
    0x5d: 'antitheft',
    0x60: 'multi_instance',
    0x62: 'door_lock',
    0x63: 'user_code',
    0x66: 'barrier_operator',
    0x70: 'configuration',
    0x71: 'notification',
    0x72: 'manufacturer_specific',
    0x73: 'powerlevel',
    0x75: 'protection',
    0x76: 'lock',
    0x77: 'node_naming',
    0x79: 'sound_switch',
    0x7a: 'firmware_update_md',
    0x7b: 'grouping_name',
    0x7c: 'remote_association_activate',
    0x7d: 'remote_association',
    0x80: 'battery',
    0x81: 'clock',
    0x82: 'hail',
    0x84: 'wake_up',
    0x85: 'association',
    0x86: 'version',
    0x87: 'indicator',
    0x88: 'proprietary',
    0x89: 'language',
    0x8a: 'time',
    0x8b: 'time_parameters',
    0x8c: 'geographic_location',
    0x8d: 'composite',
    0x8e: 'multi_instance_association',
    0x8f: 'multi_cmd',
    0x90: 'energy_production',
    0x91: 'manufacturer_proprietary',
    0x92: 'screen_md',
    0x93: 'screen_attributes',
    0x94: 'simple_av_control',
    0x95: 'av_content_directory_md',
    0x96: 'av_renderer_status',
    0x97: 'av_content_search_md',
    0x98: 'security',
    0x99: 'av_tagging_md',
    0x9a: 'ip_configuration',
    0x9b: 'association_command_configuration',
    0x9c: 'sensor_alarm',
    0x9d: 'silence_alarm',
    0x9e: 'sensor_configuration',
    0xef: 'mark',
    0xf0: 'non_interoperable',
};
function commandClass(cmd) {
    return _commandClassMap[cmd] || `unknownClass_${cmd}`;
}
exports.commandClass = commandClass;
const _genericDeviceClassMap = {
    // https://github.com/OpenZWave/open-zwave/blob/master/config/device_classes.xml
    // https://github.com/home-assistant/core/blob/dev/homeassistant/components/zwave/const.py#L196
    // 0x00: specific_type_not_used // Available in all Generic types
    0x01: {
        generic: 'generic_type_generic_controller',
        specific: {
            0x01: 'specific_type_portable_controller',
            0x02: 'specific_type_portable_scene_controller',
            0x03: 'specific_type_portable_installer_tool',
            0x04: 'specific_type_control_av',
            0x06: 'specific_type_control_simple',
        },
    },
    0x02: {
        generic: 'generic_type_static_controller',
        specific: {
            0x01: 'specific_type_pc_controller',
            0x02: 'specific_type_scene_controller',
            0x03: 'specific_type_static_installer_tool',
            0x04: 'specific_type_set_top_box',
            0x05: 'specific_type_sub_system_controller',
            0x06: 'specific_type_tv',
            0x07: 'specific_type_gateway',
        },
    },
    0x03: {
        generic: 'generic_type_av_control_point',
        specific: {
            0x01: 'specific_type_sound_switch',
            0x04: 'specific_type_satellite_receiver',
            0x11: 'specific_type_satellite_receiver_v2',
            0x12: 'specific_type_doorbell',
        },
    },
    0x04: {
        generic: 'generic_type_display',
        specific: {
            0x01: 'specific_type_simple_display',
        },
    },
    0x05: {
        generic: 'generic_type_network_extender',
        specific: {
            0x01: 'specific_type_secure_extender',
        },
    },
    0x06: {
        generic: 'generic_type_appliance',
        specific: {
            0x01: 'specific_type_general_appliance',
            0x02: 'specific_type_kitchen_appliance',
            0x03: 'specific_type_laundry_appliance',
        },
    },
    0x07: {
        generic: 'generic_type_sensor_notification',
        specific: {
            0x01: 'specific_type_notification_sensor',
        },
    },
    0x08: {
        generic: 'generic_type_thermostat',
        specific: {
            0x01: 'specific_type_thermostat_heating',
            0x02: 'specific_type_thermostat_general',
            0x03: 'specific_type_setback_schedule_thermostat',
            0x04: 'specific_type_setpoint_thermostat',
            0x05: 'specific_type_setback_thermostat',
            0x06: 'specific_type_thermostat_general_v2',
        },
    },
    0x09: {
        generic: 'generic_type_windows_covering',
        specific: {
            0x01: 'specific_type_simple_window_covering',
        },
    },
    0x0f: {
        generic: 'generic_type_repeater_slave',
        specific: {
            0x01: 'specific_type_repeater_slave',
            0x02: 'specific_type_virtual_node',
        },
    },
    0x10: {
        generic: 'generic_type_switch_binary',
        specific: {
            0x01: 'specific_type_power_switch_binary',
            0x02: 'specific_type_color_tunable_binary',
            0x03: 'specific_type_scene_switch_binary',
            0x04: 'specific_type_power_strip',
            0x05: 'specific_type_siren',
            0x06: 'specific_type_valve_open_close',
            0x07: 'specific_type_irrigation_controller',
        },
    },
    0x11: {
        generic: 'generic_type_switch_multilevel',
        specific: {
            0x01: 'specific_type_power_switch_multilevel',
            0x02: 'specific_type_color_tunable_multilevel',
            0x03: 'specific_type_motor_multiposition',
            0x04: 'specific_type_scene_switch_multilevel',
            0x05: 'specific_type_class_a_motor_control',
            0x06: 'specific_type_class_b_motor_control',
            0x07: 'specific_type_class_c_motor_control',
            0x08: 'specific_type_fan_switch',
        },
    },
    0x12: {
        generic: 'generic_type_switch_remote',
        specific: {
            0x01: 'specific_type_remote_binary',
            0x02: 'specific_type_remote_multilevel',
            0x03: 'specific_type_remove_toggle_binary',
            0x04: 'specific_type_remote_toggle_multilevel',
        },
    },
    0x13: {
        generic: 'generic_type_switch_toggle',
        specific: {
            0x01: 'specific_type_switch_toggle_binary',
            0x02: 'specific_type_switch_toggle_multilevel',
        },
    },
    0x14: {
        generic: 'generic_type_zip_gateway',
        specific: {
            0x01: 'specific_type_zip_tun_gateway',
            0x02: 'specific_type_zip_adv_gateway',
        },
    },
    0x15: {
        generic: 'generic_type_zip_node',
        specific: {
            0x01: 'specific_type_zip_tun_node',
            0x02: 'specific_type_zip_adv_node',
        },
    },
    0x16: {
        generic: 'generic_type_ventilation',
        specific: {
            0x01: 'specific_type_residential_hrv',
        },
    },
    0x17: {
        generic: 'generic_type_security_panel',
        specific: {
            0x01: 'specific_type_zoned_security_panel',
        },
    },
    0x18: {
        generic: 'generic_type_wall_controller',
        specific: {
            0x01: 'specific_type_basic_wall_controller',
        },
    },
    0x20: {
        generic: 'generic_type_sensor_binary',
        specific: {
            0x01: 'specific_type_routing_sensor_binary',
        },
    },
    0x21: {
        generic: 'generic_type_sensor_multilevel',
        specific: {
            0x01: 'specific_type_routing_sensor_multilevel',
            0x02: 'specific_type_chimney_fan',
        },
    },
    0x30: {
        generic: 'generic_type_meter_pulse',
        specific: {},
    },
    0x31: {
        generic: 'generic_type_meter',
        specific: {
            0x01: 'specific_type_simple_meter',
            0x02: 'specific_type_adv_energy_control',
            0x03: 'specific_type_whole_home_meter_simple',
        },
    },
    0x40: {
        generic: 'generic_type_entry_control',
        specific: {
            0x01: 'specific_type_door_lock',
            0x02: 'specific_type_advanced_door_lock',
            0x03: 'specific_type_secure_keypad_door_lock',
            0x04: 'specific_type_secure_keypad_door_lock_deadbolt',
            0x05: 'specific_type_secure_door',
            0x06: 'specific_type_secure_gate',
            0x07: 'specific_type_secure_barrier_addon',
            0x08: 'specific_type_secure_barrier_open_only',
            0x09: 'specific_type_secure_barrier_close_only',
            0x0a: 'specific_type_secure_lockbox',
            0x0b: 'specific_type_secure_keypad',
        },
    },
    0x50: {
        generic: 'generic_type_semi_interoperable',
        specific: {
            0x01: 'specific_type_energy_production',
        },
    },
    0xa1: {
        generic: 'generic_type_sensor_alarm',
        specific: {
            0x01: 'specific_type_basic_routing_alarm_sensor',
            0x02: 'specific_type_routing_alarm_sensor',
            0x03: 'specific_type_basic_zensor_net_alarm_sensor',
            0x04: 'specific_type_zensor_net_alarm_sensor',
            0x05: 'specific_type_adv_zensor_net_alarm_sensor',
            0x06: 'specific_type_basic_routing_smoke_sensor',
            0x07: 'specific_type_routing_smoke_sensor',
            0x08: 'specific_type_basic_zensor_net_smoke_sensor',
            0x09: 'specific_type_zensor_net_smoke_sensor',
            0x0a: 'specific_type_adv_zensor_net_smoke_sensor',
            0x0b: 'specific_type_alarm_sensor',
        },
    },
    0xff: {
        generic: 'generic_type_non_interoperable',
        specific: {},
    },
};
function genericDeviceClassAttributes(cls) {
    return _genericDeviceClassMap[cls];
}
exports.genericDeviceClassAttributes = genericDeviceClassAttributes;
function genericDeviceClass(cls) {
    const clsAttr = genericDeviceClassAttributes(cls);
    if (clsAttr) {
        return clsAttr.generic;
    }
    else {
        return 'unknownGenericDeviceType_' + cls;
    }
}
exports.genericDeviceClass = genericDeviceClass;
function specificDeviceClass(genericCls, specificCls) {
    const clsAttr = genericDeviceClassAttributes(genericCls);
    if (clsAttr) {
        return (clsAttr.specific[specificCls] ||
            `unknownSpecificDeviceType_${specificCls}`);
    }
    else {
        return `unknownGenericDeviceType_${genericCls}`;
    }
}
exports.specificDeviceClass = specificDeviceClass;
