This process allows to expose in Home Assistant (or other Smart Home Hub) all information about all LXC and VMs defined in a Proxmox VE node.
It uses Proxmox VE, Home Assistant, Node-RED, MQTT, MQTT Discovery, REST API and a little Javascript programming.

It is essential to keep track of and monitor the containers and virtual machines managed by Proxmox. There are several tools that can help achieve this goal, such as Uptime Kuma, which provides real-time notifications if any service becomes unreachable, or integrations with Grafana, allowing you to always have a comprehensive dashboard displaying all critical parameters.
In my case, I wasn't interested in continuously monitoring a dashboard. Instead, I focused on receiving notifications or alerts whenever a parameter exceeded the defined thresholds. This approach enables timely analysis and management of issues related to abnormal CPU usage or the saturation of available disk space.
Using Proxmox's APIs, I exposed all the sensors from LXC containers or VMs to Home Assistant, where I configured alarms and notifications. Unfortunately, the native Proxmox integration only provides basic information, such as the container/VM state (running, stopped, etc.), which is far from sufficient.
To simplify the configuration on the Home Assistant side and create an integration that doesn't require constant maintenance whenever new containers are added (as is the case with the official integration), I developed a flow in Node-RED. This flow acts as a proxy between Proxmox and Home Assistant by accessing the APIs to retrieve all the necessary values, converting them into a readable format, and exposing them to Home Assistant via MQTT.
Additionally, to avoid manually configuring each sensor in Home Assistant, I leveraged the MQTT Discovery feature. This allows the Node-RED flow to dynamically generate the configuration for each sensor, making the setup fully automated and maintenance-free.
Another advantage of using MQTT is that the same pattern can be applied with other Home Automation hubs/controllers such as Homey, Open Hab, Smartthings, and so on.
The notification part is managed by Home Assistant like I do for other notifications and It won't be covered by this note. By the way, It's not mandatory to expose all the sensor to Home Assistant: you can esaily get notified by Telegram, Ntfy or other notification services directly from Node-RED.

Node-RED is a flow-based development tool for wiring together hardware devices, APIs, and online services using a browser-based visual editor. It enables users to create and deploy automation workflows with ease, leveraging a wide range of built-in nodes and community-contributed extensions. It allows users to write complex automation with ease. As with MQTT, it can be installed in a Proxmox LXC container through a community script, rather than directly in Home Assistant through an addon. For further information pleas refer to Node-RED official site.
Instead of re-implementing the authentication handling for Proxmox APIs and the token lifecycle management from scratch, we will leverage the additional module node-red-contrib-proxmox, so please install it from the Manage palette menu. 
By the way, If you want to explore further how Proxmox API works, please take a look to the official API documentation.

Import the flow into Node-RED using the Proxmox resources monitoring JSON provided.
Data Injection and Scheduling:
Send Values node, configured to trigger every 60 seconds (you can modify this schedule following your specific needs), to send the updated value of all the sensors. You can also achieve the same goal on demand by calling the GET API at the endpoint <nodered_ip>/api/proxmoxSend Config node, used one time only to send all the sensor definition to Home Assistant (see Step 3) Proxmox API Integration:
nodes/<YourNodeName>/lxc endpoint) and QEMU virtual machines (nodes/<YourNodeName>/qemu). You have to configure it once by setting the Proxmox server and the user/password to be used.Data Transformation:
percdisk, percmem, percswap: respectively the percentages of disk usage, memory occupancy, and swap file utilization, calculated based on other exposed sensors.lastbackup: a marker for the last succesfully backup date; It's is not provided by this trick but from the Expose the date of Proxmox and Synology backups in Home Assistant one. You can remove it if not interested, but If you want it, you have to define It here even if not provided as sensor value, because this transformation node is also used by the MQTT Discovery configuration part.backupalarm: related to the previous one: I will explain more about it later.MQTT Messages definition:
Send Values node, or the Send Config one, which has a specific topic (Config).For the values, reading all the attributes provided by the previous node, it generates MQTT messages for each attribute of every container or virtual machine, such as:
proxmox/<YourNodeName>/<VM/Container Name>/memoryproxmox/<YourNodeName>/<VM/Container Name>/diskproxmox/<YourNodeName>/<VM/Container Name>/uptime(Replace <YourNodeName> in the code with the name of the node in your Proxmox VE setup)
Split node
If everything worked, you will find all the sensor published with the topic above:

If you don't plan to use all the sensor exposed in Home Assistant or if you want to configure them indipendently, you can stop here. If you wnt to try the MQTT Discovery feature, instead, move to next step.
The MQTT Discovery functionality in Home Assistant automates the process of adding devices, sensors, and other entities to your Home Assistant setup using the MQTT protocol, since It allows devices or integrations to communicate their configuration data to Home Assistant using MQTT topics. When enabled, Home Assistant listens for these configuration messages and automatically creates entities based on the received data. This simplifies the configuration of devices and integrations by enabling them to dynamically announce their presence and configuration without requiring manual YAML entries.
To use MQTT Discovery, the MQTT integration in Home Assistant must be set up, and discovery must be enabled. Here’s how to enable it:
Devices Publish Configuration Topics:
homeassistant/<component>/<object_id>/confighomeassistant/sensor/temperature_sensor/config.Payload Format:
name - The friendly name of the entity.state_topic - The MQTT topic where the device publishes its data.unique_id - A unique identifier for the entity.unit_of_measurement - Units like °C, %, or seconds.value_template - A template to process the received payload.{
"name": "Temperature Sensor",
"state_topic": "home/livingroom/temperature",
"unit_of_measurement": "°C",
"value_template": "{{ value_json.temperature }}",
"unique_id": "sensor_temp_livingroom"
}Home Assistant Processes the Message:
Device Data Updates:
state_topic defined in the payload.In the MQTT Messages definition node, if the msg.topic is Config, ths script:
name property since it's used only for identification{
    topic: `${baseTopic}${obj.name}${key}/config`,
    payload: JSON.stringify({
        name: `${key}`,
        unique_id: `${obj.name}_${key}`,
        state_topic: `proxmox/<YourNodeName>/${obj.name}/${key}`,
        icon: att.icon || "mdi:eye",
        ...(att.unit_of_measurement && { unit_of_measurement: att.unit_of_measurement }),
        ...(att.value_template && { value_template: att.value_template }),
        device: {
            identifiers: [`${obj.name}`],
            name: `${obj.name}`,
            model: `Proxmox ${obj.type}`,
            manufacturer: "Proxmox VE"
        },
    }),
    retain: true
}At the end iterate over each object in msg.payload and maps it to a list of MQTT configuration messages; the flatMap ensures that the resulting array is flattened (i.e., not nested).
baseTopic:<YourNodeName> with the real name of your Proxmox VE node.
Example: "homeassistant/sensor/<YourNodeName>/"topic:homeassistant/sensor/<YourNodeName>/<device_name><attribute>/configpayload:name: A user-friendly name, e.g., CPU. Starting from mid 2023 Home Assistant concatenates by design the name of the device and the attribute one, so at the end it will appear as Server1 CPUunique_id: A unique identifier for Home Assistant, e.g., server1_cpu.state_topic: The MQTT topic where the device publishes state updates.proxmox/<YourNodeName>/Server1_cpuicon: Specific icon defined for that attributes; if not provided, it will be used the default sensor icon (mdi:eye).unit_of_measurement and value_template: only if defined in the specific attributesdevice: Metadata about the device:retain: Ensures the message is retained on the MQTT broker.As said before, instead of using default sensors definition, all with the same specs, values and icons, I customized each one thanks to the attributes object, defined by:
icon: the specific icon for the sensorunit_of_measurement: used only with percentage sensors or numeric ones that have been formatted in the previous node by converting original byte value in a more readable Mb or Gb value accordingly.value_template: used only by one sensor, backupalarm for which no values will be ever sent by this flow (filtered because always null): this because it's a template sensor that will provide a dynamic value based on the lastbackup sensor. For this reason I had to define the lastBackupSensorName by using Home Assistant naming convention: sensor.<device name>_<sensor name>. This sensor will be used in Home Assistant lovelace board to change the behaviour of a card that doesn't allow templating.If everything worked, after triggering the injection node, you will find all the sensor definituon published with the topic above:

and in Home Assistant would appear the device with all it's sensor under MQTT integration.

Now you can configure push notifications in Home Assistant Campanion App, Telegram or whatever you want when a sensor exceeds a certain threshold. For example, I have set up notifications for when the disk reaches 90% usage or the CPU or memory remains above 85% for more than 10 minutes. Additionally, I have configured cards on the Lovelace dashboard to monitor some of the main services, with an icon that changes color based on the value of the relevant sensors. In this case, I wanted to monitor the service's availability (via Uptime Kuma service), its status (running/stopped/…), the 'freshness' of the last backup, and the percentages of disk, CPU, and memory usage. Apart from availability, all the parameters were obtained from the sensors just configured.

The second image is a popup that appears when clicking on each icon.
Even if I'll try to keep all this pages updated, products change over time, technologies evolve... so some use cases may no longer be necessary, some syntax may change, some technologies or products may no longer be available. Remember to make a backup before modifying configuration files and consult the official documentation if any concept is unclear or unfamiliar. 
Use this guide under your own responsibility.
This work and all the contents of this website are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0).
You can distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only by giving credit to the creator. Modified or adapted material must be licensed under identical terms.
You can find the full license terms here