{ pkgs, lib, config, ... }: let sensors = { temperature = { "temperature_sensor_1" = { id = "0x00158d0002d79220"; room = "living_room_present"; }; "temperature_sensor_2" = { id = "0x00158d0002d7913d"; room = "living_room_present"; }; }; door = { "door_sensor_1" = { id = "0x00158d000312dc52"; }; "door_sensor_2" = { id = "0x00158d000316d5bf"; room = "floor_room_present"; }; "door_sensor_3" = { id = "0x00158d0002f9516f"; }; "door_sensor_4" = { id = "0x00158d00031383b9"; room = "floor_room_present"; }; "door_sensor_5" = { id = "0x00158d0003120d3e"; }; }; }; # todo : generate automatically allSensors = with sensors; temperature // door; in { imports = [ ./mqtt.nix ./zigbee2mqtt/service.nix ./zigbee2mqtt/lights.nix ./zigbee2mqtt/motion.nix ./zigbee2mqtt/buttons.nix ]; services.zigbee2mqtt.enable = true; services.zigbee2mqtt.password = lib.fileContents ; services.zigbee2mqtt.devices = lib.mapAttrs' (name: { id, ... }: { name = id; value = { retain = false; friendly_name = name; }; }) (allSensors); services.homeAssistantConfig = { # define sensors # -------------- sensor = let # define temperature sensors temperature = with lib; mapAttrsToList (name: { ... }: [ { platform = "mqtt"; name = name; state_topic = "zigbee2mqtt/${name}"; availability_topic = "zigbee2mqtt/bridge/state"; unit_of_measurement = "°C"; device_class = "temperature"; value_template = "{{ value_json.temperature }}"; } { platform = "mqtt"; name = "humidity_${name}"; state_topic = "zigbee2mqtt/${name}"; availability_topic = "zigbee2mqtt/bridge/state"; unit_of_measurement = "%"; device_class = "humidity"; value_template = "{{ value_json.humidity }}"; } { platform = "mqtt"; name = "pressure_${name}"; state_topic = "zigbee2mqtt/${name}"; availability_topic = "zigbee2mqtt/bridge/state"; unit_of_measurement = "hPa"; device_class = "pressure"; value_template = "{{ value_json.pressure }}"; } ]) sensors.temperature; # define meta information sensors informations = lib.mapAttrsToList (name: { ... }: [ { name = "battery_${name}"; platform = "mqtt"; state_topic = "zigbee2mqtt/${name}"; availability_topic = "zigbee2mqtt/bridge/state"; unit_of_measurement = "%"; icon = "mdi:battery-10"; value_template = "{{ value_json.battery }}"; } { name = "link_${name}"; platform = "mqtt"; state_topic = "zigbee2mqtt/${name}"; availability_topic = "zigbee2mqtt/bridge/state"; icon = "mdi:signal"; unit_of_measurement = "lqi"; value_template = "{{ value_json.linkquality }}"; } ]) allSensors; in lib.flatten (temperature ++ informations); # define binary sensors # --------------------- binary_sensor = let # define door sensors # ------------------- door = lib.mapAttrsToList (name: { ... }: { name = name; platform = "mqtt"; device_class = "door"; state_topic = "zigbee2mqtt/${name}"; availability_topic = "zigbee2mqtt/bridge/state"; payload_on = false; payload_off = true; value_template = "{{ value_json.contact}}"; }) sensors.door; in lib.flatten (door); # create groups # ------------- # to have nice panels for every device group = let information = name: [ "sensor.battery_${name}" "sensor.link_${name}" ]; sensorTemperature = lib.mapAttrs' (name: { ... }: { name = name; value = { control = "hidden"; entities = [ "sensor.${name}" "sensor.humidity_${name}" "sensor.pressure_${name}" ] ++ (information name); }; }) (sensors.temperature); sensorDoors = lib.mapAttrs' (name: { ... }: { name = name; value = { control = "hidden"; entities = [ "binary_sensor.${name}" ] ++ (information name); }; }) (sensors.door); views = { view_sensors = { name = "Sensoren"; control = "hidden"; view = true; entities = lib.mapAttrsToList (name: { ... }: "group.${name}") allSensors; }; }; # sort sensors in room groups # --------------------------- allRoomsGroups = let createGroupEntities = { sensors, entityNameing }: let flatSensors = lib.mapAttrsToList (name: values: { name = name; } // values) sensors; allRooms' = lib.groupBy ({ room ? "unknown", ... }: room) flatSensors; allRooms = lib.mapAttrs (_: devices: map entityNameing devices) allRooms'; in allRooms; groupEntries = { doorGroups = createGroupEntities { sensors = sensors.door; entityNameing = ({ name, ... }: "binary_sensor.${name}"); }; }; # merge all group entries in lib.mapAttrs (_: entities: { entities = lib.flatten entities; }) (lib.zipAttrs (builtins.attrValues groupEntries)); in views // allRoomsGroups // sensorTemperature // sensorDoors // { all_sensors.entities = (lib.mapAttrsToList (name: { ... }: "sensor.${name}") (sensors.temperature)) ++ (lib.mapAttrsToList (name: { ... }: "binary_sensor.${name}") sensors.door); }; }; }