├── README.md ├── zha-backto-zigbee2mqtt.md ├── homeassistant-google-home-ip-ranges.md ├── homeassistant-proxmoxve-updates-notification.md ├── homeassistant-ebusd-statenumber-translation.md ├── homeassistant-diskspace-notification.md ├── proxmox-nixos-lxc.md ├── proxmox-security-groups.md ├── homeassistant-proxmox-host-ssh.md ├── homeassistant-ebusd-read-values.md ├── frigate-lxc.md ├── openwrt-802.11k.md ├── zabbix-mqtt.md ├── zabbix-debian-updating.md ├── proxmox-lxc-nixos-desktop.md ├── ryzenadj-on-proxmox.md ├── homeassistant-ebusd-sensor-names.md ├── frigate-docker-lxc.md ├── MR60BHA2.md ├── provision-lxc-desktop-from-homeassistant.md └── ebus-hass.md /README.md: -------------------------------------------------------------------------------- 1 | # proxmox-tips 2 | Some self-hosting tips (Proxmox, HomeAssistant, etc) 3 | 4 | In this repository i described some parts of my home-lab setup. 5 | -------------------------------------------------------------------------------- /zha-backto-zigbee2mqtt.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | For a few years i've been using Zigbee2MQTT which did work fine. But during some refactoring of my homeserver i wanted to switch to ZHA as it's integrated in Home Assistant. 3 | Unfortunatly devices are becomming unavailable and seem to be dropping of the network. So now i'll be switching back to Zigbee2MQTT. 4 | 5 | # Zigbee2MQTT 6 | 7 | 1. I added a new Home Assistant addon repository: https://github.com/zigbee2mqtt/hassio-zigbee2mqtt 8 | 2. I installed the Zigbee2MQTT addon 9 | 3. Copied the serial port ZHA is using: `/dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_46541a0ee993eb1198edb15b3d98b6d1-if00-port0` and `/dev/ttyUSB1` 10 | 4. Disabled the ZHA-integration 11 | 5. In the field "serial" i put in: `port: /dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_46541a0ee993eb1198edb15b3d98b6d1-if00-port0` 12 | 6. I started the addon 13 | 7. I then removed the ZHA-integration 14 | -------------------------------------------------------------------------------- /homeassistant-google-home-ip-ranges.md: -------------------------------------------------------------------------------- 1 | I use my Google Home devices to control my smart-home via Home Assistant. This uses the Google Assistant integration in Home Assistant. 2 | 3 | For this to work i need to allow the following IP-ranges through my firewall to my Home Assistant instance. 4 | 5 | This are the IP-ranges: 6 | * 66.102.0.0/20 7 | * 66.249.80.0/20 8 | * 74.125.0.0/16 9 | * 108.177.0.0/17 10 | * 192.178.0.0/15 11 | 12 | I also had to add an IP-address from my ISP (Tmobile/Odido), but this might be from a mobile phone: 13 | * 89.205.130.202 14 | 15 | This are some of the IP-adresses i actually saw incomming traffic from: 16 | * 66.102.9.73 17 | * 66.102.9.74 18 | * 66.249.81.133 19 | * 66.249.93.14 20 | * 66.249.93.2 21 | * 74.125.208.72 22 | * 74.125.208.73 23 | * 74.125.208.74 24 | * 74.125.211.7 25 | * 108.177.64.4 26 | * 108.177.64.5 27 | * 108.177.64.6 28 | * 108.177.76.2 29 | * 192.178.13.200 30 | 31 | 32 | 33 | Resources: 34 | * https://community.home-assistant.io/t/expose-home-assistant-for-google-ips-only-ipv4-only/184646 35 | * https://md5calc.com/google/ip 36 | * https://www.gstatic.com/ipranges/goog.json 37 | -------------------------------------------------------------------------------- /homeassistant-proxmoxve-updates-notification.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | Via HACS i installed the [ProxmoxVE-integration](https://github.com/dougiteixeira/proxmoxve) to be able to monitor my Proxmox-installation. I would like to see a persistent-notification in Home Assistant when an update is available for ProxmoxVE. 3 | 4 | 5 | # Automations 6 | 7 | This is the automation to create a persistant notification when updates are available for ProxmoxVE: 8 | ``` 9 | alias: ProxmoxVE updates notificatie 10 | description: "" 11 | trigger: 12 | - platform: numeric_state 13 | entity_id: 14 | - sensor.node_pve_total_updates 15 | above: 0 16 | - platform: homeassistant 17 | event: start 18 | condition: 19 | - condition: numeric_state 20 | entity_id: sensor.node_pve_total_updates 21 | above: 0 22 | action: 23 | - service: persistent_notification.create 24 | data: 25 | message: >- 26 | {{ states("sensor.node_pve_total_updates") }} updates beschikbaar voor 27 | ProxmoxVE 28 | notification_id: proxmoxve_updates 29 | ``` 30 | I added "Home Assistant start" as a trigger as otherwise the notification will disappear after a restart of Home Assistant. 31 | 32 | And an automation to close the notification when no updates are available: 33 | ``` 34 | alias: ProxmoxVE updates notificatie sluiten 35 | trigger: 36 | - platform: numeric_state 37 | entity_id: 38 | - sensor.node_pve_total_updates 39 | below: 1 40 | action: 41 | - service: persistent_notification.dismiss 42 | data: 43 | notification_id: proxmoxve_updates 44 | ``` 45 | -------------------------------------------------------------------------------- /homeassistant-ebusd-statenumber-translation.md: -------------------------------------------------------------------------------- 1 | Page 44/45: https://www.vaillant.nl/downloads/handleidingen-na-10-december-2014/installatiehandleiding-ecotec-plus-0020116691-05-272298.pdf 2 | 3 | My Vaillant EcoTec CV publishes it's "statenumber" on the ebus. By translating the numbers into a textual description, the functioning of the CV is much more clear. 4 | 5 | Home Assistant "Template helper sensor" to translate "ebusd bai statenumber" into a description: 6 | ```text 7 | {{ 8 | { 9 | '0':'Verwarming geen warmtevraag', 10 | '1':'CV-bedrijf ventilatorstart', 11 | '2':'CV-bedrijf pompvoorloop', 12 | '3':'CV-bedrijf ontsteking', 13 | '4':'CV-bedrijf brander aan', 14 | '5':'CV-bedrijf pomp-/ventilatornaloop', 15 | '6':'CV-bedrijf ventilatornaloop', 16 | '7':'CV-bedrijf pompnaloop', 17 | '8':'CV-bedrijf restwachttijd', 18 | '9':'Meetprogramma', 19 | '10':'Warmwatervraag door stromingssensor', 20 | '11':'Warmwaterbedrijf ventilatorstart', 21 | '13':'Warmwaterbedrijf ontsteking', 22 | '14':'Warmwaterbedrijf brander aan', 23 | '15':'Warmwaterbedrijf pomp-/ventilatornaloop', 24 | '16':'Warmwaterbedrijf ventilatornaloop', 25 | '17':'Warmwaterbedrijf pompnaloop', 26 | '30':'Kamerthermostaat (RT) blokkeert CV vraag', 27 | '31':'Zomermodus actief of geen warmtevraag door eBus-thermostaat', 28 | '32':'Wachttijd wegens afwijking ventilatortoerental', 29 | '34':'Vorstbeveiligingsfunctie actief', 30 | '76':'Installatiedruk te gering. Water bijvullen' 31 | }.get(states('sensor.ebusd_bai_statenumber') | default('') ) 32 | }} 33 | ``` 34 | 35 | The above states can also be viewed using the "live monitor" functionality on the display of the CV. 36 | 37 | In Home Assistant i see this in the logbook: 38 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/fc6c5bf8-ad4e-4ee2-8465-6f5b2c5136b5) 39 | -------------------------------------------------------------------------------- /homeassistant-diskspace-notification.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | I just got an error in Homeassistant about the file-system being readonly. This was caused by Homeassistant running out-of-disk-space in the VM as the disk was only 32gb. I would've liked to have received a notification for this. To resolve the error itself i increased the sized of the disk via Proxmox. 3 | 4 | # Data-disk 5 | I also chose to take this opportunity to add a second disk to the Home Assistant VM and to make this the data-disk for Home Assistant. 6 | 1. Via Proxmox i added a 40gb on SCSI:1 with writetrough-caching, enabled discard, enabled backup. It's important to choose the size to match or be larger than the current disk on which Home Assistant is installed or an errormessage will be displayed in Home Assistant. 7 | 2. Rebooted the Home Assistant VM to get Home Assistant to learn about the newly added disk 8 | 3. Navigate in Home Assistant to "Settings" > "Storage" 9 | 4. I chose "Move data-disk" and selected the only available option "drive-scsi1" 10 | 5. In the Proxmox console of the Home Assistant VM i watched the log for the operation to complete 11 | 12 | # Sensors 13 | I would expect that Homeassistant or "Home Assistant Supervisor" to provide information about diskspace, but apparently not. 14 | But the "systemmonitor" integration does provide this information. With this Yaml the diskspace information will become available: 15 | ``` 16 | sensor: 17 | - platform: systemmonitor 18 | resources: 19 | - type: processor_use 20 | - type: disk_use_percent 21 | arg: / 22 | - type: disk_use_percent 23 | arg: /config 24 | - type: disk_use 25 | arg: / 26 | - type: disk_free 27 | arg: / 28 | ``` 29 | After reload/reboot Home Assistant i got the following sensors: 30 | * `sensor.processor_use` 31 | * `sensor.disk_use_percent` 32 | * `sensor.disk_use_percent_config` 33 | * `sensor.disk_use` 34 | * `sensor.disk_free` 35 | 36 | 37 | # Automation 38 | With the following automation i will receive a notification on my iPhone when more than 90% is used: 39 | ``` 40 | alias: Home Assistant controleer vrije diskruimte 41 | description: "" 42 | trigger: 43 | - platform: numeric_state 44 | entity_id: 45 | - sensor.disk_use_percent 46 | above: 90 47 | - platform: numeric_state 48 | entity_id: 49 | - sensor.disk_use_percent_config 50 | above: 90 51 | action: 52 | - service: notify.mobile_app_iphone_van_sander 53 | data: 54 | message: Weinig vrije diskruimte voor Home Assisant 55 | mode: single 56 | ``` 57 | -------------------------------------------------------------------------------- /proxmox-nixos-lxc.md: -------------------------------------------------------------------------------- 1 | # Create NixOS environments as Proxmox LXC containers 2 | Created on: 18-12-2024, NixOS release 24.11, Proxmox v8.3.1 3 | 4 | ## Get a NixOS container template from hydra.nixos.org 5 | 6 | 1. Open in browser: [https://hydra.nixos.org/project/nixos](https://hydra.nixos.org/project/nixos) 7 | 2. Select the release: [at this time: `nixos:release-24.11`](https://hydra.nixos.org/jobset/nixos/release-24.11) 8 | 3. Navigate to the tab: `Jobs` [nixos:release-24.11 Jobs](https://hydra.nixos.org/jobset/nixos/release-24.11#tabs-jobs) 9 | 4. On the Jobs-tab use the search-bar to search for: `nixos.proxmoxLXC.x86_64-linux` 10 | 5. Click a green checkmark which sits behind the correct CPU-arch 11 | 6. Copy the download link of `nixos-system-x86_64-linux.tar.xz` 12 | 7. In the Proxmox Web UI, navigate to the "Storage" and choose `CT Template` 13 | 8. Click the button `Download from URL` and paste the download link ([at this time](https://hydra.nixos.org/build/282070945/download/1/nixos-system-x86_64-linux.tar.xz)) 14 | 15 | ## Create a NixOS environment as a Proxmox LXC container 16 | * The exact parameters for `cmode`, `unprivileged`, `ostype`, and `features` is needed for getting this container running. 17 | * The container will get an IP via DHCP 18 | * The root user in the container is passwordless 19 | * SSH is enabled, also for the root user 20 | 21 | Run on your Proxmox host: 22 | ``` 23 | pct create 300 local-btrfs:vztmpl/nixos-system-x86_64-linux.tar.xz --tags nixos --cmode console \ 24 | -ostype nixos --arch amd64 -net0 name=eth0,bridge=vmbr0,hwaddr=BC:24:11:8B:6C:00,ip=dhcp,type=veth \ 25 | -storage local-btrfs --hostname qbittorrent --swap 0 --memory 2048 --unprivileged 0 --features nesting=1 26 | 27 | pct resize 300 rootfs +2G 28 | pct start 300 29 | pct enter 300 30 | ``` 31 | In the shell of CT 300: 32 | 1. Run: `source /etc/set-environment` 33 | 2. Clear the root password: `passwd --delete root` 34 | 3. Start editting: `nano /etc/nixos/configuration.nix` 35 | 4. Add the following minimal configuration to allow for remote deployment via SSH 36 | ``` 37 | { config, modulesPath, pkgs, lib, ... }: 38 | { 39 | imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ]; 40 | nix.settings = { sandbox = false; }; 41 | security.pam.services.sshd.allowNullPassword = true; 42 | services.openssh = { 43 | enable = true; 44 | openFirewall = true; 45 | settings = { 46 | PermitRootLogin = "yes"; 47 | PasswordAuthentication = true; 48 | PermitEmptyPasswords = "yes"; 49 | }; 50 | }; 51 | system.stateVersion = "24.11"; 52 | } 53 | ``` 54 | 4. Run the following commands 55 | ``` 56 | nix-channel --update 57 | nixos-rebuild switch --upgrade 58 | ``` 59 | 60 | I myself use this container as the target to deploy a flake target onto, by: 61 | ``` 62 | nixos-rebuild switch --flake .#qbittorrent --target-host root@192.168.1.119 63 | ``` 64 | 65 | 66 | -------------------------------------------------------------------------------- /proxmox-security-groups.md: -------------------------------------------------------------------------------- 1 | If you have multiple virtual appliances in Proxmox with Zabbix-clients, then it's possible to create a "Security Group" to configure a set of firewall rules. 2 | 3 | Zabbix-server communicates with it's Zabbix client instances using TCP 10050. 4 | It's also possible to have an "active" Zabbix client instance which will communicate using TCP 10051 to the Zabbix-server. 5 | 6 | # Create alias for Zabbix-server IP# 7 | 1. Navigate in Proxmox WebUI to the Proxmox Cluster node. 8 | 2. Expand the menu "Firewall" 9 | 3. Navigate to "Alias" 10 | 4. Click "Create" to create an alias 11 | 5. Give: 12 | name: `Zabbix-server` 13 | IP/CIDR: `192.168.178.10` 14 | Comment: `Zabbix server` 15 | 16 | # Create Security Group "Zabbix-client" 17 | 1. Navigate in Proxmox WebUI to the Proxmox Cluster node. 18 | 2. Expand the menu "Firewall" 19 | 3. Navigate to "Security Group" 20 | 4. Click "Create" to create a group 21 | 5. Give name: `zabbix-client` 22 | 6. Confirm with the "OK" button 23 | 7. Select the group "zabbix-client" 24 | 8. On the right-side choose for "Add" 25 | 9. Configure: 26 | Direction: `In` 27 | Action: `Accept` 28 | Protocol: `TCP` 29 | Dest.Port: `10050` 30 | Source: alias `zabbix-server` 31 | Comment: `Allow inbound Zabbix agent traffic` 32 | Log level: `nolog` 33 | 10. Choose again on the right side for "Add" 34 | 11. Configure: 35 | Direction: `Out` 36 | Action: `Accept` 37 | Protocol: `TCP` 38 | Dest.Port: `10051` 39 | Destination: alias `zabbix-server` 40 | Comment: `Allow outbound Zabbix agent (active) traffic` 41 | Log level: `nolog` 42 | 43 | # Insert Security Group "Zabbix-client" to "OPNsense" 44 | 1. Navigate in Proxmox to your "OPNsense" container 45 | 2. Navigate to the Firewall-menu 46 | 3. Click the "Insert: security group" button 47 | 4. Select: 48 | Security Group: `zabbix-client` 49 | Enabled: `checked` 50 | 5. Confirm with the "OK" button 51 | 52 | # Create Security Group for "Zabbix-ping" 53 | I also configured Zabbix-server to ping my network devices. I want to allow this ping-checks. 54 | So i created a "Security Group" named `zabbix-ping`. 55 | With a rule: 56 | Direction: `In` 57 | Action: `Accept` 58 | Protocol: `icmp` 59 | ICMP-type: `echo-request` 60 | Source: `zabbix-server` 61 | Comment: `Allow inbound Zabbix ping` 62 | Log level: `nolog` 63 | I added this security group to all my LXCs/VMs. 64 | 65 | # Create Security Group for "Mail-delivery" 66 | I also create a Security Group to allow mail-delivery (smtp, tcp/25) to my mail-server. 67 | 68 | I create an alias for my mail-server: 69 | * Name: `Mail-server` 70 | * IP/CIDR: `192.168.178.97` 71 | * Comment: `Mail server` 72 | 73 | So i created a "Security Group" named `mail-delivery`. 74 | With a rule: 75 | Direction: `Out` 76 | Action: `Accept` 77 | Protocol: `tcp` 78 | Dest Port: `80` 79 | Destination: alias `mail-server` 80 | Comment: `Allow mail delivery` 81 | Log level: `nolog` 82 | I added this security group to all my LXCs/VMs which make use of mail-delivery (Zabbix, PVE-node). 83 | 84 | 85 | # Create Security Group for "drop-inbound-mdns" 86 | 87 | | | | Protocol | Destination | 88 | |------|------|--------------|-------------| 89 | | IN | DROP | 90 | -------------------------------------------------------------------------------- /homeassistant-proxmox-host-ssh.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | I wanted to use Homeassistant to execute scripts on my Proxmox host. In the past i did this through setting up SSH-connection by logging in as the root. 3 | I searched for an alternative solution which would work without SSH. I though something like a rest-api for triggering scripts would exist. And indeed those solutions did exist, but no common-used-solution that everybody is using. 4 | This common-used-solution seem to be "SSH". So eventually i chose to use SSH. 5 | 6 | # Creating the "Homeassistant" user on the Proxmox host 7 | 1. Open a Shell on Proxmox via the Web-gui 8 | 2. Create the user “homeassistant” with: `useradd --shell /usr/bash --create-home homeassistant` 9 | 10 | # Enable the "Homeassistant" user in Proxmox 11 | 1. Navigate in the Proxmox GUI to the "Server View" > “Datacenter” 12 | 2. Navigate to “Permissions” > “Users” 13 | 3. Click “Add” 14 | 4. Give "Username": `homeassistant` 15 | 5. Ensure "Realm": `Linux PAM standard authentication` 16 | 6. Ensure "Enabled": `Checked` 17 | 7. Click the button to create the user 18 | 8. Select the user `homeassistant` 19 | 9. Choose the button "Password" 20 | 10. Enter a password 21 | 22 | # Generate keypair and provide to remote host 23 | 1. Open "Homeassistant" 24 | 2. Install the "SSH-addon" 25 | 3. Configure the "SSH-addon" to accept a password by providing a password 26 | 4. Configure the "SSH-addon" to work on port: 22 27 | 5. Start the SSH-addon 28 | 6. Choose the the button "OPEN WEB-UI" 29 | 7. In the console crreate directory: `mkdir -p /config/key/` 30 | 8. Generate keypair: `ssh-keygen -t rsa -b 4096 -f /config/key/id_rsa` 31 | 9. Copy the public key to the Proxmox-host: `ssh-copy-id -i /config/key/id_rsa.pub homeassistant@192.168.178.2` (192.168.178.2 is the IP# of my Proxmox-host) 32 | 10. Accept the fingerprint of the remote host (SSH addon) 33 | 11. Enter the password of the user “homeassistant” you created on the Proxmox-host 34 | 35 | # (Optional) Allow Homeassistant to run ryzenadj 36 | In the shell of the Proxmox-host as the root user: 37 | 1. Create a usegroup which can run "ryzenadj": `groupadd ryzenadj` 38 | 2. Make the user "homeassistant" member of the usergroup: `usermod -aG ryzenadj homeassistant` 39 | 3. Create a sudoers-file to allow for running "ryzenadj" with "sudo" without requiring a password: `nano /etc/sudoers.d/ryzenadj` 40 | 4. Put in this file: 41 | ``` 42 | ## Members of the ryzenadj group may gain some privileges 43 | %ryzenadj ALL=(ALL) NOPASSWD: /usr/local/bin/ryzenadj 44 | ``` 45 | I installed the [remote command line integration](https://github.com/koying/ha-remote-command-line) via HACS. 46 | In homeassistant add this yaml: 47 | ``` 48 | remote_command_line: 49 | tdp_low: 50 | ssh_user: homeassistant 51 | ssh_host: 192.168.178.2 < IP# of my Proxmox host 52 | ssh_key: /config/key/id_rsa 53 | command_timeout: 10 54 | command: "sudo ./ryzenadj --stapm-limit=1000 --fast-limit=1000 --slow-limit=1000 --tctl-temp=90 --power-saving > /dev/null" 55 | 56 | tdp_high: 57 | ssh_user: homeassistant 58 | ssh_host: 192.168.178.2 59 | ssh_key: /config/key/id_rsa < IP# of my Proxmox host 60 | command_timeout: 10 61 | command: "sudo ./ryzenadj --stapm-limit=45000 --fast-limit=45000 --slow-limit=45000 --tctl-temp=90 --max-performance > /dev/null" 62 | ``` 63 | 64 | -------------------------------------------------------------------------------- /homeassistant-ebusd-read-values.md: -------------------------------------------------------------------------------- 1 | The following script will send an "ebusd/list"- and some "get"-commands via MQTT. This to populate Home Assistant entities as early as possible with values. 2 | This script also registers high-priority updating for some values. 3 | 4 | ``` 5 | alias: Alle ebusd entiteiten voorzien van de ontvangen waarden of null 6 | description: "" 7 | sequence: 8 | - service: mqtt.publish 9 | data: 10 | topic: ebusd/list 11 | payload: " " 12 | alias: Publiceer "ebusd/list" commando voor ophalen alle bekende waarden 13 | - delay: 14 | seconds: 5 15 | - variables: 16 | topics: 17 | - 350/DisplayedHc1RoomTempDesired 18 | - 350/DisplayedRoomTemp 19 | - 350/HwcOPMode 20 | - 350/Hc1DayTemp 21 | - 350/Hc1HolidayRoomTemp 22 | - 350/Hc1NightTemp 23 | - bai/PrEnergySumHc1 24 | - bai/PrEnergySumHwc1 25 | - bai/PartloadHcKW 26 | alias: Definieer lijst van topics waarvan de waarde opgevraagd dient te worden 27 | - alias: Publiceer "get" commando's voor ophalen van waarden van topics 28 | repeat: 29 | count: "{{ topics | count }}" 30 | sequence: 31 | - variables: 32 | topic: ebusd/{{ topics[repeat.index - 1] }}/get 33 | - service: mqtt.publish 34 | data: 35 | topic: "{{topic}}" 36 | - variables: 37 | topics: 38 | - bai/Flame 39 | - bai/CirPump 40 | - bai/HwcWaterflow 41 | - bai/PrEnergySumHc1 42 | - bai/PrEnergySumHwc1 43 | - bai/Statenumber 44 | - bai/HwcDemand 45 | - bai/RemainingBoilerblocktime 46 | - bai/ReturnTemp 47 | - bai/PumpPowerDesired 48 | alias: >- 49 | Definieer lijst van topics waarvan de waarde regelmatig bijgewerkt dient 50 | te worden 51 | - alias: >- 52 | Publiceer "get?1" commando's voor het regelmatig bijwerken van de waarden 53 | van topics 54 | repeat: 55 | count: "{{ topics | count }}" 56 | sequence: 57 | - variables: 58 | topic: ebusd/{{ topics[repeat.index - 1] }}/get 59 | - service: mqtt.publish 60 | data: 61 | topic: "{{topic}}" 62 | payload: "?1" 63 | ``` 64 | 65 | I combine the script above with the two following automations: 66 | ``` 67 | alias: Alle ebusd waarden opvragen bij starten Home Assistant 68 | description: "" 69 | trigger: 70 | - platform: homeassistant 71 | event: start 72 | action: 73 | - delay: 74 | hours: 0 75 | minutes: 1 76 | seconds: 0 77 | milliseconds: 0 78 | - service: script.turn_on 79 | metadata: {} 80 | data: {} 81 | target: 82 | entity_id: script.opvragen_ebusd_waarden 83 | ``` 84 | 85 | ``` 86 | alias: Alle ebusd waarden opvragen na opstarten ebusd/mqtt 87 | description: "" 88 | trigger: 89 | - platform: state 90 | entity_id: 91 | - sensor.ebusd_scan 92 | to: "\"finished\"" 93 | condition: [] 94 | action: 95 | - delay: 96 | hours: 0 97 | minutes: 1 98 | seconds: 0 99 | milliseconds: 0 100 | - service: script.turn_on 101 | metadata: {} 102 | data: {} 103 | target: 104 | entity_id: script.opvragen_ebusd_waarden 105 | mode: single 106 | ``` 107 | 108 | 109 | Because of the above script i can see an accurate representation of my boiler: 110 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/914762cc-80db-4694-9353-554484a47544) 111 | 112 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/d7a36f2a-e878-456a-92f5-c23607af984f) 113 | 114 | 115 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/b2f9c4bd-b96a-4ad7-b7f9-e4220140444b) 116 | -------------------------------------------------------------------------------- /frigate-lxc.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | I've tried many different apps to monitor my security camera, but i keep on comming back to Frigate and it's free. 3 | * I found the UI of Shinobi counter-intuitive. Also the live-stream was very much delayed. I chose to switch to Frigate again when the Testflight-period expired of the Shinobi-iOS app. 4 | 5 | # Create container 6 | 1. I used the TTeck Docker script to create the container with: 7 | `bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/docker.sh)"` 8 | 2. During the script i chose "Debian 12", hostname "frigate", disable ipv6 9 | 3. I also chose to make the container "Privileged". This as i intend to give the container access to my GPU. 10 | 4. I also had to choose the option "enabled fuse OverlayFS". This as my Proxmox host is using ZFS. 11 | 5. I choose NOT to install "Portainer" or the "Portainer agent" 12 | 6. I chose to install "Docker Compose" 13 | 14 | # Bind mounts 15 | 1. Stop the created container 16 | 2. Make a directory for storage on the proxmox host via the Proxmox shell: `mkdir /root/frigate` 17 | 2. Also in the Proxmox shell configure the mount for storage on the container: `pct set 211 -mp0 /root/frigate,mp=/cctv_clips` 18 | 3. Add an mount to passthrough the GPU: `nano /etc/pve/lxc/211.conf` 19 | 4. Add the following line: `lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0`. I also had to add the environment variable "LIBVA_DRIVER_NAME" in the docker-compose.yaml file. This to allow my AMD Ryzen 4800H CPU to hardware accelerate video processing. 20 | 5. I chose to remove mounting of USB-devices from the LXC configuration file. This as i will not use that. 21 | 6. Choose to start the container with: `pct start 211` 22 | 23 | 24 | # Install Frigate 25 | 1. Via the Proxmox Web-UI open the console of the created container 26 | 2. In the console, run: `cd /opt` 27 | 3. Create a docker compose file: `nano docker-compose.yaml` and put this in this file 28 | ``` 29 | version: '3.9' 30 | 31 | services: 32 | 33 | frigate: 34 | container_name: frigate 35 | privileged: true 36 | restart: unless-stopped 37 | image: ghcr.io/blakeblackshear/frigate:stable 38 | shm_size: "128mb" 39 | devices: 40 | - /dev/dri/renderD128 41 | volumes: 42 | - /etc/localtime:/etc/localtime:ro 43 | - /opt/frigate/config:/config:ro 44 | - /cctv_clips:/media/frigate 45 | - type: tmpfs 46 | target: /tmp/cache 47 | tmpfs: 48 | size: 1000000000 49 | ports: 50 | - "5000:5000" 51 | - "1935:1935" # RTMP feeds 52 | environment: 53 | FRIGATE_RTSP_PASSWORD: "myPassword" 54 | LIBVA_DRIVER_NAME: "radeonsi" 55 | ``` 56 | 57 | # Continue 58 | 1. Run: `mkdir -p /opt/frigate/config` 59 | 1. Run: `cd /opt` 60 | 2. Run: `docker compose pull` 61 | 3. Run: `nano /opt/frigate/config/config.yml` 62 | 4. Put this in the file: 63 | 64 | ``` 65 | mqtt: 66 | enabled: false 67 | ffmpeg: 68 | hwaccel_args: preset-vaapi 69 | detectors: 70 | coral: 71 | type: edgetpu 72 | device: usb 73 | #Global Object Settings 74 | objects: 75 | track: 76 | - person 77 | filters: 78 | person: 79 | min_area: 5000 80 | max_area: 100000 81 | cameras: 82 | FrontCam: 83 | ffmpeg: 84 | inputs: 85 | # High Resolution Stream 86 | - path: rtsp://192.168.22.1:7447/P6C9GcVoZ8mRmYor 87 | roles: 88 | - record 89 | # Low Resolution Stream 90 | - path: rtsp://192.168.22.1:7447/s0Wju46GtlXua3J4 91 | roles: 92 | - detect 93 | detect: 94 | width: 480 95 | height: 360 96 | fps: 24 97 | ``` 98 | 99 | 1. Run: `docker compose pull -d` 100 | 101 | 102 | 103 | Based on: 104 | * https://www.homeautomationguy.io/blog/running-frigate-on-proxmox 105 | * https://github.com/blakeblackshear/frigate/discussions/1111 106 | 107 | 108 | Todo: 109 | I suspect this also needs to be added to the 211.conf file: 110 | ``` 111 | lxc.cgroup2.devices.allow: c 226:128 rwm 112 | ``` 113 | -------------------------------------------------------------------------------- /openwrt-802.11k.md: -------------------------------------------------------------------------------- 1 | For a while i've used Usteer and Dawn to enable devices to switch between Access-Points. Modern devices would roam using 802.11k and 802.11r and legacy devices would be kicked upon bad-connections. 2 | 3 | I was doing experimentation with `ubus` and noticed the ability to call `rrm_nr_list` to retrieve the list of WiFi-networks to be available for roaming. I think a static list of networks would be sufficient. 4 | I have 4 access-points in my house with the same SSID for 2g and 5g bands. So devices should already be able to roam automatically. But wihout 802.11r a new handshake would probably need to be made. 5 | 6 | I have configured the radio's to align with the names of the bands: `2g` and `5g` instead of (phy0-ap0, phy1-ap0). 7 | 8 | Check if 802.11k and 802.11v is enabled on your access-points, by running: 9 | ``` 10 | ubus call hostapd.5g get_status 11 | ubus call hostapd.2g get_status 12 | ``` 13 | 14 | You can enable with: 15 | ``` 16 | ubus call hostapd.5g bss_mgmt_enable '{ "neighbor_report": true, "beacon_report": true, "link_measurements": true, "bss_transition": true }' 17 | ``` 18 | 19 | ``` 20 | { 21 | "status": "ENABLED", 22 | "bssid": "90:9f:22:0d:97:bf", 23 | "ssid": "WiFiForMe", 24 | "freq": 5320, 25 | "channel": 64, 26 | "op_class": 128, 27 | "beacon_interval": 100, 28 | "bss_color": 8, 29 | "phy": "phy1", 30 | "rrm": { 31 | "neighbor_report_tx": 13 32 | }, 33 | "wnm": { 34 | "bss_transition_query_rx": 0, 35 | "bss_transition_request_tx": 0, 36 | "bss_transition_response_rx": 0 37 | }, 38 | "airtime": { 39 | "time": 6528591, 40 | "time_busy": 454027, 41 | "utilization": 18 42 | }, 43 | "dfs": { 44 | "cac_seconds": 0, 45 | "cac_active": false, 46 | "cac_seconds_left": 0 47 | } 48 | } 49 | 50 | ``` 51 | 52 | 53 | For all your access-points you need to retrieve some info of the interfaces by running: 54 | ``` 55 | ubus call hostapd.5g rrm_nr_get_own 56 | ubus call hostapd.2g rrm_nr_get_own 57 | ``` 58 | 59 | 60 | 61 | Using the info i retrieved from my Access-Points i created the following script: 62 | ```/root/rrm.sh 63 | ssid="WiFiForMe" 64 | ap_beneden=[\"f8:0d:a9:3a:19:ba\",\"$ssid\",\"f80da93a19baef5900008088090603028a00\"],[\"f8:0d:a9:3a:19:b9\",\"$ssid\",\"f80da93a19b9ef4900005101070603000100\"] 65 | ap_keuken=[\"90:9f:22:0d:97:bf\",\"$ssid\",\"909f220d97bfef5900008040090603023a00\"],[\"90:9f:22:0d:97:be\",\"$ssid\",\"909f220d97beef4900005103070603000300\"] 66 | ap_washok=[\"d4:1a:d1:18:87:01\",\"$ssid\",\"d41ad1188701ef5900008040090603023a00\"],[\"d4:1a:d1:18:87:00\",\"$ssid\",\"d41ad1188700ef4900005106070603000600\"] 67 | ap_zolder=[\"f8:0d:a9:3a:01:01\",\"$ssid\",\"f80da93a0101ef5900008040090603023a00\"],[\"f8:0d:a9:3a:00:00\",\"$ssid\",\"f80da93a0000ef490000510d070603000d00\"] 68 | 69 | # Remove current Access-Point from $list. This to not advertise itself. 70 | list=[$ap_beneden,$ap_zolder,$ap_washok,$ap_keuken] 71 | 72 | ubus call hostapd.5g rrm_nr_set '{"list": '$list' }' 73 | ubus call hostapd.2g rrm_nr_set '{"list": '$list' }' 74 | ``` 75 | The script will register 5g and 2g of each Access-Point and assigns them both bands. 76 | 77 | Check using: 78 | ``` 79 | ubus call hostapd.5g rrm_nr_list 80 | ubus call hostapd.2g rrm_nr_list 81 | ``` 82 | 83 | ``` 84 | more /var/run/hostapd-ph0.conf 85 | ``` 86 | 87 | In Startup: `sleep 10 && /root/rrm.sh &` 88 | 89 | 90 | https://github.com/simonyiszk/openwrt-rrm-nr-distributor 91 | 92 | 93 | ``` 94 | root@AP-Keuken:~# hostapd_cli -i 5g show_neighbor 95 | d4:1a:d1:18:87:00 ssid=57694669466f724d65 nr=d41ad1188700ef4900005106070603000600 96 | d4:1a:d1:18:87:01 ssid=57694669466f724d65 nr=d41ad1188701ef5900008040090603023a00 97 | f8:0d:a9:3a:00:00 ssid=57694669466f724d65 nr=f80da93a0000ef490000510d070603000d00 98 | f8:0d:a9:3a:01:01 ssid=57694669466f724d65 nr=f80da93a0101ef5900008040090603023a00 99 | f8:0d:a9:3a:19:b9 ssid=57694669466f724d65 nr=f80da93a19b9ef4900005101070603000100 100 | f8:0d:a9:3a:19:ba ssid=57694669466f724d65 nr=f80da93a19baef5900008088090603028a00 101 | 90:9f:22:0d:97:bf ssid=57694669466f724d65 nr=909f220d97bfef5900008040090603023a00 stat 102 | ``` 103 | -------------------------------------------------------------------------------- /zabbix-mqtt.md: -------------------------------------------------------------------------------- 1 | # Monitoring MQTT with Zabbix 2 | 3 | ## MQTT-plugin 4 | The Zabbix-agent2 version has support for MQTT using the [MQTT-plugin](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mqtt_plugin). 5 | I've decided that i wanted to use the agent within my Zabbix-LXC-container would be the best instance to have it monitor MQTT. 6 | 7 | ### Install Zabbix-agent2 in Zabbix-LXC-container 8 | My Zabbix-LXC-container was setup with the older Zabbix-agent (v1) which does not support the MQTT-plugin. This meant that i had to switch from the currently installed agent (v1) and to install the new agent (v2). 9 | 10 | I disabled the service of the current intstalled agent (v1): 11 | ``` 12 | systemctl stop zabbix-agent 13 | systemctl disable zabbix-agent 14 | ``` 15 | 16 | I installed and enabled the new agent (v2): 17 | ``` 18 | apt install -y zabbix-agent2 19 | systemctl enable zabbix-agent2 20 | ``` 21 | 22 | I renamed the example provisioned `mqtt.conf` file: 23 | ``` 24 | mv /etc/zabbix/zabbix_agent2.d/plugins/mqtt.conf /etc/zabbix/zabbix_agent2.d/plugins/mqtt.conf.org 25 | ``` 26 | 27 | I created a new `mqtt.conf` file: 28 | ``` 29 | nano /etc/zabbix/zabbix_agent2.d/plugins/mqtt.conf 30 | ``` 31 | And put this in the file: 32 | ``` 33 | Plugins.MQTT.Sessions.hassaddon.Url=tcp://192.168.178.9:1883 34 | Plugins.MQTT.Sessions.hassaddon.Topic=$SYS/broker/clients/active 35 | Plugins.MQTT.Sessions.hassaddon.User=mosquitto 36 | Plugins.MQTT.Sessions.hassaddon.Password=Passw0rd! 37 | ``` 38 | I'm not actually sure about the value of the topic. 39 | 40 | I restarted the agent (v2) service: 41 | ``` 42 | systemctl restart zabbix-agent2 43 | systemctl status zabbix-agent2 44 | ``` 45 | 46 | If everything went well, uninstall the old agent (v1): 47 | ``` 48 | apt purge zabbix-agent 49 | apt autoremove 50 | ``` 51 | 52 | ## Create the item "Broker clients active" 53 | These steps describe how to create an item which pulls data from your MQTT-broker into Zabbix via the agent: 54 | 1. In Zabbix i navigated to "Data collection" > "Hosts" 55 | 2. For the entry of my Zabbix server i chose for the link `Items` 56 | 3. In the top-right-corner i chose for the "Create item" button. 57 | 4. I enter the following values for the fields: 58 | * Name: `Broker clients active` 59 | * Type: `Zabbix agent (active)` 60 | * Key: `mqtt.get["hassaddon","$SYS/broker/clients/active"]` 61 | * Type of information: `Numeric (unsigned)` 62 | * Enabled: `checked` 63 | 5. I checked the checkbox in front of the newly item and clicked the buttons "Enable" and "Execute now" at the bottom of the screen. 64 | 65 | ## Create the trigger "Mosquitto: Active clients has changed" 66 | These steps describe how to create a trigger which will raise a problem if the item-value changes: 67 | 1. In Zabbix i navigated to "Data collection" > "Hosts" 68 | 2. For the entry of my Zabbix server i chose for the link `Triggers` 69 | 3. In the top-right-corner i chose for the "Create trigger" button. 70 | 4. I enter the following values for the fields: 71 | * Name: `Mosquitto: Active clients has changed` 72 | * Event name: `Mosquitto: Active clients has changed` 73 | * Operational data: `From {ITEM.LASTVALUE1} to {ITEM.LASTVALUE2}` 74 | * Severity: `Warning` 75 | * Expression: `last(/Zabbix server/mqtt.get["hassaddon","$SYS/broker/clients/active"],#1)<>last(/Zabbix server/mqtt.get["hassaddon","$SYS/broker/clients/active"],#2)` 76 | * OK event generation: `None` 77 | * Allow manual close: `checked` 78 | * Enabled: `checked` 79 | 80 | 81 | 82 | ## Other items 83 | I also create items for the following MQTT topics.. 84 | 85 | ### Item: EbusD ebus running 86 | * Name: `EbusD ebus running` 87 | * Type: `Zabbix agent (active)` 88 | * Key: `mqtt.get["hassaddon","ebusd/global/running"]` 89 | * Type of information: `Text` 90 | * Enabled: `checked` 91 | 92 | ### Item: EBusD Ebus signal 93 | * Name: `EbusD ebus running` 94 | * Type: `Zabbix agent (active)` 95 | * Key: `mqtt.get["hassaddon","ebusd/global/signal"]` 96 | * Type of information: `Text` 97 | * Enabled: `checked` 98 | 99 | ### Item: EbusD update check 100 | * Name: `EbusD update check` 101 | * Type: `Zabbix agent (active)` 102 | * Key: `mqtt.get["hassaddon","ebusd/global/updatecheck"]` 103 | * Type of information: `Text` 104 | * Enabled: `checked` 105 | 106 | ### Item: Frigate available 107 | * Name: `Frigate available` 108 | * Type: `Zabbix agent (active)` 109 | * Key: `mqtt.get["hassaddon","frigate/available"]` 110 | * Type of information: `Text` 111 | * Enabled: `checked` 112 | 113 | ## Other triggers 114 | 115 | ### Trigger: Frigate available 116 | * Name: `Frigate available` 117 | * Event name: `Frigate available: not online` 118 | * Severity: `High` 119 | * Expression: `last(/Zabbix server/mqtt.get["hassaddon","frigate/available"])<>"online"` 120 | * OK event generation: `Expression` 121 | * Allow manual close: `UN-checked` 122 | * Description: `Frigate is not available` 123 | * Enabled: `checked` 124 | 125 | -------------------------------------------------------------------------------- /zabbix-debian-updating.md: -------------------------------------------------------------------------------- 1 | # Check for Debian updates on machine 2 | 3 | ## Configure on Debian machine 4 | 5 | Open a terminal on the Debian machines you want to check for updates on. 6 | 7 | Install the required packages: 8 | ``` 9 | apt-get install unattended-upgrades apt-listchanges 10 | ``` 11 | 12 | Now create there a configuration file: 13 | ``` 14 | nano /etc/zabbix/zabbix_agent2.d/90-debian-updates.conf 15 | ``` 16 | Give that file the following content: 17 | ``` 18 | UserParameter=debian_updates.package,apt-get upgrade -s | grep -c ^Inst 19 | UserParameter=debian_updates.security,apt-get upgrade -s | grep ^Inst | grep -c security 20 | ``` 21 | Restart the service: 22 | ``` 23 | systemctl restart zabbix-agent2 24 | ``` 25 | 26 | ## Import template in Zabbix 27 | Create a file on your desktop with the follow contents: 28 | ``` 29 | 30 | 31 | 6.0 32 | 2023-02-20T08:27:01Z 33 | 34 | 35 | 846977d1dfed4968bc5f8bdb363285bc 36 | Templates/Operating systems 37 | 38 | 39 | 40 | 108 | 109 | 110 | ``` 111 | 112 | Open web WebUI of your Zabbix instance and navigate to "Data collection" > "Templates". 113 | Click the "Import" button at the top-right. Select the file you created on your desktop. 114 | Now assign the template to the hosts which you want to check for available updates. 115 | 116 | # Script "Apt full-upgrade" 117 | * Name: `Apt full-upgrade` 118 | * Scope: `Manual host action` 119 | * Type: `Script` 120 | * Execute on: `Zabbix agent` 121 | * Commands: `apt update && apt full-upgrade` 122 | * Host group: `Selected` `Linux servers` 123 | * User group: `Zabbix administrators` 124 | * Required host permissions: `Write` 125 | * Enable confirmation: `checked` 126 | * Confirmation text: `Are you sure you want to do a full-upgrade?` 127 | 128 | # Allow running commands on Linux server 129 | Allow running commands on a machine: 130 | 1. Edit configuration file: `nano /etc/zabbix/zabbix_agent2.conf` 131 | 2. Add at the bottom of the file: `AllowKey=system.run[*]` 132 | 133 | # Run zabbix-agent2 as root 134 | Open SSH terminal on a machine you want to run commands on: 135 | ``` 136 | ssh root@192.168.178.xxx 137 | ``` 138 | We are gonna edit the configuration of the zabbix-agent2 service: 139 | ``` 140 | systemctl edit zabbix-agent2 141 | ``` 142 | Add at the specified line: 143 | ``` 144 | [Service] 145 | User=root 146 | Group=root 147 | ``` 148 | 149 | Restart service: 150 | ``` 151 | systemctl daemon-reload 152 | systemctl restart zabbix-agent2 153 | ``` 154 | -------------------------------------------------------------------------------- /proxmox-lxc-nixos-desktop.md: -------------------------------------------------------------------------------- 1 | # NixOS KDE/Plasma desktop in a LXC-container on Proxmox 2 | My preference is to re-use as much as possible of my tech-stuff. More tech-stuff means more effort to keep things working. 3 | This preference resulted in me running a small mini pc for my smart-home, but also using that pc for desktop usage. 4 | Currently i'm running a [Minisforum](https://www.minisforum.com/) um4800xt mini-pc. 5 | This mini-pc is running Proxmox as it's host-os. In VMs/LXCs i'm running: Frigate, Home assistant, OPNsense, Immich and more... 6 | 7 | Instead of having a seperate machine to run as a desktop-computer, i'm running full Linux Desktop environments also on this mini-pc. The desktops having full GPU access and have HDMI output for video and audio. 8 | It's kind-of mind-boggling what kind of magic is behind enabling this ability. 9 | 10 | For a long while i've creating my desktop environment based on Debian, but recently felt comfortable to try it using NixOS. I'm happy to share my knowledge/experience how to achieve this. 11 | 12 | ## How? 13 | It all boils down to running a LXC-container with these properties: 14 | * Devices should be available for the Proxmox-host (thus device-drivers should be installed) 15 | * An Privileged LXC-container with extra low-level privileges 16 | * Passing through the device-files of the host to the LXC-container. 17 | 18 | ## Know issues 19 | * Sometimes the screen blacks-out for a while when i move my mouse. Currently i don't why this happens. I've noticed that this happens when i move my mouse on the login-screen (SDDM-greeter), but also when i move my mouse when making a snapshot with Spectacle. 20 | * In the log (`journalctl -ef`) quite some errors are logged because of some services not being available. 21 | 22 | ## Privileges 23 | For running a full desktop, the following configuration is needed: 24 | ``` 25 | lxc.apparmor.profile: unconfined 26 | lxc.cap.drop: 27 | lxc.cap.drop: sys_time sys_module sys_rawio 28 | lxc.cgroup2.devices.allow: a 29 | lxc.mount.auto: cgroup:rw 30 | lxc.mount.auto: sys:rw 31 | ``` 32 | 33 | ## Device-files 34 | 35 | ### Display passthrough 36 | It all starts with passing through the device-files of the display to the LXC-container. These device-files are in [/dev/dri/](https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure) of your Proxmox-host. 37 | To "see" these device-files, you can connect with the Console/Shell of your Proxmox-host and run: `ls /dev/dri -lai`, which should display something like this: 38 | ``` 39 | 949 drwxr-xr-x 3 root root 100 Jun 1 00:14 . 40 | 1 drwxr-xr-x 19 root root 4740 Jun 11 08:57 .. 41 | 961 drw-rw---- 2 root root 80 Jun 11 08:57 by-path 42 | 951 crw-rw----+ 1 root video 226, 1 Jun 11 08:57 card1 43 | 950 crw-rw-rw-+ 1 root 303 226, 128 Jun 11 08:57 renderD128 44 | ``` 45 | The device-files "card1" and "renderD128" are related and for the single display-device my mini-pc has. If you have more display-devices, you should see more "card*" and "renderD*" entries. 46 | The name "card1" is somewhat weird, previously i had the name "card0" here. I don't know why that changed on my machine. 47 | It's important to take notice of the major device-number" `226`. As i only have one device, i've chosen to passthrough the whole `/dev/dri/`-folder. 48 | The passthrough is done using this LXC-configuration snippet: 49 | ``` 50 | lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 51 | lxc.cgroup2.devices.allow: c 226:* rwm 52 | ``` 53 | When you got your LXC-container up and running, doing a `ls /dev/dri -lai` in your LXC container should display something like this: 54 | ``` 55 | 949 drwxr-xr-x 3 root root 100 1 jun 00:14 . 56 | 1 drwxr-xr-x 13 root root 800 11 jun 08:57 .. 57 | 961 drw-rw---- 2 root root 80 11 jun 08:57 by-path 58 | 951 crw-rw----+ 1 root 44 226, 1 11 jun 08:57 card1 59 | 950 crw-rw-rw-+ 1 root render 226, 128 11 jun 08:57 renderD128 60 | ``` 61 | As you can see the output is almost the same as the output we got on the Proxmox-host itself. 62 | The only difference is that in the LXC-container the groupid "44" is displayed instead of the groupname "video", but this is not important or an issue. 63 | 64 | ## Sound passthrough 65 | The passthrough of the sound-devices is the same procedure as the "Display passthrough". 66 | On the Console/Shell of your Proxmox-host run: `ls /dev/dri -lai`, which should display something like this: 67 | ``` 68 | 580 drwxr-xr-x 3 root root 300 Jun 1 00:14 . 69 | 1 drwxr-xr-x 19 root root 4740 Jun 11 08:57 .. 70 | 921 drwxr-xr-x 2 root root 80 Jun 11 08:57 by-path 71 | 919 crw-rw----+ 1 root audio 116, 7 Jun 11 08:57 controlC0 72 | 930 crw-rw----+ 1 root audio 116, 11 Jun 11 08:57 controlC1 73 | 909 crw-rw----+ 1 root audio 116, 6 Jun 11 08:57 hwC0D0 74 | 927 crw-rw----+ 1 root audio 116, 10 Jun 11 08:57 hwC1D0 75 | 905 crw-rw----+ 1 root audio 116, 2 Jun 11 08:57 pcmC0D3p 76 | 906 crw-rw----+ 1 root audio 116, 3 Jun 11 08:57 pcmC0D7p 77 | 907 crw-rw----+ 1 root audio 116, 4 Jun 11 08:57 pcmC0D8p 78 | 908 crw-rw----+ 1 root audio 116, 5 Jun 11 08:57 pcmC0D9p 79 | 926 crw-rw----+ 1 root audio 116, 9 Jun 11 08:57 pcmC1D0c 80 | 925 crw-rw----+ 1 root audio 116, 8 Jun 11 08:57 pcmC1D0p 81 | 582 crw-rw----+ 1 root audio 116, 1 Jun 11 08:57 seq 82 | 581 crw-rw----+ 1 root audio 116, 33 Jun 11 08:57 timer 83 | ``` 84 | The passthrough is done using this LXC-configuration snippet: 85 | ``` 86 | lxc.mount.entry: /dev/snd dev/snd none bind,optional,create=dir 87 | lxc.cgroup.devices.allow: c 116:* rwm 88 | ``` 89 | 90 | 91 | 92 | Passthrough input devices (keyboard, mouse): 93 | ``` 94 | lxc.mount.entry: /dev/input dev/input none bind,optional,create=dir 95 | lxc.cgroup2.devices.allow: c 13:* rwm 96 | ``` 97 | 98 | Passthrough TTY: 99 | ``` 100 | lxc.tty.max: 6 101 | 102 | lxc.cgroup2.devices.allow: c 4:* rwm 103 | 104 | lxc.mount.entry: /dev/tty0 dev/tty0 none bind,create=file 0 0 105 | 106 | lxc.mount.entry: /dev/tty7 dev/tty7 none bind,optional,create=file 107 | 108 | lxc.mount.entry: /dev/tty8 dev/tty8 none bind,create=file 0 0 109 | ``` 110 | 111 | Passthough framebuffer: 112 | ``` 113 | lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 114 | lxc.cgroup2.devices.allow: c 29:0 rwm 115 | ``` 116 | 117 | Passthrough fuse: 118 | ``` 119 | lxc.mount.entry: /dev/fuse dev/fuse none bind,create=file,optional 120 | lxc.cgroup2.devices.allow: c 10:229 rwm 121 | ``` 122 | -------------------------------------------------------------------------------- /ryzenadj-on-proxmox.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | I recently bought a [MinisForum UM450XT](https://store.minisforum.de/products/minisforum-venus-series-um560) to be used as my homeserver. The version i bought has got a Ryzen 7 4800H as the cpu. 3 | This CPU is very powerfull but will use up-to 45watt of power. As this machine is 24/7/365 running, making it run as efficiently as possible makes sense. When nobody is at home or during the night the system can be throttled without anybody noticing. After i installed everything i measured around 19watt when running idle (with a few VMs and LXCs). Not too bad, but i wanted to see if i could reduce it anyway. 4 | 5 | # CPU Scaling Governor 6 | I started out with using the [Proxmox VE CPU Scaling Governor script from TTeck](https://tteck.github.io/Proxmox/) to select the Powersave-profile. This did work, but kept the system running idle at 15watt. 7 | 8 | # BIOS setting 9 | In the BIOS i noticed an option with which the CPU TDP can be selected. The system came configured with a TDP of 45watt. I selected a TDP of 15watt which resulted in a lowering the idle usage to around 8watts. Selecting this TDP of course seriously capped the power/speed of the CPU. 10 | 11 | # Powertop 12 | I did try to run `powertop` a few times, but don´t seem to understand how to actually use it. I'll look into it at a later time. 13 | 14 | # RyzenAdj 15 | I came across [RyzenAdj](https://github.com/FlyGoat/RyzenAdj) which allowed for doing the same as the BIOS setting, but then on-the-fly. 16 | 17 | I had to compile the application on my Proxmox host. The instructions were very clear. My preference would be not to install any additional packages on my Proxmox host. Thus i created a script to allow me to For which i used this script: 18 | ``` 19 | apt install build-essential cmake libpci-dev git 20 | git clone https://github.com/FlyGoat/RyzenAdj.git 21 | cd RyzenAdj 22 | git fetch --prune 23 | git pull 24 | rm -r win32 25 | rm -rf build 26 | mkdir build && cd build 27 | cmake -DCMAKE_BUILD_TYPE=Release .. 28 | make 29 | if [ -d ~/.local/bin ]; then ln -s $PWD/ryzenadj ~/.local/bin/ryzenadj && echo "symlinked to ~/.local/bin/ryzenadj"; fi 30 | if [ -d ~/.bin ]; then ln -s $PWD/ryzenadj ~/.bin/ryzenadj && echo "symlinked to ~/.bin/ryzenadj"; fi 31 | if [ -d /usr/local/bin ]; then ln -s $PWD/ryzenadj /usr/local/bin/ryzenadj && echo "symlinked to /usr/local/bin/ryzenadj"; fi 32 | ``` 33 | 34 | Running this command would make the system run at a very low power usage CPU TDP of 1watt: 35 | ``` 36 | ./ryzenadj --stapm-limit=1000 --fast-limit=1000 --slow-limit=1000 --tctl-temp=90 --info --power-saving 37 | ``` 38 | 39 | Running this command would make the system run at higher power usage with a CPU TDP of 45watt: 40 | ``` 41 | ./ryzenadj --stapm-limit=45000 --fast-limit=45000 --slow-limit=45000 --tctl-temp=90 --info --max-performance 42 | ``` 43 | 44 | 45 | # Benchmarking 46 | For comparing the various scenario's i used the built-in benchmark functionality of 7zip. Which i installed with: 47 | ``` 48 | apt install -y 7zip 49 | ``` 50 | 51 | To run a benchmark i used the following command on the Proxmox host via the Shell: 52 | ``` 53 | 7zz b 54 | ``` 55 | 56 | The first result i got was: 57 | ``` 58 | root@pve:~# 7zz b 59 | 60 | 7-Zip (z) 22.01 (x64) : Copyright (c) 1999-2022 Igor Pavlov : 2022-07-15 61 | 64-bit locale=en_US.UTF-8 Threads:16 62 | 63 | Compiler: 12.2.0 GCC 12.2.0 64 | Linux : 6.5.11-4-pve : #1 SMP PREEMPT_DYNAMIC PMX 6.5.11-4 (2023-11-20T10:19Z) : x86_64 65 | PageSize:4KB THP:madvise hwcap:2 hwcap2:2 66 | AMD Ryzen 7 4800H with Radeon Graphics (860F01) 67 | 68 | 1T CPU Freq (MHz): 386 388 391 392 391 389 391 69 | 8T CPU Freq (MHz): 788% 383 787% 383 70 | 71 | RAM size: 15415 MB, # CPU hardware threads: 16 72 | RAM usage: 3559 MB, # Benchmark threads: 16 73 | 74 | Compressing | Decompressing 75 | Dict Speed Usage R/U Rating | Speed Usage R/U Rating 76 | KiB/s % MIPS MIPS | KiB/s % MIPS MIPS 77 | 78 | 22: 6310 1103 557 6139 | 54633 1272 366 4659 79 | 23: 5922 1104 546 6035 | 51009 1203 367 4413 80 | 24: 5686 1085 563 6114 | 51079 1220 367 4482 81 | 25: 5496 1077 582 6275 | 49455 1202 366 4400 82 | ---------------------------------- | ------------------------------ 83 | Avr: 5854 1092 562 6141 | 51544 1224 367 4488 84 | Tot: 1158 464 5315 85 | ```` 86 | 87 | ``` 88 | root@pve:~# ryzenadj/RyzenAdj/build/ryzenadj --info 89 | CPU Family: Renoir 90 | SMU BIOS Interface Version: 18 91 | Version: v0.14.0 92 | PM Table Version: 370005 93 | | Name | Value | Parameter | 94 | |---------------------|-----------|--------------------| 95 | | STAPM LIMIT | 1.000 | stapm-limit | 96 | | STAPM VALUE | 4.230 | | 97 | | PPT LIMIT FAST | 1.000 | fast-limit | 98 | | PPT VALUE FAST | 4.239 | | 99 | | PPT LIMIT SLOW | 1.000 | slow-limit | 100 | | PPT VALUE SLOW | 3.923 | | 101 | | StapmTimeConst | 275.000 | stapm-time | 102 | | SlowPPTTimeConst | 5.000 | slow-time | 103 | | PPT LIMIT APU | 54.000 | apu-slow-limit | 104 | | PPT VALUE APU | 3.923 | | 105 | | TDC LIMIT VDD | 58.000 | vrm-current | 106 | | TDC VALUE VDD | 0.780 | | 107 | | TDC LIMIT SOC | 15.000 | vrmsoc-current | 108 | | TDC VALUE SOC | 1.292 | | 109 | | EDC LIMIT VDD | 96.000 | vrmmax-current | 110 | | EDC VALUE VDD | 7.501 | | 111 | | EDC LIMIT SOC | 20.000 | vrmsocmax-current | 112 | | EDC VALUE SOC | 0.000 | | 113 | | THM LIMIT CORE | 90.000 | tctl-temp | 114 | | THM VALUE CORE | 29.657 | | 115 | | STT LIMIT APU | 0.000 | apu-skin-temp | 116 | | STT VALUE APU | 0.000 | | 117 | | STT LIMIT dGPU | 0.000 | dgpu-skin-temp | 118 | | STT VALUE dGPU | 0.000 | | 119 | | CCLK Boost SETPOINT | 95.000 | power-saving / | 120 | | CCLK BUSY VALUE | 99.615 | max-performance | 121 | ``` 122 | 123 | Retrieving the Scaling Governor with: 124 | ``` 125 | cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 126 | ``` 127 | 128 | # Benchmark results 129 | | Scaling governor | Idle watt | Benchmarking | stapm-limit | fast-limit | slow-limit | threads | 8T MHZ | AVG Compressing MIPS | AVG Decompressing MIPS | 130 | |------------------|-----------|--------------|--------------|-------------|------------|---------|--------|----------------------|------------------------| 131 | | ondemand | 9.3w | 10.5w | 45.000 | 45.000 | 100 | 16 | 379 | 6.056 | 4.401 | 132 | | ondemand | 8.7w | 11.0w | 1.000 | 1.000 | 1.000 | 16 | 380 | 6.001 | 4.380 | 133 | | ondemand | 15.4w | 30.4w | 45.000 | 45.000 | 4.000 | 16 | 378 | 42.954 | 39.411 | 134 | | ondemand | 15.6w | 30.4w | 45.000 | 45.000 | 15.000 | 16 | 3.793 | 42.954 | 39.411 | 135 | | ondemand | 11.6w | 71.1w | 45.000 | 45.000 | 45.000 | 16 | 3.017 | 47.122 | 53.957 | 136 | | powersave | 11.6w | 18.1w | 45.000 | 45.000 | 45.000 | 16 | 1.381 | 23.744 | 18.329 | 137 | | performance | 13.1w | 73.4w | 45.000 | 45.000 | 45.000 | 16 | 4.207 | 49.404 | 55.004 | 138 | 139 | With these results i'm not sure what the best settings are. 140 | A "slow-limit" below 4000 doesn't have any impact. 141 | I´m unable to notice any difference with the "stapm-limit" and "fast-limit" parameters. 142 | In the table of "Supported Models" my "Renoir" CPU-model is stated that "stapm-limit" does not do anything. 143 | -------------------------------------------------------------------------------- /homeassistant-ebusd-sensor-names.md: -------------------------------------------------------------------------------- 1 | When using EBusD via MQTT, i got a lot of cryptic-named entities in Home Assistant. 2 | In the following table i provided more descriptive entity names for the Diagnose-fields. 3 | 4 | 5 | | D-code | Default sensor Entity id | Given entity name | Icon | Remark | 6 | |--------|------------------------------|------------------|----------------|-------| 7 | |D.000| ebusd_bai_partloadhckw_power | CV-deellast (D.000) | | | 8 | |D.001| ebusd_bai_wppostruntime_minutes0 | Nalooptijd interne pomp voor CV-bedrijf (D.001) | | | 9 | |D.002| ebusd_bai_blocktimehcmax_minutes0 | Maximum branderwachttijd verwarming (D.002) | | | 10 | |D.003| ebusd_bai_hwctemp_temp | Warmwater temperatuur gemeten (D.003) | | | 11 | |D.004| ebusd_bai_storagetemp_temp | Meetwaarde van de warmwatersensor (D.004) | | | 12 | |D.005| ebusd_bai_flowtempdesired_temp | Gewenste aanvoertemperatuur (D.005) | | | 13 | |D.006| ebusd_bai_hwctempdesired_temp | Gewenste waarde warmwatertemperatuur (D.006) | | | 14 | |D.007| ebusd_bai_storagetempdesired_temp | Gewenste waarde warmestarttemperatuur (D.007) | | | 15 | |D.008| # niets | | | 16 | |D.009| ebusd_bai_extflowtempdesiredmin_temp | Gewenste waarde van externe eBUS thermostaat (D.009) | | | 17 | |D.010| ebusd_bai_wp_onoff | Status interne pomp (D.010) | | | 18 | |D.011| ebusd_bai_extwp_onoff | Status externe CV-pomp (D.011) | mdi:pump | | 19 | |D.012| ebusd_bai_storageloadpump_percent0 | Status boilerlaadpomp (D.012) | | | 20 | |D.013| ebusd_bai_cirpump_onoff | Status warmwater - circulatiepomp (D.013) | | | 21 | |D.013| ebusd_bai_statuscirpump | Status warmwater - circulatiepomp (D.013) | | | 22 | |D.014| ebusd_bai_pumppowerdesired | Pomp kracht ingesteld (D.014) | | | 23 | |D.015| ebusd_bai_pumppower | Pomp kracht werkelijke waarde (D.015) | | | 24 | |D.016| DCRoomthermostat | Kamerthermostaat 24V DC (D.016) | | | 25 | |D.017| ebusd_bai_returnregulation_onoff | Retour temperatuurregeling verwarming (D.017) | | | 26 | |D.018| ebusd_bai_hcpumpmode | Instelling van de pompmodus (D.018) | mdi:pump | | 27 | |D.019| ebusd_bai_secondpumpmode | Modus van de 2-traps pomp (D.019) | | | 28 | |D.020| ebusd_bai_hwctempmax_temp | Max. instelwaarde voor gewenste boilerwaarde (D.020) | | | 29 | |D.021| 30 | |D.022| ebusd_bai_hwcdemand_yesno | Vraag warm water (D.022) | mdi:hand-water | | 31 | |D.023| ebusd_bai_heatingswitch_onoff | Verwarming geactiveerd (D.023) | | | 32 | |D.024| 33 | |D.025| ebusd_bai_storagereleaseclock_yesno | Warmwaterbereiding vrijgegeven door eBus-thermostaat (D.025) | | | 34 | |D.026| | Aansturing hulprelais | | | 35 | |D.027| ebusd_bai_accessoriesone | Omschakeling relais 1 (D.027) | | Decode error | 36 | |D.028| ebusd_bai_accessoriestwo | Omschakeling relais 2 (D.028) | | Decode error | 37 | |D.029| 38 | |D.030| 39 | |D.031| 40 | |D.032| 41 | |D.033| ebusd_bai_targetfanspeed | Gewenste waarde ventilatortoerental (D.033) | mdi:fan | | 42 | |D.034| ebusd_bai_fanspeed | Actuele waarde ventilatortoerental (D.034) | | | 43 | |D.035| ebusd_bai_positionvalveset | Stand van de driewegklep (D.035) | mdi:valve-open | | 44 | |D.036| ebusd_bai_hwcwaterflow_uin100 | Warmwaterdebiet (D.036) | | | 45 | |D.037| 46 | |D.038| 47 | |D.039| | Zonne-inlooptemperatuur (D.039) | | | 48 | |D.040| ebusd_bai_flowtemp_temp | Aanvoertemperatuur (D.040) | | | 49 | |D.041| ebusd_bai_returntemp_temp | Retourtemperatuur (D.041) | | | 50 | |D.042| 51 | |D.043| 52 | |D.044| ebusd_bai_ionisationvoltagelevel | Gedigitaliseerde ionisatiewaarde (D.044) | | | 53 | |D.045| 54 | |D.046| | Soort pomp 0 (D.046) | | | 55 | |D.047| ebusd_bai_outdoorstempsensor_temp | Buitentemperatuur (D.047) | | | 56 | |D.048| 57 | |D.049| 58 | |D.050| ebusd_bai_fanspeedoffsetmin | Offset voor minimaal toerental (D.050) | | | 59 | |D.051| ebusd_bai_fanspeedoffsetmax | Offset voor maximaal toerental (D.051) | | | 60 | |D.052| 61 | |D.053| 62 | |D.054| 63 | |D.055| 64 | |D.056| 65 | |D.057| 66 | |D.058| ebusd_bai_solpostheat | Activering naverwarming via zonneenergie voor combiproduct (D.058) | | | 67 | |D.059| 68 | |D.060| ebusd_bai_deactivationstemplimiter | Aantal uitschakelingen door temperatuurbegrenzer (D.060) | | | 69 | |D.061| ebusd_bai_deactivationsifc | Aantal storingen branderautomaat (D.061) | | | 70 | |D.062| 71 | |D.063| 72 | |D.064| ebusd_bai_averageignitiontime | Gemiddelde ontstekingstijd (D.064) | mdi:fire | | 73 | |D.065| ebusd_bai_maxignitiontime | Maximale ontstekingstijd (D.065) | | | 74 | |D.066| 75 | |D.067| ebusd_bai_remainingboilerblocktime_minutes0 | Resterende branderwachttijd (D.067) | | | 76 | |D.068| ebusd_bai_counterstartattempts1_temp0 | Mislukte ontstekingen bij 1e poging (D.068) | | | 77 | |D.069| ebusd_bai_counterstartattempts2_temp0 | Mislukte ontstekingen bij 2e poging (D.069) | | | 78 | |D.070| ebusd_bai_valvemode | Instellen stand driewegklep (D.070) | | | 79 | |D.071| ebusd_bai_flowsethcmax_temp | Gewenste waarde max. aanvoertemperatuur verwarming (D.071) | | | 80 | |D.072| ebusd_bai_hwcpostruntime | Nalooptijd interne pomp na boilerlading (D.072) | | | 81 | |D.073| ebusd_bai_warmstartoffset_temp | Gewenste warme start offset (D.073) | | | 82 | |D.074| ebusd_bai_apclegioprotection | Legionellabeveiligingsfunctie actoSTOR (D.074) | | Geen actoSTOR aanwzg | 83 | |D.075| ebusd_bai_storageloadtimemax_minutes0 | Max. laadtijd voor warmwaterboiler zonder eigen regeling (D.075) | | | 84 | |D.076| | Toestelidentificatie (D.076) | | | 85 | |D.077| ebusd_bai_partloadhwckw_power | Begrenzing van het boilerlaadvermogen in kW (D.077) | | Decode error | 86 | | | ebusd_bai_modulationtempdesired | Modulatie temperatuur gevraagd | | ebusd_bai_partloadhwckw_power = % van partloadhcKW | 87 | |D.078| ebusd_bai_flowsethwcmax_temp | Begrenzing van de boilerlaadtemperatuur in °C (D.078) | | | 88 | |D.079| 89 | |D.080| ebusd_bai_hchours_hoursum2 | Bedrijfsuren verwarming (D.080) | | | 90 | |D.081| ebusd_bai_hwchours_hoursum2 | Bedrijfsuren warmwaterbereiding (D.081) | | | 91 | |D.082| ebusd_bai_hcstarts | Aantal branderstarts in CV-bedrijf (D.082) | | | 92 | |D.083| ebusd_bai_hwcstarts | Aantal branderstarts in warmwaterbedrijf (D.083) | | | 93 | |D.084| ebusd_bai_hourstillservice_hoursum2 | Onderhoudsindicatie: aantal uren tot de volgende onderhoudsbeurt (D.084) | | | 94 | |D.085| 95 | |D.086| 96 | |D.087| 97 | |D.088| ebusd_bai_specialadj | Inschakelvertraging voor warmwatertapherkenning via vleugelwiel (D.088) | | # werkt niet | 98 | |D.089| 99 | |D.090| ebusd_bai_ebusheatcontrol_yesno | Status digitale thermostaat (D.090) | | | 100 | |D.091| thermostaat_statusdcf_dcfstate | Status DCF bij aangesloten buitentemperatuurvoeler (D.091) | | | 101 | |D.092| ebusd_bai_apccomstatus | actoSTOR moduleherkenning (D.092) | | | 102 | |D.093| ebusd_bai_dsnoffset | Instelling toestelidentificatie (D.093) | | | 103 | |D.094| | Foutcode historie verwijderen (D.094) | | | 104 | |D.095| | Softwareversie PeBUS-componenten Printplaat (D.095) | | | 105 | |D.096| | Fabrieksinstelling Reset (D.096) | | | 106 | |D.097| ebusd_bai_password | Activering installateurniveau Code (D.097) | | werkt niet | 107 | |D.098| | Waarde van de codeerweerstanden (D.098) | 108 | 109 | 110 | | Other | Name | Icon | 111 | |---------------|-----|------| 112 | | sensor.ebusd_bai_flame | CV brander | mdi:fire | 113 | | sensor.ebusd_bai_gasvalveasicfeedback | CV gas-klep terugkoppeling | | 114 | | sensor.ebusd_bai_gasvalve3uc | CV gas-klep activeer 3 signaal | mdi:ray-start | 115 | | sensor.ebusd_bai_gasvalve | CV gas-klep actief | mdi:valve | 116 | | binary_sensor.ebusd_bai_fluegasvalve_onoff | CV rookgasklep actief | mdi:valve | 117 | | sensor.ebusd_bai_status01_pumpstate | CV pomp actief | mdi:pump | 118 | | sensor.ebusd_bai_templimiter | | | 119 | | sensor.ebusd_bai_statenumber | | | 120 | | sensor.ebusd_bai_status | | | 121 | | sensor.ebusd_bai_pumphours_hoursum2 | CV uren pomp actief | mdi:pump | 122 | | sensor.ebusd_bai_setmode_disablehc | CV verwarming uitgeschakeld | mdi:radiator-off | 123 | | sensor.ebusd_bai_status02_hwcmode | Warm-water circuit geactiveerd | mdi:hand-water | 124 | | sensor.ebusd_bai_blocktimehcmax_minutes0 | CV maximale wachttijd | mdi:timer-sand | 125 | | binary_sensor.ebusd_bai_externalfaultmessage_onoff | CV extern fout bericht | | 126 | | sensor.ebusd_bai_hwcwaterflowmax_uin100 | Warm-water circuit maximale doorstroming | | 127 | | sensor.ebusd_bai_remainingboilerblocktime_minutes0 | Resterende CV wachttijd | | 128 | | sensor.ebusd_bai_targetfanspeedoutput | CV gerealiseerde ventilator doel snelheid | mdi:fan | 129 | | sensor.ebusd_bai_waterpressure_press | Verwarming waterdruk | | 130 | 131 | 132 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/9c1e8cf2-09b0-408d-9ce2-bf953a4720eb) 133 | -------------------------------------------------------------------------------- /frigate-docker-lxc.md: -------------------------------------------------------------------------------- 1 | With these notes it is possible to take the official Frigate (Docker) container and convert it into a fully working Proxmox LXC container. Thus running it without Docker as virtualization layer. The LXC container should not suffer from the issues which are known for having a ZFS filesystem and nested Docker. 2 | 3 | It's actually working :-S 4 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/4dd103e2-8e29-4f74-a359-3fb2d99be532) 5 | 6 | # Initialization 7 | We will using the init-system which is part of the Frigate Docker container. This init-system (`s6-overlay`) manages the several parallel processes for Frigate. Normally in LXC-containers `systemd` is used, but for this container this is not neccesary. 8 | Be aware that the init-system will stop the LXC-container when an error occurs or the configuration is changed. 9 | 10 | # Process 11 | 12 | ## Creating the template 13 | 14 | Create raw LXC container from Docker container image. Run this on your Proxmox host: 15 | ``` 16 | apt install skopeo umoci jq 17 | lxc-create frigate -t oci -- --url docker://ghcr.io/blakeblackshear/frigate:stable 18 | ``` 19 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/833ef741-5e41-45e6-a538-64f58381ee9c) 20 | You will now have a LXC container running which is not managed by Proxmox. The commando `lxc-ls` should now show a container named "frigate" next to the Proxmox managed containers. 21 | The filesystem of the running Frigate container is here: `/var/lib/lxc/frigate/rootfs` 22 | 23 | Change to the rootfs directory of the Frigate LXC container: 24 | ``` 25 | cd /var/lib/lxc/frigate/rootfs/ 26 | ``` 27 | Create the Frigate media and config folders: 28 | ``` 29 | mkdir -p media/frigate 30 | mkdir -p config 31 | ``` 32 | 33 | Edit the init file with: `nano init`. We will be adding some statements to provide DHCP on eth0 in the container. Also we will create a ramdisk for the cache.Add the parts between `# Begin` and `# End` to the file: 34 | ``` 35 | #!/bin/sh -e 36 | 37 | # Begin 38 | /sbin/ip link set dev eth0 up 39 | /sbin/ip link set dev lo up 40 | dhclient 41 | 42 | export S6_LOGGING_SCRIPT="T 1 n0 s10000000 T" 43 | export S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 44 | #export CCACHE_DIR=/root/.ccache 45 | #export CCACHE_MAXSIZE=2G 46 | 47 | mkdir -p /tmp/cache 48 | chmod 777 /tmp/cache 49 | mount -t tmpfs -o size=1024m tmpcache /tmp/cache 50 | 51 | rm -rf /dev/shm 52 | mkdir -p /dev/shm/logs/frigate/ 53 | chmod -R 777 /dev/shm/ 54 | mount -t tmpfs -o size=1024m devshm /dev/shm 55 | # End 56 | 57 | # This is the first program launched at container start. 58 | # We don't know where our binaries are and we cannot guarantee 59 | # that the default PATH can access them. 60 | # So this script needs to be entirely self-contained until it has 61 | # at least /command, /usr/bin and /bin in its PATH. 62 | ... 63 | ``` 64 | 65 | Also add this part between `# Begin` and `# End` to the init file: 66 | ``` 67 | addpath /bin 68 | addpath /usr/bin 69 | addpath /command 70 | 71 | # Begin 72 | addpath /usr/lib/btbn-ffmpeg/bin 73 | addpath /usr/local/go2rtc/bin 74 | addpath /usr/local/nginx/sbin 75 | # End 76 | 77 | export PATH 78 | ... 79 | ``` 80 | Save and close Nano with CTRL-O, , CTRL-X 81 | 82 | For running this LXC container within Proxmox some packages need to be installed in the container rootsfs. 83 | ``` 84 | /usr/sbin/chroot /var/lib/lxc/frigate/rootfs/ apt update 85 | /usr/sbin/chroot /var/lib/lxc/frigate/rootfs/ apt install init isc-dhcp-client -y 86 | ``` 87 | The package `init` might not be needed anymore. 88 | 89 | Lookup in which folder the Proxmox templates are situated by running `cat /etc/pve/storage.cfg`. On my system the output is: 90 | ``` 91 | dir: local 92 | disable 93 | path /var/lib/vz 94 | content vztmpl,backup,iso 95 | 96 | btrfs: local-btrfs 97 | path /var/lib/pve/local-btrfs 98 | content rootdir,vztmpl,images,backup,iso 99 | ``` 100 | In my system the storage named `local` is disabled and the one named `local-btrfs` is used. So i'll be using the path `/var/lib/pve/local-btrfs` in the next command. You might to use path `/var/lib/vz`. If i run `ls /var/lib/pve/local-btrfs` i should see previously downloaded CT templates. 101 | 102 | Create the template file by creating an archive from the rootfs filesystem. This command might take a few minutes: 103 | ``` 104 | ctstorage="/var/lib/pve/local-btrfs" 105 | tar --exclude=dev --exclude=sys --exclude=proc -czf $ctstorage/template/cache/frigate_template.tar.gz ./ 106 | ``` 107 | After creating the Proxmox-LXC-template, you can remove the unmanaged LXC frigate container: 108 | ``` 109 | cd / 110 | lxc-destroy frigate 111 | ``` 112 | 113 | ## Creating the Frigate container in Proxmox 114 | 115 | We can create now create a Promox managed Frigate LXC container. This can be done by using the Proxmox Web UI, but also via the command-line: 116 | ``` 117 | ctid="998" 118 | ctstorage="local-btrfs" 119 | storage="local-btrfs" 120 | pct create $ctid /var/lib/pve/$ctstorage/template/cache/frigate_template.tar.gz \ 121 | -hostname frigate-test -memory 2048 --cores 2 \ 122 | -net0 name=eth0,hwaddr=52:4A:5E:26:58:D8,bridge=vmbr0 \ 123 | -storage $storage -password Passw0rd! \ 124 | --unprivileged 0 --features nesting=1 --cmode console 125 | ``` 126 | ![image](https://github.com/GrumpyMeow/proxmox-tips/assets/12073499/569ed24c-e621-4df4-901c-c4aef24235f7) 127 | 128 | For updating the Frigate container in the future, it's smart to keep data stored outside of the Frigate container. The following command is what i use: 129 | ``` 130 | configpath="/root/frigate" 131 | mediapath="/zpool-storage/media/Frigate" 132 | ctid="998" 133 | mkdir -p $configpath 134 | mkdir -p $mediapath 135 | chmod -R 777 $mediapath 136 | chmod -R 777 $configpath 137 | pct set $ctid -mp0 $configpath,mp=/config/ 138 | pct set $ctid -mp1 $mediapath,mp=/media/frigate 139 | ``` 140 | 141 | In the media folder we bound to the container, we will download a sample video file: 142 | ``` 143 | mediapath="/zpool-storage/media/Frigate" 144 | cd $mediapath 145 | wget -q https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4 146 | ``` 147 | 148 | Here we will be creating an initial configuration file in the folder i've just bound to the container: 149 | ``` 150 | configpath="/root/frigate" 151 | cat >$configpath/config.yml <<'EOL' 152 | detectors: 153 | detector_name: 154 | type: cpu 155 | 156 | mqtt: 157 | enabled: False 158 | 159 | go2rtc: 160 | webrtc: 161 | candidates: 162 | - stun:8555 163 | 164 | cameras: 165 | dummy_camera: 166 | ffmpeg: 167 | inputs: 168 | - path: /media/frigate/person-bicycle-car-detection.mp4 169 | input_args: -re -stream_loop -1 -fflags +genpts 170 | roles: 171 | - detect 172 | 173 | motion: 174 | threshold: 30 175 | lightning_threshold: 0.8 176 | contour_area: 10 177 | frame_alpha: 0.01 178 | frame_height: 50 179 | improve_contrast: False 180 | mqtt_off_delay: 30 181 | 182 | record: 183 | enabled: False 184 | 185 | objects: 186 | track: 187 | - person 188 | - car 189 | - bicycle 190 | EOL 191 | ``` 192 | 193 | Edit the lxc config file with: 194 | ``` 195 | ctid="998" 196 | nano /etc/pve/lxc/$ctid.conf 197 | ``` 198 | 199 | Add in this file: 200 | ``` 201 | lxc.init.cmd: /init 202 | lxc.log.level: 3 203 | lxc.console.logfile: /var/log/frigate.log 204 | ``` 205 | 206 | 207 | ## Starting the container 208 | 209 | Start Proxmox LXC container: 210 | ``` 211 | ctid="998" 212 | pct start $ctid 213 | pct status $ctid 214 | ``` 215 | 216 | In Proxmox you should the logging output of Frigate rolling by on the console of the container. 217 | 218 | You now probably need to get the IP-address of the container. You can do this: 219 | ``` 220 | ctid="998" 221 | pct enter $ctid 222 | ip a 223 | ... 224 | exit 225 | ``` 226 | The container should've received an IP-address via DHCP from your router. 227 | 228 | You should be able to access Frigate with the IP-address on port 5000, for example: `http://192.168.178.156:5000/` 229 | 230 | # Notes 231 | * On the proxmox host a log file is created at: `tail -f /var/log/frigate.log` 232 | * Log files in the container are created at: `cd /dev/shm/logs` 233 | * Frigate S6-overlay files are at: `/etc/s6-overlay/s6-rc.d` 234 | 235 | Resources: 236 | * https://www.buzzwrd.me/index.php/2021/03/10/creating-lxc-containers-from-docker-and-oci-images/ 237 | * https://github.com/pimox/pimox7/issues/160 238 | * https://forum.proxmox.com/threads/permission-denied-failed-to-exec-sbin-init.118710/ 239 | * https://forum.proxmox.com/threads/cant-start-lxc.108036/ 240 | * https://forum.proxmox.com/threads/how-to-migrate-a-regular-lxc-container-to-a-proxmox-lxc-container.24138/ 241 | * https://serverfault.com/questions/731400/how-to-migrate-a-regular-lxc-container-to-a-proxmox-lxc-container 242 | * https://gist.github.com/midoriiro/58b6d16d1578e030e7078917a5872290 243 | * https://github.com/just-containers/s6-overlay 244 | * https://unix.stackexchange.com/questions/119100/cannot-connect-to-any-localhost-connections 245 | 246 | # Hardware acceleration 247 | I'm able to get Hardware-acceleration on my AMD Ryzen 4800h system with the notes below. I have multiple LXC containers which share the Hardware-acceleration of my GPU. This is only possible with LXC containers, not with VMs. 248 | ``` 249 | lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 250 | lxc.cgroup2.devices.allow: c 226:128 rwm 251 | ``` 252 | Add in the Frigate configuration file: 253 | ``` 254 | environment_vars: 255 | LIBVA_DRIVER_NAME=radeonsi 256 | 257 | ffmpeg: 258 | hwaccel_args: preset-vaapi 259 | ``` 260 | # Notes 261 | * After modifying the config via the web-ui. Saving will stop the LXC container. And should manually be started. 262 | -------------------------------------------------------------------------------- /MR60BHA2.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | So i just received from Seeedstudio the [MR60BHA2](https://www.seeedstudio.com/MR60BHA2-60GHz-mmWave-Sensor-Breathing-and-Heartbeat-Module-p-5945.html) mmwave sensor for Breathing and Heartbeat detection. 4 | It comes with pre-flashed with an ESPHome based firmware. 5 | 6 | # Fork of original repository 7 | I created [my own fork](https://github.com/grumpymeow/MR60BHA2_ESPHome_external_components) of the [original repository](https://github.com/limengdu/MR60BHA2_ESPHome_external_components). 8 | This to resolve a few issues. 9 | 10 | ## Hard to upload firmware 11 | At often times it was quite hard to upload a new firmware to the device over-the-air. Quite often no connection could be made from ESPHome to the device. Partly this is caused by the poor wireless connection the device had. 12 | I had to resort to using ESPTool and flash over-the-wire. I eventually added a `yield()` to `loop` function to give ensure the CPU would give more time to other processes. This resolved all timeout issues. 13 | ``` 14 | // main loop 15 | void MR60BHA2Component::loop() { 16 | uint8_t byte; 17 | 18 | // Is there data on the serial port 19 | while (this->available()) { 20 | this->read_byte(&byte); 21 | this->rx_message_.push_back(byte); 22 | if (!this->validate_message_()) { 23 | this->rx_message_.clear(); 24 | } 25 | } 26 | yield(); <= added this 27 | } 28 | ``` 29 | 30 | ## More frame types 31 | At this time 3 time of frame types with data can be processed by the code, but the device itself transmits two additional frame types. In code I added these event-types. Although i didn't bother to implement the decoding as i saw no interesting information. 32 | One of the frame-types transmitted the text `no targets!!!`. 33 | ``` 34 | static const uint16_t UNKNOWN_TYPE_BUFFER = 0x0A13; <== Added this 35 | static const uint16_t UNKNOWN2_TYPE_BUFFER = 0x0100; <== Added this 36 | static const uint16_t BREATH_RATE_TYPE_BUFFER = 0x0A14; 37 | static const uint16_t HEART_RATE_TYPE_BUFFER = 0x0A15; 38 | static const uint16_t DISTANCE_TYPE_BUFFER = 0x0A16; 39 | ``` 40 | and 41 | ``` 42 | void MR60BHA2Component::process_frame_(uint16_t frame_id, uint16_t frame_type, const uint8_t *data, size_t length) { 43 | switch (frame_type) { 44 | case BREATH_RATE_TYPE_BUFFER: 45 | ... 46 | break; 47 | case HEART_RATE_TYPE_BUFFER: 48 | ... 49 | break; 50 | case DISTANCE_TYPE_BUFFER: 51 | ... 52 | break; 53 | case UNKNOWN_TYPE_BUFFER: 54 | break; 55 | case UNKNOWN2_TYPE_BUFFER: 56 | break; 57 | default: 58 | break; 59 | } 60 | } 61 | ``` 62 | 63 | # No distance data 64 | In the current version of the repository there is an error in the decoding of distance. 65 | ``` 66 | case DISTANCE_TYPE_BUFFER: 67 | if (data[0] != 0) { <== changed 68 | if (this->distance_sensor_ != nullptr && length >= 8) { 69 | uint32_t current_distance_int = encode_uint32(data[7], data[6], data[5], data[4]); 70 | float distance_float; 71 | memcpy(&distance_float, ¤t_distance_int, sizeof(float)); 72 | this->distance_sensor_->publish_state(distance_float); 73 | } 74 | } 75 | ``` 76 | 77 | 78 | # YAML-definition 79 | 80 | I currently am using this Yaml-definition. In this definition i added template-sensors for heartrate and breathingrate which expose the minimum, maximum and average values. 81 | For all the sensors i'd added the `timeout`-filter to make the sensor `unavailable` in Home Assistant when nothing is detected for a while. 82 | I also added the `clamp` filter to get rid of noise values. 83 | ``` 84 | substitutions: 85 | name: "slaapsensor" 86 | friendly_name: "Slaapsensor" 87 | timeout: 120s 88 | hrf_name: "Hartslagfrequentie" 89 | brf_name: "Ademfrequentie" 90 | 91 | esphome: 92 | name: "${name}" 93 | friendly_name: "${friendly_name}" 94 | # project: 95 | # name: "seeedstudio.mr60bha2_kit" 96 | # version: "2.0" 97 | platformio_options: 98 | board_upload.maximum_size: 4194304 99 | min_version: "2024.3.2" 100 | 101 | esp32: 102 | board: esp32-c6-devkitc-1 103 | variant: esp32c6 104 | flash_size: 4MB 105 | framework: 106 | type: esp-idf 107 | sdkconfig_options: 108 | CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y 109 | 110 | # Enable logging 111 | logger: 112 | hardware_uart: USB_SERIAL_JTAG 113 | #level: VERY_VERBOSE 114 | level: DEBUG 115 | 116 | api: 117 | reboot_timeout: 0s 118 | 119 | ota: 120 | - platform: esphome 121 | 122 | wifi: 123 | ssid: !secret wifi_ssid 124 | password: !secret wifi_password 125 | fast_connect: false 126 | enable_btm: true 127 | enable_rrm: true 128 | power_save_mode: none 129 | reboot_timeout: 120min 130 | ap: 131 | ssid: "Slaapsensor hotspot" 132 | password: !secret wifi_password 133 | ap_timeout: 5min 134 | 135 | light: 136 | - platform: esp32_rmt_led_strip 137 | id: led_ring 138 | name: "Led" 139 | pin: GPIO1 140 | num_leds: 1 141 | rmt_channel: 0 142 | rgb_order: GRB 143 | chipset: ws2812 144 | 145 | i2c: 146 | sda: GPIO22 147 | scl: GPIO23 148 | scan: true 149 | # frequency: 200kHz 150 | id: bus_a 151 | 152 | uart: 153 | id: uart_bus 154 | baud_rate: 115200 155 | rx_pin: 17 156 | tx_pin: 16 157 | parity: NONE 158 | stop_bits: 1 159 | 160 | seeed_mr60bha2: 161 | id: my_seeed_mr60bha2 162 | 163 | sensor: 164 | - platform: bh1750 165 | name: "Omgevingslicht" 166 | address: 0x23 167 | update_interval: 60s 168 | filters: 169 | - timeout: ${timeout} 170 | - platform: seeed_mr60bha2 171 | breath_rate: 172 | id: brf_raw 173 | name: "${brf_name} ruw" 174 | unit_of_measurement: bpm 175 | internal: false 176 | accuracy_decimals: 2 177 | filters: 178 | - clamp: 179 | min_value: 1 180 | max_value: 40 181 | ignore_out_of_range: true 182 | - timeout: ${timeout} 183 | on_value: 184 | then: 185 | - component.update: brf_avg 186 | - component.update: brf_min 187 | - component.update: brf_max 188 | heart_rate: 189 | id: hrf_raw 190 | name: "${hrf_name} ruw" 191 | unit_of_measurement: bpm 192 | internal: false 193 | accuracy_decimals: 2 194 | filters: 195 | - clamp: 196 | min_value: 40 197 | max_value: 130 198 | ignore_out_of_range: true 199 | - timeout: ${timeout} 200 | on_value: 201 | then: 202 | - component.update: hrf_avg 203 | - component.update: hrf_min 204 | - component.update: hrf_max 205 | distance: 206 | name: "Afstand" 207 | accuracy_decimals: 2 208 | filters: 209 | - exponential_moving_average: 210 | alpha: 0.1 211 | send_every: 1 212 | - timeout: ${timeout} 213 | 214 | # Hartslagfrequentie 215 | - platform: template 216 | id: hrf_avg 217 | name: "${hrf_name}" 218 | accuracy_decimals: 2 219 | unit_of_measurement: bpm 220 | lambda: return id(hrf_raw).state; 221 | filters: 222 | - exponential_moving_average: 223 | alpha: 0.1 224 | send_every: 1 225 | - timeout: ${timeout} 226 | - platform: template 227 | id: hrf_min 228 | name: "${hrf_name} min" 229 | accuracy_decimals: 2 230 | unit_of_measurement: bpm 231 | lambda: return id(hrf_raw).state; 232 | filters: 233 | - min: 234 | window_size: 5 235 | send_every: 1 236 | - timeout: ${timeout} 237 | - platform: template 238 | id: hrf_max 239 | name: "${hrf_name} max" 240 | accuracy_decimals: 2 241 | unit_of_measurement: bpm 242 | lambda: return id(hrf_raw).state; 243 | filters: 244 | - max: 245 | window_size: 5 246 | send_every: 1 247 | - timeout: ${timeout} 248 | 249 | # Ademfrequentie 250 | - platform: template 251 | id: brf_avg 252 | name: "${brf_name}" 253 | accuracy_decimals: 2 254 | unit_of_measurement: bpm 255 | lambda: return id(brf_raw).state; 256 | filters: 257 | - exponential_moving_average: 258 | alpha: 0.1 259 | send_every: 1 260 | - timeout: ${timeout} 261 | - platform: template 262 | id: brf_min 263 | name: "${brf_name} min" 264 | accuracy_decimals: 2 265 | unit_of_measurement: bpm 266 | lambda: return id(brf_raw).state; 267 | filters: 268 | - min: 269 | window_size: 5 270 | send_every: 1 271 | - timeout: ${timeout} 272 | - platform: template 273 | id: brf_max 274 | name: "${brf_name} max" 275 | accuracy_decimals: 2 276 | unit_of_measurement: bpm 277 | lambda: return id(brf_raw).state; 278 | filters: 279 | - max: 280 | window_size: 5 281 | send_every: 1 282 | - timeout: ${timeout} 283 | 284 | 285 | external_components: 286 | - source: 287 | type: git 288 | url: https://github.com/grumpymeow/MR60BHA2_ESPHome_external_components 289 | ref: main 290 | components: [ seeed_mr60bha2 ] 291 | refresh: 0s 292 | ``` 293 | 294 | # Results 295 | 296 | ## 18-12-2024 297 | 298 | ### Distance detected object 299 | The result of the measured distance looks accurate. It detected some tossing and turning of me during my sleep. 300 | ![image](https://github.com/user-attachments/assets/ce65fdb6-d4a6-48c8-84fe-dadbf923b26a) 301 | 302 | ### Light sensor 303 | The result of the measured light looks accurate. At 6:45 a bedside lamp is turned on. From 8:40 and later it's daylight. 304 | ![image](https://github.com/user-attachments/assets/cc2c501f-ea02-439d-bf1f-bbe9da8f8bfa) 305 | 306 | 307 | ### Breathing rate 308 | This is a graph of the raw sensor data. The variation is quite big and hopefully inaccuracy. This as otherwise i might have a severe case of slaap apnea. 309 | ![image](https://github.com/user-attachments/assets/87ac53d9-36f6-45ee-911e-d9aea22a28b8) 310 | 311 | I also do some filtering on the sensor data which results in this chart: 312 | ![image](https://github.com/user-attachments/assets/d0fe9463-e956-4fd7-be95-2454ff7e43db) 313 | 314 | I also expose the min and max of the sensor data. 315 | ![image](https://github.com/user-attachments/assets/1859197a-a593-43ce-ab32-ef5daba49b54) 316 | 317 | 318 | ### Heart rate 319 | This is the chart of the raw and filtered sensor data. The brownish-line is of the raw data. Blue is of the filtered data. 320 | ![image](https://github.com/user-attachments/assets/74a245cd-bb11-4d0a-a899-cf0708e1c05a) 321 | 322 | This is the chart of the min and max sensor data. 323 | ![image](https://github.com/user-attachments/assets/72adb0f6-7574-4c2c-a35b-60f2f0264a6b) 324 | 325 | ### Conclusion 326 | My conclusion at this time is that i need to increase the average over a longer period. As the variation makes it impossible to visually see anything usefull. 327 | 328 | Current filter settings: 329 | ``` 330 | - exponential_moving_average: 331 | alpha: 0.1 332 | send_every: 1 (default=15, i might have used a weird value here) 333 | send_first_at: 1 <=default 334 | 335 | - max/min: 336 | window_size: 5 337 | send_every: 1 338 | ``` 339 | 340 | My new filter settings i'm gonna try: 341 | ``` 342 | - quantile: 343 | window_size: 7 (default=7) 344 | send_every: 4 345 | send_first_at: 3 346 | quantile: .9 347 | 348 | - max/min: 349 | window_size: 20 350 | send_first_at: 1 351 | send_every: 1 352 | ``` 353 | I also chose to increase the timeout from `timeout: 120s` to `timeout: 600s` to get rid of some small gaps in the data. 354 | 355 | There seem to be a [few patterns](https://ouraring.com/blog/sleeping-heart-rate/) which can be seen during sleeping. 356 | It would be fun to eventually see these patterns arise. 357 | 358 | Looking at the data i already suspect that there might not be enough of data to really get usefull insights. 359 | Maybe just like on the Oura-ring page, only three-point-patterns like hammock, slope, hill, etc. We will see. 360 | 361 | I noticed the device crashes on a regular basis which is recognizable by the short lighting of the led. This distorts the filters. So probably better to implement the filters in Home Assistant instead of on the device. 362 | 363 | ## 29-12-2024 364 | Doing the filtering in Home Assistant gives much better results. 365 | 366 | Initially i had configured a moving-average filter with a maximum of 50samples and/or 30minutes. This still gave too much jittery to visually interpret. 367 | The following screenshot is my breathing-frequency for the last 6 nights. The last night i had changed the moving-average filter to 250samples and/or 2hours. 368 | ![image](https://github.com/user-attachments/assets/481c12f8-072a-44bc-96c0-913a26da81bc) 369 | And this is the screenshot of my heart-rate for the last 6 nights. 370 | ![image](https://github.com/user-attachments/assets/12ab6d0b-5a46-4547-8bd7-fcf3491e1d2c) 371 | 372 | This is the chart of my breathing-rate of the last night: 373 | ![image](https://github.com/user-attachments/assets/d46e6894-4a20-4719-ac76-35508683046b) 374 | And the same chart with the raw sensor values in blue overlayed: 375 | ![image](https://github.com/user-attachments/assets/228229f5-075e-4442-a8f9-3e512e40aacb) 376 | 377 | ### Conclusion 378 | I think better results might be retrieved by reducing the number of ourliers which should allow for reducing the strength moving average filter. 379 | -------------------------------------------------------------------------------- /provision-lxc-desktop-from-homeassistant.md: -------------------------------------------------------------------------------- 1 | In conformance to `when you have a hammer, everything is a nail` i have a command in Home Assistant which provisions a fresh desktop environment. 2 | Triggering the [`create_desktop` command](https://github.com/koying/ha-remote-command-line) will create: 3 | * An unprivileged/unconfined LXC container 4 | * Debian v12 LXC is upgraded to v13 5 | * Mounted GPU-devices, USB, sound and low-level devices 6 | * Plasma-desktop with Chromium and other apps i regularly use 7 | 8 | I have this running on my Minisforum UM480xt machine with directly connected monitor. When i start the container, the Proxmox console will automatically switch to the screen of the container. It runs (near?) native using my Proxmox connected monitor: 9 | image 10 | 11 | The only thing i notice that i'm running inside an LXC container is that things like Snap and Flatpak have issues. 12 | 13 | ``` 14 | remote_command_line: 15 | create_desktop: 16 | ssh_user: root 17 | ssh_host: hub.lan 18 | ssh_key: /config/key/id_ed25519 19 | command_timeout: 900 20 | command: | 21 | ctid="800" 22 | ctname="desktop" 23 | user="sander" 24 | password="Passw0rd!" 25 | template="/var/lib/pve/local-btrfs/template/cache/debian-12-standard_12.7-1_amd64.tar.zst" 26 | 27 | logger "Create container $ctid" 28 | pct create $ctid $template \ 29 | --storage "local-btrfs" \ 30 | --rootfs volume=local-btrfs:16 \ 31 | --start false \ 32 | --timezone host \ 33 | --unprivileged 0 \ 34 | --cores 4 \ 35 | --features nesting=1,fuse=1,force_rw_sys=1,mount=sysfs\;cgroup \ 36 | --tty=6 \ 37 | --hostname $ctname \ 38 | --memory 4096 \ 39 | --password $password \ 40 | --onboot 0 \ 41 | --arch amd64 \ 42 | --ostype debian \ 43 | --force 1 \ 44 | --description "Big Beautiful Desktop" \ 45 | --hookscript local:snippets/chvt-desktop.pl \ 46 | --unique=1 \ 47 | --net0 name=eth0,bridge=vmbr0,hwaddr=66:66:66:66:66:66,ip=dhcp,type=veth 48 | 49 | logger "Configuring container $ctid" 50 | cat <> /etc/pve/lxc/$ctid.conf 51 | lxc.apparmor.profile: unconfined 52 | lxc.cap.drop: 53 | lxc.cap.drop: sys_time sys_module sys_rawio 54 | lxc.cgroup2.devices.allow: a 55 | 56 | lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 57 | lxc.cgroup2.devices.allow: c 226:* rwm 58 | 59 | lxc.mount.entry: /dev/tty7 dev/tty7 none bind,optional,create=file 60 | lxc.cgroup2.devices.allow: c 4:7 rwm 61 | 62 | lxc.mount.entry: /dev/tty8 dev/tty8 none bind,create=file 0 0 63 | lxc.cgroup2.devices.allow: c 4:8 rwm 64 | 65 | lxc.mount.entry: /dev/tty0 dev/tty0 none bind,create=file 0 0 66 | lxc.cgroup2.devices.allow: c 4:0 rwm 67 | 68 | lxc.mount.entry: /dev/input dev/input none bind,optional,create=dir 69 | lxc.cgroup2.devices.allow: c 13:* rwm 70 | 71 | lxc.mount.entry: /dev/snd dev/snd none bind,optional,create=dir 72 | lxc.cgroup.devices.allow = c 116:* rwm 73 | 74 | lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file 75 | lxc.cgroup2.devices.allow: c 29:0 rwm 76 | 77 | lxc.mount.entry: /dev/fuse dev/fuse none bind,create=file,optional 78 | lxc.cgroup2.devices.allow: c 10:229 rwm 79 | 80 | lxc.mount.auto: cgroup:rw 81 | lxc.mount.auto: sys:rw 82 | lxc.tty.max: 6 83 | EOF 84 | 85 | pct snapshot $ctid "Post-configuration" 86 | 87 | logger "Starting container" 88 | pct start $ctid 89 | 90 | logger "Waiting for network connectivity" 91 | sleep 10 92 | 93 | logger "Provisioning SSH public keys" 94 | pct exec $ctid -- sh -c "echo \"....\" >> /root/.ssh/authorized_keys" 95 | pct exec $ctid -- sh -c "echo \"...\" >> /root/.ssh/authorized_keys" 96 | 97 | pct exec $ctid -- sh -c "apt update" 98 | 99 | logger "Install essential tools" 100 | pct exec $ctid -- sh -c "apt install -y sudo curl apt-transport-https nano" 101 | 102 | logger "Configure container timezone" 103 | pct exec $ctid -- sh -c " 104 | apt install -y locales; 105 | locale-gen en_US.UTF-8; 106 | locale-gen nl_NL.UTF-8; 107 | localedef -i nl_NL -f UTF-8 nl_NL.UTF-8 108 | " 109 | 110 | logger "Configuring keyboard" 111 | pct exec $ctid -- sh -c "tee /etc/default/keyboard < /etc/polkit-1/rules.d/49-nm-network-control.rules" 155 | 156 | logger "Installing applications" 157 | pct exec $ctid -- su - $user -c "sudo apt -y install chromium" 158 | pct exec $ctid -- su - $user -c "sudo apt -y install radeontop" 159 | pct exec $ctid -- su - $user -c "sudo apt -y install gimp" 160 | pct exec $ctid -- su - $user -c "sudo apt -y install kcharselect" 161 | pct exec $ctid -- su - $user -c "sudo apt -y install filelight" 162 | pct exec $ctid -- su - $user -c "sudo apt -y install okular" 163 | pct exec $ctid -- su - $user -c "sudo apt -y install skanpage" 164 | pct exec $ctid -- su - $user -c "sudo apt -y install thunderbird thunderbird-l10n-nl" 165 | pct exec $ctid -- su - $user -c "sudo apt -y install vlc" 166 | pct exec $ctid -- su - $user -c "sudo apt -y install kdenlive" 167 | pct exec $ctid -- su - $user -c "sudo apt -y install libreoffice-calc" 168 | pct exec $ctid -- su - $user -c "sudo apt -y install ksystemlog" 169 | pct exec $ctid -- su - $user -c "sudo apt -y install kwave" 170 | pct exec $ctid -- su - $user -c "sudo apt -y install webext-plasma-browser-integration" 171 | pct exec $ctid -- su - $user -c "sudo apt -y install golang" 172 | pct exec $ctid -- su - $user -c "sudo apt -y install flatpak" 173 | 174 | logger "Installing dutch spelling" 175 | pct exec $ctid -- su - $user -c "sudo apt -y install aspell-nl hunspell-nl" 176 | pct exec $ctid -- su - $user -c "kwriteconfig5 --file KDE/Sonnet.conf --group General --key defaultLanguage nl_NL" 177 | 178 | logger "Set user language" 179 | pct exec $ctid -- su - $user -c " 180 | kwriteconfig5 --file plasma-localerc --group Formats --key LANG nl_NL.UTF-8; 181 | kwriteconfig5 --file plasma-localerc --group Translations --key LANGUAGE nl 182 | " 183 | 184 | logger "Set keyboard layout" 185 | pct exec $ctid -- su - $user -c " 186 | kwriteconfig5 --file kxkbrc --group Layout --key LayoutList nl; 187 | kwriteconfig5 --file kxkbrc --group Layout --key Model pc105; 188 | kwriteconfig5 --file kxkbrc --group Layout --key Use true; 189 | kwriteconfig5 --file kxkbrc --group Layout --key VariantList us 190 | " 191 | 192 | logger "Configuring daily automatic updating" 193 | pct exec $ctid -- su - $user -c "kwriteconfig5 --file PlasmaDiscoverUpdates --group Global --key UseUnattendedUpdates true" 194 | 195 | logger "Configuring Screen timeout" 196 | pct exec $ctid -- su - $user -c "kwriteconfig5 --file ~/.config/kscreenlockerrc --group Daemon --key Timeout 300" 197 | 198 | logger "Installing Tailscale" 199 | pct exec $ctid -- su - $user -c " 200 | curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null; 201 | curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list; 202 | sudo apt-get update; 203 | sudo apt-get install -y tailscale 204 | " 205 | logger "Install TriliumNext desktop v0.98.0" 206 | pct exec $ctid -- su - $user -c " 207 | wget https://github.com/TriliumNext/Trilium/releases/download/v0.98.0/TriliumNotes-v0.98.0-linux-x64.deb; 208 | sudo dpkg -i TriliumNotes-v0.98.0-linux-x64.deb; 209 | rm TriliumNotes-v0.98.0-linux-x64.deb 210 | " 211 | 212 | logger "Install Bitwarden desktop" 213 | pct exec $ctid -- su - $user -c " 214 | wget \"https://bitwarden.com/download/?app=desktop&platform=linux&variant=deb\" -O bitwarden.deb; 215 | sudo dpkg -i bitwarden.deb; 216 | rm bitwarden.deb 217 | " 218 | 219 | logger "Installing VSCode" 220 | pct exec $ctid -- su - $user -c " 221 | echo \"code code/add-microsoft-repo boolean true\" | sudo debconf-set-selections; 222 | sudo apt-get install wget gpg; 223 | wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg; 224 | sudo install -D -o root -g root -m 644 microsoft.gpg /usr/share/keyrings/microsoft.gpg; 225 | rm -f microsoft.gpg 226 | " 227 | pct exec $ctid -- sh -c "tee /etc/apt/sources.list.d/vscode.sources <- 85 | Definieer lijst van topics waarvan de waarde direct opgevraagd dient te 86 | worden 87 | - alias: Publiceer "get" commando's voor direct ophalen van waarden van topics 88 | repeat: 89 | count: "{{ topics | count }}" 90 | sequence: 91 | - variables: 92 | topic: ebusd/{{ topics[repeat.index - 1] }}/get 93 | - data: 94 | topic: "{{topic}}" 95 | action: mqtt.publish 96 | - variables: 97 | topics: 98 | - bai/Flame 99 | - bai/HwcWaterflow 100 | - bai/Statenumber 101 | - bai/HwcDemand 102 | - bai/PumpPower 103 | alias: >- 104 | Definieer lijst van topics waarvan de waarde zeer regelmatig bijgewerkt 105 | dient te worden 106 | - alias: >- 107 | Publiceer "get?1" commando's voor het zeer regelmatig bijwerken van de 108 | waarden van topics 109 | repeat: 110 | count: "{{ topics | count }}" 111 | sequence: 112 | - variables: 113 | topic: ebusd/{{ topics[repeat.index - 1] }}/get 114 | - data: 115 | topic: "{{topic}}" 116 | payload: "?1" 117 | action: mqtt.publish 118 | - variables: 119 | topics: 120 | - bai/CirPump 121 | - bai/PrEnergySumHc1 122 | - bai/PrEnergySumHwc1 123 | - bai/PrEnergyCountHwc1 124 | - bai/PrEnergyCountHc1 125 | - bai/RemainingBoilerblocktime 126 | - bai/ReturnTemp 127 | - bai/PumpPowerDesired 128 | alias: >- 129 | Definieer lijst van topics waarvan de waarde minder regelmatig bijgewerkt 130 | dient te worden 131 | - alias: >- 132 | Publiceer "get?2" commando's voor het minder regelmatig bijwerken van de 133 | waarden van topics 134 | repeat: 135 | count: "{{ topics | count }}" 136 | sequence: 137 | - variables: 138 | topic: ebusd/{{ topics[repeat.index - 1] }}/get 139 | - data: 140 | topic: "{{topic}}" 141 | payload: "?2" 142 | action: mqtt.publish 143 | ``` 144 | 145 | ## Feature: High-low-temperature schedule 146 | I am using a "2 presets" configuration with a high-temperature and low-temperature preset. 147 | 148 | I am using a setup which is using a [Schedule helper](https://www.home-assistant.io/integrations/schedule/) to switch the heating-presets (high or low) at which times. 149 | 150 | I am also using a [Boolean helper](https://www.home-assistant.io/integrations/input_boolean/) to temporarely pause the heating, for instance when doors are opened or nobody is at home. 151 | 152 | 153 | imageimage 154 | 155 | ### Helpers 156 | * `input_boolean.verwarming_schema_gestuurd`: This is a switch to enable/disable the controlling of the heating via the schema. 157 | * `schedule.verwarming`: This is a schedule helper in which a week-schedule can be configured to define when the "high"-heating-preset is desired. 158 | * `input_number.woonkamer_verwarming_hoog_temperatuur`: This is the temperature which is desired to be used for the "high"-preset. 159 | * `input_number.woonkamer_verwarming_laag_temperatuur`: This is the temperature which is desired to be used for the "low"-preset 160 | 161 | ### Dashboard card 162 | ``` 163 | type: entities 164 | title: Verwarmingsschema 165 | state_color: false 166 | entities: 167 | - entity: input_boolean.verwarming_schema_gestuurd 168 | secondary_info: last-changed 169 | - type: simple-entity 170 | name: Schema tijdelijk onderbroken 171 | entity: input_boolean.verwarming_schema_gestuurd_tijdelijk_gedeactiveerd 172 | secondary_info: last-changed 173 | state_color: true 174 | tap_action: 175 | action: more-info 176 | hold_action: 177 | action: none 178 | double_tap_action: none 179 | - type: conditional 180 | conditions: 181 | - condition: state 182 | entity: schedule.verwarming 183 | state: "on" 184 | row: 185 | type: attribute 186 | name: Huidige aansturing 187 | icon: mdi:radiator 188 | format: time 189 | entity: schedule.verwarming 190 | attribute: next_event 191 | prefix: hoog tot 192 | - type: conditional 193 | conditions: 194 | - condition: state 195 | entity: schedule.verwarming 196 | state: "off" 197 | row: 198 | type: attribute 199 | name: Verwarming schema 200 | icon: mdi:radiator-disabled 201 | format: time 202 | entity: schedule.verwarming 203 | attribute: next_event 204 | prefix: laag tot 205 | - type: weblink 206 | name: Schema helper 207 | url: /config/helpers 208 | icon: mdi:home-assistant 209 | new_tab: false 210 | - type: divider 211 | - type: custom:multiple-entity-row 212 | name: Woonkamer temperatuur 213 | entity: climate.woonkamer_verwarming 214 | entities: 215 | - entity: sensor.huidige_temperatuur_woonkamer 216 | name: Huidig 217 | - entity: input_number.woonkamer_verwarming_hoog_temperatuur 218 | name: Hoog 219 | - entity: input_number.woonkamer_verwarming_laag_temperatuur 220 | name: Laag 221 | show_header_toggle: false 222 | ``` 223 | 224 | ### "Woonkamer verwarming hoog op basis van schema" 225 | This automation ensures the "high"-preset to be enabled. 226 | ``` 227 | alias: Woonkamer verwarming hoog op basis van schema 228 | triggers: 229 | - trigger: state 230 | entity_id: 231 | - schedule.verwarming 232 | from: "off" 233 | to: "on" 234 | - trigger: state 235 | entity_id: 236 | - input_boolean.verwarming_schema_gestuurd 237 | from: "off" 238 | to: "on" 239 | - trigger: state 240 | entity_id: 241 | - input_boolean.verwarming_schema_gestuurd_tijdelijk_gedeactiveerd 242 | from: "on" 243 | to: "off" 244 | conditions: 245 | - condition: state 246 | entity_id: schedule.verwarming 247 | state: "on" 248 | - condition: state 249 | entity_id: input_boolean.verwarming_schema_gestuurd 250 | state: "on" 251 | - condition: state 252 | entity_id: input_boolean.verwarming_schema_gestuurd_tijdelijk_gedeactiveerd 253 | state: "off" 254 | actions: 255 | - target: 256 | entity_id: 257 | - climate.woonkamer_verwarming 258 | data: 259 | temperature: "{{ states(\"input_number.woonkamer_verwarming_hoog_temperatuur\") }}" 260 | alias: Stel temperatuur in op hoog 261 | action: climate.set_temperature 262 | mode: single 263 | ``` 264 | 265 | ### "Woonkamer verwarming laag op basis van schema" 266 | This automation ensures the "low"-preset to be activated. 267 | ``` 268 | alias: Woonkamer verwarming laag op basis van schema 269 | triggers: 270 | - entity_id: 271 | - schedule.verwarming 272 | trigger: state 273 | from: "on" 274 | to: "off" 275 | - trigger: state 276 | entity_id: 277 | - input_boolean.verwarming_schema_gestuurd_tijdelijk_gedeactiveerd 278 | from: "on" 279 | to: "off" 280 | conditions: 281 | - condition: state 282 | entity_id: schedule.verwarming 283 | state: "off" 284 | - condition: state 285 | entity_id: input_boolean.verwarming_schema_gestuurd 286 | state: "on" 287 | - condition: state 288 | entity_id: input_boolean.verwarming_schema_gestuurd_tijdelijk_gedeactiveerd 289 | state: "off" 290 | actions: 291 | - alias: Stel temperatuur in op laag 292 | target: 293 | entity_id: 294 | - climate.woonkamer_verwarming 295 | data: 296 | temperature: "{{ states(\"input_number.woonkamer_verwarming_laag_temperatuur\") }}" 297 | hvac_mode: heat 298 | action: climate.set_temperature 299 | mode: single 300 | ``` 301 | 302 | ## Feature: Polling and updating 303 | This automation keeps the script running. The script should run continuously. I use this automation and a script to prevent Home Assistant from continuously registering the start of automations and scripts. 304 | 305 | ### "automation.poll_warm_water_script_starten" 306 | ``` 307 | alias: Scripts "eBUS polling" actief houden 308 | triggers: 309 | - trigger: homeassistant 310 | event: start 311 | - trigger: state 312 | entity_id: 313 | - script.poll_warm_water_waarden 314 | to: "off" 315 | - trigger: state 316 | entity_id: 317 | - script.poll_low_prio_ebus_registers 318 | to: "off" 319 | actions: 320 | - action: script.turn_on 321 | target: 322 | entity_id: 323 | - script.poll_warm_water_waarden 324 | - script.poll_low_prio_ebus_registers 325 | mode: single 326 | ``` 327 | 328 | ### "script.poll_warm_water_waarden" 329 | This script polls values which are used to temporarily increase the polling frequency of certain other values. 330 | ``` 331 | sequence: 332 | - repeat: 333 | while: 334 | - condition: template 335 | value_template: "{{true}}" 336 | sequence: 337 | - action: mqtt.publish 338 | data: 339 | topic: ebusd/bai/HwcDemand/get 340 | payload: "?1" 341 | alias: Poll "warm-water-vraag" 342 | - delay: 343 | seconds: 5 344 | - alias: Poll "flame" 345 | action: mqtt.publish 346 | data: 347 | topic: ebusd/bai/Flame/get 348 | payload: "?1" 349 | - delay: 350 | seconds: 5 351 | - alias: Poll "Statenumber" 352 | action: mqtt.publish 353 | data: 354 | topic: ebusd/bai/Statenumber/get 355 | payload: "?1" 356 | - delay: 357 | seconds: 5 358 | alias: Poll high-prio ebus waarden 359 | icon: mdi:target 360 | ``` 361 | 362 | ### "script.poll_low_prio_ebus_registers" 363 | This script runs in a loop and will poll certain values on a lower frequency. 364 | ``` 365 | sequence: 366 | - repeat: 367 | while: 368 | - condition: template 369 | value_template: "{{true}}" 370 | sequence: 371 | - action: mqtt.publish 372 | data: 373 | topic: ebusd/bai/PrEnergySumHwc1/get 374 | payload: "?1" 375 | alias: Poll "PrEnergySumHwc1" 376 | - action: mqtt.publish 377 | data: 378 | topic: ebusd/bai/PrEnergyCountHwc1/get 379 | payload: "?1" 380 | alias: Poll "PrEnergyCountHwc1" 381 | - action: mqtt.publish 382 | data: 383 | topic: ebusd/bai/HwcStarts/get 384 | payload: "?1" 385 | alias: Poll "HwcStarts" 386 | - action: mqtt.publish 387 | data: 388 | topic: ebusd/bai/HwcTemp/get 389 | payload: "?1" 390 | alias: Poll "HwcTemp" 391 | - action: mqtt.publish 392 | data: 393 | topic: ebusd/bai/HwcHours/get 394 | payload: "?1" 395 | alias: Poll "HwcHours" 396 | - delay: 397 | seconds: 60 398 | - action: mqtt.publish 399 | data: 400 | topic: ebusd/bai/CirPump/get 401 | payload: "?1" 402 | alias: Poll "CirPump" 403 | - action: mqtt.publish 404 | data: 405 | topic: ebusd/bai/PrEnergySumHc1/get 406 | payload: "?1" 407 | alias: Poll "PrEnergySumHc1" 408 | - action: mqtt.publish 409 | data: 410 | topic: ebusd/bai/PrEnergyCountHc1/get 411 | payload: "?1" 412 | alias: Poll "PrEnergyCountHc1" 413 | - action: mqtt.publish 414 | data: 415 | topic: ebusd/bai/ReturnTemp/get 416 | payload: "?1" 417 | alias: Poll "ReturnTemp" 418 | - alias: Poll "DisplayedRoomTemp" 419 | action: mqtt.publish 420 | data: 421 | topic: ebusd/350/DisplayedRoomTemp/get 422 | payload: "?1" 423 | - delay: 424 | seconds: 60 425 | alias: Poll low-prio ebus registers 426 | description: "" 427 | icon: mdi:target-variant 428 | ``` 429 | 430 | ### "automation.tijdens_cv_brander_frequenter_waarden_ophalen" 431 | ``` 432 | alias: Tijdens "CV Brander" frequenter waarden ophalen 433 | description: "" 434 | triggers: 435 | - trigger: state 436 | entity_id: 437 | - sensor.ebusd_bai_flame 438 | to: "on" 439 | from: "off" 440 | actions: 441 | - repeat: 442 | while: 443 | - condition: state 444 | entity_id: sensor.ebusd_bai_flame 445 | state: "on" 446 | sequence: 447 | - action: mqtt.publish 448 | metadata: {} 449 | data: 450 | topic: ebusd/bai/PrEnergySumHc1/get 451 | payload: "?1" 452 | alias: Poll "PrEnergySumHc1" 453 | - action: mqtt.publish 454 | metadata: {} 455 | data: 456 | topic: ebusd/bai/PrEnergyCountHc1/get 457 | payload: "?1" 458 | alias: Poll "PrEnergyCountHc1" 459 | - action: mqtt.publish 460 | metadata: {} 461 | data: 462 | topic: ebusd/bai/Flame/get 463 | payload: "?1" 464 | alias: Poll "flame" 465 | - delay: 466 | hours: 0 467 | minutes: 0 468 | seconds: 5 469 | milliseconds: 0 470 | mode: single 471 | ``` 472 | 473 | 474 | ## Feature: Seperate sensors for gas usage for heating-circuit and hot-water-circuit 475 | Using a P1 meter i'm able to track the usage of gas. But using PrEnergy* of my Vaillant Boiler, i'm even able to track for which goal gas used. 476 | image 477 | 478 | 479 | ### "automation.reset_prenergy_waarden_om_middernacht" 480 | This automation will start a script at midnight which resets the prenergy* fields. 481 | ``` 482 | alias: Reset PrEnergy* waarden om middernacht 483 | triggers: 484 | - trigger: time_pattern 485 | hours: "0" 486 | minutes: "0" 487 | seconds: "0" 488 | actions: 489 | - action: script.turn_on 490 | target: 491 | entity_id: script.reset_prenergy_waarden 492 | mode: single 493 | ``` 494 | 495 | ### "script.reset_prenergy_waarden" 496 | This script resets the PrEnergy* fields. 497 | ``` 498 | sequence: 499 | - alias: Reset ebusd/bai/PrEnergyCountHwc1 500 | data: 501 | topic: ebusd/bai/PrEnergyCountHwc1/set 502 | payload: "0" 503 | action: mqtt.publish 504 | enabled: true 505 | - alias: Reset ebusd/bai/PrEnergyCountHc1 506 | data: 507 | topic: ebusd/bai/PrEnergyCountHc1/set 508 | payload: " 0" 509 | action: mqtt.publish 510 | enabled: true 511 | - alias: Reset ebusd/bai/PrEnergySumHc1 512 | data: 513 | topic: ebusd/bai/PrEnergySumHc1/set 514 | payload: " 0" 515 | action: mqtt.publish 516 | enabled: true 517 | - alias: Reset ebusd/bai/PrEnergySumHwc1 518 | data: 519 | topic: ebusd/bai/PrEnergySumHwc1/set 520 | payload: " 0" 521 | action: mqtt.publish 522 | enabled: true 523 | alias: Reset PrEnergy* waarden 524 | ``` 525 | 526 | 527 | ### Template Helper: "sensor.gasverbruik_voor_warm_water" 528 | This helper will calculate the m3 of gas used for hot-water-circuit. 529 | ``` 530 | {{ (states("sensor.ebusd_bai_prenergysumhwc1") |float) * 0.000002010000000 }} 531 | ``` 532 | 533 | ### Template Helper: "sensor.gasverbruik_vandaag_voor_verwarming" 534 | This helper will calculate the m3 of gas used for heating-circuit. 535 | ``` 536 | {{ (states("sensor.ebusd_bai_prenergysumhc1") |float) * 0.00000203370665409 }} 537 | ``` 538 | --------------------------------------------------------------------------------