Hello,
I’m really new with Home Assistant. I have an raspberry pi, which is running a database server with a temperature log (Not on the one, which has Home Assistant).
I have a python file, that logs in the database, grabs the temperature and saves it as a varible. How can i import that into Home Assistant, as an device?
(Home assistant-os)
Cheers,
Ivthered
Mine is not shown as a device - I didn’t need that really - but here is a quick way -
I am doing something similar - in a nutshell:
Within HA, create a long-lived token in HA and copy it somewhere (notepad or wherever).
On the remote device that has the temperature:
- Write a shell script which will run on startup,
- It needs to run in a loop continuously to grab the temperature and send it to HA, and not exit and complete the program when connectivity is lost but just continue looping and trying. I have mine grab the information about the temperature every 5 minutes and then send it to HA.
Here is my code - use chatgpt and the forums here for questions you run into when working on it:
Mine will be different than yours, since I have HAOS on a RPI5 in a VM it cannot get the temp of it’s own CPU within HAOS, so I have a shell script that logs into the RPI5 from an RPI4, grabs the temp and fan status and speed, then calls an HA API to post that information in input_texts I have in HA. I have the text_inputs hidden and a simple read-only template sensors in configuration.yaml so on a dashboard is shows as just read-only text and not an input_text.
As mentioned: The below runs on an RPI4 at a Debian (linux) command line, at startup using systemd (chatgpt or the internet can help you). The below logs into the actual RPI5 host to gather the information, then posts the (properly formatted) information to HA (which is on a VM on the RPI machine so that has it’s own separate IP address since it is a VM).
Save the below file with somename that ends in .sh, on the remote RPI
Remember in python spacing is very important - the below all works so the spacing is correct
#!/bin/bash
# Define the target machine's hostname, IP address and password
RPI5="<host login id>@<RPI5 host IP address>"
PASSWORD="<password on the host on the RPI5>"
API_TARGET="http://<IP address of the HA instance on the RPI5, mine is different from the above because it is on a VM>/api/services/input_text/set_value"
API_KEY="<this is the API key I said to obtain in the first step>>"
FAN_STATUS="Nuttin yet!"
CPU_ENTITY_ID="input_text.rpi5_cpu_temperature"
FAN_ENTITY_ID="input_text.rpi5_fan_status"
while true; do
# SSH into RPI5 using sshpass and retrieve the CPU temperature
cpu_temp=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no $RPI5 "cat /sys/class/thermal/thermal_zone0/temp")
if [ $? -ne 0 ]; then
echo "Error retrieving CPU temperature"
sleep 5
continue
fi
# I am saving the temp formthe RPI5 in Fahrenheit
cpu_temp=$(echo "scale=2; ($cpu_temp / 1000) * (9/5) + 32" | bc)
# SSH into RPI5 using sshpass and retrieve the fan state
fan_state=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no $RPI5 "cat /sys/class/thermal/cooling_device0/cur_state")
if [ $? -ne 0 ]; then
echo "Error retrieving fan state"
sleep 5
continue
fi
# SSH into RPI5 using sshpass and retrieve the fan speed
fan_speed=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no $RPI5 "cat /sys/devices/platform/cooling_fan/hwmon/*/fan1_input")
if [ $? -ne 0 ]; then
echo "Error retrieving fan speed"
sleep 5
continue
fi
# Assemble the fan status:
if [ "$fan_state" -eq 1 ]; then
FAN_STATUS="Fan on: ${fan_speed} RPM"
else
FAN_STATUS="Fan off"
fi
# Send CPU Temperature
curl -sS --insecure -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"entity_id\": \"$CPU_ENTITY_ID\", \"value\": \"$cpu_temp\"}" \
$API_TARGET > /dev/null
if [ $? -ne 0 ]; then
echo "Failed to send RPI5 CPU temp"
continue
fi
# Send Fan Status
curl -sS --insecure -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"entity_id\": \"$FAN_ENTITY_ID\", \"value\": \"$FAN_STATUS\"}" \
$API_TARGET > /dev/null
if [ $? -ne 0 ]; then
echo "Failed to send fan status data"
continue
fi
# Wait for 5 seconds before the next loop iteration
sleep 5
done
Hope that helps! I have learned alot form these forums so I try to give back when I can. Pay it forward!
Hello and welcome to Home Assistant!
If you want the data to appear as entities under a “device” you can use the MQTT integration discovery feature to define custom device(s) and entities with associated update MQTT topics. After that your Python script can send measurement readings as JSON messages to the update topics. This is the only way I’m aware to get a custom “device” in HA without writing an entire custom integration. It does require you to set up the MQTT broker add-on for HAOS.
A more direct path (i.e. skipping the python and mqtt intermediaries) would be to setup a SQL sensor for HA to query the database and create temperature entities. However these entities will not be linked to a device, they would just be standalone measurement entities. You can also have your python script post the data to a url to define a HTTP sensor, but the docs say it would be recreated every time HA restarts, which may or may not work for your purposes.
Although my use case is different, that is one additional reason why I use the input texts in the background, their values survive HA restarts/reboots. I also have other unrelated reasons why it needs to run on the rpi4 instead of just on the rpi5 host outside the vm.
Hi @peterxian,
I tried to use MQTT, but when i start the script, i recice this error:
New connection from 10.64.64.95:37835 on port 1883.
error: received null username or password for unpwd check
I looked the web and did not find a way to fix this. By the way thanks for the idea and resources.
UPDATE
I fixed managed to fix it, but i dont know how to add my “test” thermometer as an device. I used a pretty sneaky pip pluging to help me: homeassistant-mqtt-binding
.
Here is the python code i used:
import time
from random import uniform
from paho.mqtt.client import Client, CallbackAPIVersion
import paho.mqtt.client as mqtt
from ha_mqtt.mqtt_device_base import MqttDeviceSettings
from ha_mqtt.mqtt_thermometer import MqttThermometer
def on_connect(client, userdata, flags, reason_code, properties):
print(f"Connected with result code {reason_code}")
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("$SYS/#")
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client(client_id="Random_CLient_id", transport="tcp")
client.tls_set()
# instantiate a paho mqtt client and connect to the mqtt server
client = Client(CallbackAPIVersion.VERSION2, "Rpi4")
client.username_pw_set("YOUR_UNAME", "YOUR_PASS")
client.connect("MQTT_SERVER", 1883)
client.loop_start()
# callbacks for the on and off actions
# instantiate an MQTTThermometer object
settings = MqttDeviceSettings("Thermometer 1", "temp1", client)
th = MqttThermometer(settings, unit="°C")
try:
th.start()
while True:
# publish a random "temperature" every 5 seconds
temp = f"{uniform(-10, 10):2.2f}"
print(f"publishing temperature: {temp} {th.unit_of_measurement}")
th.update_state(temp)
time.sleep(5)
except KeyboardInterrupt:
pass
finally:
# close the device for cleanup. Gets marked as offline/unavailable in homeassistant
th.stop()
client.loop_stop()
client.disconnect()
Nice work. I’ve never created a device manually, but my link above to the MQTT discovery docs have most of the details. There are also some good topics on this forum with advice and a quick search found this comprehensive explanation.
Update:
@peterxian, Thank you so much for they help you and @KruseLuds provided.
I hoocked it up to my other python script and,now everything works.