commit 53fe5ec764a520b9f115a7b28d198ab69ec2d3b3
parent ff62bafb789c6aa57d680fe3fe6da2551ba22bbb
Author: Leah (ctucx) <git@ctu.cx>
Date: Fri, 9 Dec 2022 22:30:13 +0100
parent ff62bafb789c6aa57d680fe3fe6da2551ba22bbb
Author: Leah (ctucx) <git@ctu.cx>
Date: Fri, 9 Dec 2022 22:30:13 +0100
machines/lollo/smarthome: add mqtt-webui
6 files changed, 329 insertions(+), 0 deletions(-)
A
|
254
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/flake.lock b/flake.lock @@ -225,6 +225,30 @@ "url": "file:///tmp/nix-secrets" } }, + "mqtt-webui": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1670619364, + "narHash": "sha256-zujFDUFOIqIllkP7yKqBhhetxS6VHOO63JZMsV5QPBE=", + "ref": "master", + "rev": "4f95bfd818d24ddb758fcd8b6e0f1f385d39b09c", + "revCount": 180, + "type": "git", + "url": "https://git.ctu.cx/mqtt-webui" + }, + "original": { + "ref": "master", + "type": "git", + "url": "https://git.ctu.cx/mqtt-webui" + } + }, "nix-eval-jobs": { "inputs": { "flake-utils": [ @@ -324,6 +348,7 @@ "home-manager": "home-manager", "lacrosse2mqtt": "lacrosse2mqtt", "local-secrets": "local-secrets", + "mqtt-webui": "mqtt-webui", "nix-std": "nix-std", "nixpkgs": "nixpkgs", "nixpkgsUnstable": "nixpkgsUnstable",
diff --git a/flake.nix b/flake.nix @@ -94,6 +94,14 @@ inputs.flake-utils.follows = "flake-utils"; }; + mqtt-webui = { + type = "git"; + url = "https://git.ctu.cx/mqtt-webui"; + ref = "master"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "flake-utils"; + }; + local-secrets.url = "/tmp/nix-secrets"; };
diff --git a/machines/lollo/smarthome/default.nix b/machines/lollo/smarthome/default.nix @@ -11,6 +11,8 @@ ./lacrosse2mqtt.nix ./influxdb2.nix + + ./mqtt-webui.nix ]; }
diff --git a/machines/lollo/smarthome/mqtt-webui-config.nix b/machines/lollo/smarthome/mqtt-webui-config.nix @@ -0,0 +1,253 @@ +let + + Switch = name: topic: { + title = name; + type = "switch"; + icon = "icons/power_button.png"; + topic.get = topic; + topic.set = "${topic}/set"; + transform.get = "return (message.state == 'ON') ? true : false"; + transform.set = "return JSON.stringify({state: (input) ? 'ON' : 'OFF'})"; + }; + + BrighnessSlider = name: topic: { + title = name; + type = "slider"; + icon = "icons/bulb.png"; + sliderMinValue = 0; + sliderMaxValue = 254; + sliderStepValue = 1; + topic.get = topic; + topic.set = "${topic}/set"; + transform.get = "return message.brightness"; + transform.set = "return JSON.stringify({brightness: Number(input)})"; + }; + + ColorTemperatureSlider = name: topic: { + title = name; + type = "slider"; + icon = "icons/bulb.png"; + sliderMinValue = 250; + sliderMaxValue = 454; + sliderStepValue = 1; + topic.get = topic; + topic.set = "${topic}/set"; + transform.get = "return message.color_temp"; + transform.set = "return JSON.stringify({color_temp: Number(input)})"; + }; + + DimmableLamp = name: topic: { + title = name; + items = [ + (Switch "Power" topic) + (BrighnessSlider "Brighness" topic) + ]; + }; + + WhiteSpectrumLamp = name: topic: { + title = name; + items = [ + (Switch "Power" topic) + (BrighnessSlider "Brighness" topic) + (ColorTemperatureSlider "Color Temperature" topic) + ]; + }; + + ColorSpectrumLamp = name: topic: { + title = name; + items = [ + (Switch "Power" topic) + (BrighnessSlider "Brighness" topic) + (ColorTemperatureSlider "Color Temperature" topic) + + { + title = "Color"; + type = "select"; + icon = "icons/bulb.png"; + topic.get = topic; + topic.set = "${topic}/set"; + transform.get = "return message.color.x + ','+message.color.y"; + transform.set = "return JSON.stringify({color: {x: input.split(',')[0], y: input.split(',')[1]}})"; + selectOptions = [ + { + label = "Red"; + value = "0.71,0.26"; + } + { + label = "Green"; + value = "0.19,0.78"; + } + { + label = "Blue"; + value = "0.09,0.13"; + } + ]; + } + ]; + }; + + +in { + + pages = [ + { + id = "mainpage"; + icon = "favicon-512x512.png"; + title = "Smart-Home"; + sections = [ + { + title = "Rooms"; + items = [ + { + title = "Leah's room"; + type = "text"; + icon = "icons/electric_range.png"; + link = "#leah"; + } + { + title = "Isa's room"; + type = "text"; + icon = "icons/electric_range.png"; + link = "#isa"; + } + ]; + } + + (WhiteSpectrumLamp "Hallway: Ceiling Light" "zigbee2mqtt/ikea_lamp_hallway") + + (WhiteSpectrumLamp "Kitchen: Ceiling Light" "zigbee2mqtt/ikea_lamp_kitchen") + + (WhiteSpectrumLamp "Bathroom: Ceiling Light" "zigbee2mqtt/ikea_lamp_bathroom") + + { + title = "Temperature-Sensors"; + items = [ + { + title = "Fridge"; + type = "text"; + topic = "lacrosse2mqtt/33"; + icon = "icons/temperature.png"; + transform = "return Math.round((message.temperature + Number.EPSILON) * 100) / 100 + ' °C'"; + } + { + title = "Bathroom"; + type = "text"; + topic = "lacrosse2mqtt/5"; + icon = "icons/temperature.png"; + transform = "return Math.round((message.temperature + Number.EPSILON) * 100) / 100 + ' °C - ' + message.humidity + ' %'"; + } + ]; + } + ]; + } + + { + id = "leah"; + icon = "favicon-512x512.png"; + title = "Leah's room"; + sections = [ + (WhiteSpectrumLamp "Ceiling Light" "zigbee2mqtt/ikea_lamp_l") + + (DimmableLamp "Desk" "zigbee2mqtt/led_stripe_desk") + + (ColorSpectrumLamp "RGB Lamp" "zigbee2mqtt/ikea_lamp_l_rgb") + + { + title = "Power-Meter"; + items = [ + { + title = "Voltage"; + type = "text"; + topic = "sdm2mqtt/leah"; + icon = "icons/power.png"; + transform = "return Math.round((message.voltage + Number.EPSILON) * 100) / 100 + ' V'"; + } + { + title = "Power"; + type = "text"; + topic = "sdm2mqtt/leah"; + icon = "icons/power.png"; + transform = "return Math.round((message.power + Number.EPSILON) * 100) / 100 + ' W'"; + } + { + title = "Frequency"; + type = "text"; + topic = "sdm2mqtt/leah"; + icon = "icons/power.png"; + transform = "return message.frequency + ' Hz'"; + } + { + title = "cos φ"; + type = "text"; + topic = "sdm2mqtt/leah"; + icon = "icons/power.png"; + transform = "return Math.round((message.cosphi + Number.EPSILON) * 100) / 100"; + } + { + title = "Total Import"; + type = "text"; + topic = "sdm2mqtt/leah"; + icon = "icons/power.png"; + transform = "return Math.round((message.import + Number.EPSILON) * 100) / 100 + ' kWh'"; + } + ]; + } + + { + title = "Temperature-Sensors"; + items = [ + { + title = "Temperature"; + type = "text"; + topic = "lacrosse2mqtt/3a"; + icon = "icons/temperature.png"; + transform = "return Math.round((message.temperature + Number.EPSILON) * 100) / 100 + ' °C'"; + } + ]; + } + ]; + } + + { + id = "isa"; + icon = "favicon-512x512.png"; + title = "Isa's room"; + sections = [ + (WhiteSpectrumLamp "Ceiling Light" "zigbee2mqtt/ikea_lamp_i") + + (ColorSpectrumLamp "RGB Lamp" "zigbee2mqtt/ikea_lamp_i_rgb") + + { + title = "Switches"; + items = [ + (Switch "Desk (L)" "zigbee2mqtt/ikea_control_outlet_i_desk_l") + (Switch "Desk (R)" "zigbee2mqtt/ikea_control_outlet_i_desk_r") + ]; + } + + { + title = "Temperature-Sensors"; + items = [ + { + title = "Temperature"; + type = "text"; + topic = "lacrosse2mqtt/3c"; + icon = "icons/temperature.png"; + transform = "return Math.round((message.temperature + Number.EPSILON) * 100) / 100 + ' °C'"; + } + { + title = "Humidity"; + type = "text"; + topic = "lacrosse2mqtt/3c"; + icon = "icons/thermostat.png"; + transform = "return message.humidity + ' %'"; + } + ]; + } + + ]; + } + + ]; + +}+ \ No newline at end of file
diff --git a/machines/lollo/smarthome/mqtt-webui.nix b/machines/lollo/smarthome/mqtt-webui.nix @@ -0,0 +1,37 @@ +{ inputs, lib, pkgs, ... }: + +let + + configFile = pkgs.writeTextDir "config.json" (builtins.toJSON (import ./mqtt-webui-config.nix)); + +in { + + services = { + nginx = { + enable = true; + virtualHosts."smart.home.ctu.cx" = { + enableACME = true; + forceSSL = true; + kTLS = true; + + locations = { + "/" = { + root = "${pkgs.buildEnv { + name = "mqtt-webui-env"; + paths = [ + pkgs.mqtt-webui + configFile + ]; + }}/"; + }; + "/mqtt" = { + proxyPass = "http://127.0.0.1:9005"; + proxyWebsockets = true; + }; + }; + }; + }; + + }; + +}+ \ No newline at end of file
diff --git a/pkgs/default.nix b/pkgs/default.nix @@ -13,6 +13,8 @@ sdm2mqtt = inputs.sdm2mqtt.packages."${currentSystem}".default; lacrosse2mqtt = inputs.lacrosse2mqtt.packages."${currentSystem}".default; + mqtt-webui = inputs.mqtt-webui.packages."${currentSystem}".default; + pleroma = prev.pleroma.overrideAttrs (old: { patches = [ ./0001-PATCH-Separate-webfinger-domain-from-host-domain.patch