Récupérer l'état d'un ventilateur connecté au Raspberry

Ma situation

Bonjour à tous,

J’ai récemment ajouté un ventillateur pour refroidir le boitier de mon raspberry car mon boitié maison intègre un écran en plus du rapsberry ce qui génère un peut trop de chaleur pour une dissipation naturelle.

J’ai donc opté pour deux petit ventilateurs 5V que j’ai intégré dans le boitié.

Les ventilateurs étant bruyant si ils fonctionnent en continu j’ai mis en place un script Python pour les réguler.
Je me suis inspiré de ce site :

P.S.: J’ai adapté le script pour qu’il adapte la puissance du ventilateur de façon plus autonome.
Si ça intéresse quelqu’un je me le code du script à la fin du post.

Mon problème

Je voudrais récupéré dans HA l’état des ventilateurs, ou plus précisement la puissance fournie.
Le script permet d’alimenter les ventillateurs via un PIN avec une puissance variant entre 0 et 5V (5V étant le max que peut fournir le PIN)

Ma configuration

version core-2021.2.3
installation_type Home Assistant Supervised
dev false
hassio true
docker true
virtualenv false
python_version 3.8.7
os_name Linux
os_version 5.10.11-v7+
arch armv7l
timezone Europe/Paris
Home Assistant Community Store
GitHub API ok
Github API Calls Remaining 4980
Installed Version 1.10.1
Stage running
Available Repositories 810
Installed Repositories 5
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Hass.io
host_os Raspbian GNU/Linux 10 (buster)
update_channel stable
supervisor_version supervisor-2021.02.6
docker_version 20.10.3
disk_total 7.0 GB
disk_used 4.5 GB
healthy true
supported failed to load: Unsupported
supervisor_api ok
version_api ok
installed_addons File editor (5.2.0), MariaDB (2.2.1), Let’s Encrypt (4.11.0), Samba share (9.3.0), Mosquitto broker (5.1), Spotify Connect (0.8.2)
Lovelace
dashboards 1
resources 2
views 7
mode storage
Spotify
api_endpoint_reachable ok

Le scrip modifié

#!/usr/bin/python
#-*- coding: utf-8 -*-

# Change made by Matt 
# Old behavior: Fan min speed is define in table
# New behavior: Fan is stopped if temperature is below trigger
#               Fan speed is automatically adjusted according if temperature is inscreasing up to max speed define

import RPi.GPIO as GPIO
import time
import sys

# Configuration
FAN_PIN = 21 # BCM pin used to drive transistor's base 
WAIT_TIME = 5 # [s] Time to wait between each refresh 
FAN_MIN = 20 # [%] Fan minimum speed. 
PWM_FREQ = 25 # [Hz] Change this value if fan has strange behavior

# Configurable temperature and fan speed steps
tempSteps = [50, 70] # [°C] 
speedSteps = [30, 80] # [%]

# Fan speed will change only of the difference of temperature is higher 
# than hysteresis
hyst = 1

# Setup GPIO pin
GPIO.setmode(GPIO.BCM)
GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW)
fan = GPIO.PWM(FAN_PIN, PWM_FREQ)
fan.start(0)

i = 0
cpuTemp = 0
fanSpeed = 0
cpuTempOld = 0
fanSpeedOld = 0
firstRun = 0 # 0:fan stopped | 1: fan start | 2:fan running
fanSpeedIncrement = 5
updateCpuTemp = 0

# We must set a speed value for each temperature step
if len(speedSteps) != len(tempSteps):
  print("Numbers of temp steps and speed steps are different")
  exit(0)

try:
  while 1:
    # Read CPU temperature
    cpuTempFile = open("/sys/class/thermal/thermal_zone0/temp","r")
    cpuTemp = float(cpuTempFile.read()) / 1000
    cpuTempFile.close()

    #print("Temperature cpu lue: %1",cpuTemp)
    
    #Below first value, fan is stopped
    if (cpuTemp < tempSteps[0]) and (firstRun != 0):
      fanSpeed = 0
      updateCpuTemp = 1
      firstRun = 0
      #print("Fan Stop")
    #First run: fan is set to max speed to make shure fan start
    elif firstRun == 0:
      fanSpeed = speedSteps[1]
      firstRun = 1
      updateCpuTemp = 1
      #print("First run: temperature : " , cpuTemp , " | fan speed : " , fanSpeed)
    else:
      #Fan speed is set to an approximate power regarding the min and max temps defined
      if firstRun == 1:
        #If  max temp reach set fan to MAX
        if cpuTemp > tempSteps[1]:
          fanSpeed = speedSteps[1]
        else:
          #Set fan speed linear integrate bewteen MIN and MAX
          currentPercentToMaxTemp = (cpuTemp - tempSteps[0]) / (tempSteps[1] - tempSteps[0]) 
          fanSpeed = round((speedSteps[1] - speedSteps[0]) * currentPercentToMaxTemp + speedSteps[0])
          #print("fan speed", fanSpeed)
        firstRun = 2
        updateCpuTemp = 1
        #print("Second run: temperature : " , cpuTemp , " | fan speed: " , fanSpeed)
      else:
        #print("Other run - Old: ", cpuTempOld , " New: ", cpuTemp)
        #Only update fan speed if temperature difference is higher than hyst
        if abs(cpuTemp - cpuTempOld) > hyst:
          #print("Trigger reach")
          if (cpuTemp > cpuTempOld) and (fanSpeed < speedSteps[len(tempSteps) - 1]):
            fanSpeed = fanSpeedOld + fanSpeedIncrement
            #print("Temperature increase: " , cpuTemp , " | new speed: " , fanSpeed)
          elif (cpuTemp < cpuTempOld) and (fanSpeed > speedSteps[0]):
            fanSpeed = fanSpeedOld - fanSpeedIncrement
            #print("Temperature decrease: " , cpuTemp , " | new speed: " , fanSpeed)
          updateCpuTemp = 1
    if fanSpeed != fanSpeedOld:
      fan.ChangeDutyCycle(fanSpeed)
      fanSpeedOld = fanSpeed
      #print("Fan speed updated!")
    if updateCpuTemp == 1:
      cpuTempOld = cpuTemp
      updateCpuTemp = 0
    time.sleep(WAIT_TIME)

# If a keyboard interrupt occurs (ctrl + c), the GPIO is set to 0 and 
# the program exits.
except KeyboardInterrupt: 
	print("Fan ctrl interrupted by keyboard") 
	GPIO.cleanup()
	sys.exit()

Le plus simple serait que ton script publie les valeurs sur MQTT.
HA, grâce à un sensor MQTT, tu récupères les valeurs.

Voici un tuto (en anglais) permettant de récupérer une valeur depuis un topic MQTT : https://diyi0t.com/home-assistant-mqtt-tutorial/

Merci pour aide, je vais regarder ce tuto.

Je m’était demandé a quoi servait MQTT, ça va me donner l’occasion de tester.

bonjour

Je viens de tomber sur cette question en cherchant à voir comment installer le RPI.GPIO…

Je n’ai pas ma réponse mais je peux donner mon avis sur ton problème:
Pour modifier des variables HA dans python (ici: input_text.payload_rflink):

        texte = 'Temp;15.'
        service_data = {"entity_id": "input_text.payload_rflink" , "value": texte }
        hass.services.call('input_text', 'set_value', service_data, False )

Une fois dans HA, un sensor template est triggé lorsque la variable est modifiée.

template:
  - trigger:
    - platform: state
      entity_id: input_text.payload_rflink
    sensor:
      - name: Temp_ext_rflinlk
        unit_of_measurement: "°C"
        state: >
            {{  states('input_text.payload_rflink').split(';')[2] }}

Mon problème est que je ne savais pas comment décoder la payload MQTT. Dans mon cas, c’est une chaîne de caractères qui peut prendre toute sorte de forme et pas du jison.