Como fazer um sensor desligado aparecer como "unavailable"?

Boas!

Estou a tentar configurar um controlo “light” feito com um ESP8266 e a lib “PubSubClient”.
Já funciona tudo excepto quando desligo o “device” o Hassio mantém o estado indefinidamente.
Há alguma configuração que tenha que ser feita para o Hassio perceber que o “device” já não está lá?

Obrigado.

@jarmilitao

Estás a utilizar um broker de MQTT?

Estou a usar o do Hassio:

 mqtt:
  broker: localhost

A pergunta era: se a comunicação do esp com o HA estava a ser realizada por mqtt. Presumo que sim.

Podes enviar o código que tens no HA?

O que queres dizer com desligo? É desligar da rede, ficar indisponível? Se for indisponibilidade do device pode estar relacionado com o LWT do device no mqtt.

NOTA: Recomendo que utilizes o mosquito, funciona melhor. Podes instalar fácil e rapidamente nos addons do hass.io.

A verdade é que o mosquitto está instalado e a correr. Agora se o estou a usar já não sei!

Para mim deligar é “desligar a alimentação”, ou seja o device “morre” sem dizer nada a ninguêm.

O que é o LWT e como é usado?

root@raspberrypi:~# ps -axj |grep mosquitto
1342 1408 1408 1342 ? -1 S 0 0:10 mosquitto -c /etc/mosquitto.conf
994 1927 1926 994 pts/0 1926 S+ 0 0:00 grep mosquitto
root@raspberrypi:~#

configuration.yaml

homeassistant:
  # Name of the location where Home Assistant is running
  name: Home
  # Location required to calculate the time the sun rises and sets
  latitude: 38.66010
  longitude: 9.17520
  # Impacts weather/sunrise data (altitude above sea level in meters)
  elevation: 80
  # metric for Metric, imperial for Imperial
  unit_system: metric
  # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: Europe/Lisbon
# Customization file
  customize: !include customize.yaml
  customize_glob:
    light.*:
      custom_ui_state_card: custom-ui
    cover.*:
      custom_ui_state_card: custom-ui

# Show links to resources in log and frontend
introduction:

# Enables the frontend
frontend:
 themes: !include_dir_merge_named themes/
 extra_html_url:
  - /local/state-card-custom-ui.html
  - /local/state-card-custom-ui.html
  - /local/vertical-stack-in-card.js
#  - /local/mycard.js
 extra_html_url_es5:
  - /local/state-card-custom-ui-es5.html
  - /local/vertical-stack-in-card.js
#  - /local/mycard.js


# Enables configuration UI
config:


# Uncomment this if you are using SSL/TLS, running in Docker container, etc.
# http:
#   base_url: example.duckdns.org:8123

# Checks for available updates
# Note: This component will send some information about your system to
# the developers to assist with development of Home Assistant.
# For more information, please see:
# https://home-assistant.io/blog/2016/10/25/explaining-the-updater/
updater:
  # Optional, allows Home Assistant developers to focus on popular components.
  # include_used_components: true

# Discover some devices automatically
discovery:
  ignore:
    - sonos
    - samsung_tv

# Allows you to issue voice commands from the frontend in enabled browsers
####conversation:

# Enables support for tracking state changes over time
###history:

# View all events in a logbook
logbook:

# Enables a map showing the location of tracked devices
map:

# Track the sun
sun:

# SmartThings Bridge
mqtt:
  broker: localhost
  keepalive: 15



# Text to speech
####tts:
#####  - platform: google

# Cloud
######cloud:

group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml

# Example configuration.yaml entry
logger:
  default: warning
  logs:
    homeassistant.components.mqtt: debug



switch: !include switches.yaml
light: !include lights.yaml
sensor: !include sensor.yaml

recorder:
  purge_keep_days: 30
  purge_interval: 1

switch.yaml

- platform: mqtt
  name: "garagem luz tv"
  state_topic: "home/garagem/switch/Luz_tv/B1/status"
  command_topic: "home/garagem/switch/Luz_tv/B1/set"
  availability_topic: "home/garagem/switch/Luz_tv/B1/available"
  payload_available: "online"
  payload_not_available: "offline"
  payload_on: "ON"
  payload_off: "OFF"
  state_on: "ON"
  state_off: "OFF"

Por acaso tens o LWT configurado no ESP?

Penso que sim.

if (mqttClient.connect(CLIENT_ID, willTopic.c_str(),0, false, willMessage.c_str()))

Com isto esperava receber periodicamente um pedido com estes tópico “willTopic” e payload “willMessage”.

Agora no Hassio é que não sei, ainda, o que tenho que fazer.

Tens de saber exactamente qual é o tópico e o payload do LWT, com o MQTTfx por exemplo, para depois colocares em availability_topic, em payload_available e payload_not_available.

Já consegui!

if (mqttClient.connect(CLIENT_ID, sSW1Availability.c_str(),0, false, sSW1NotAvailable.c_str()))

Obrigado a todos!

2 Likes

Legal, mas aonde colocou este código?

No código do device.
Após ter ligação para a rede.

obrigado, vou testar

Este é o código que utilizo. Onde adiciono o código extra?

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define MQTT_VERSION MQTT_VERSION_3_1_1

// Wifi: SSID and password
const char* WIFI_SSID = "CVBGH";
const char* WIFI_PASSWORD = "minha senha wifi";

// MQTT: ID, server IP, port, username and password
const PROGMEM char* MQTT_CLIENT_ID = "lampada_3";
const PROGMEM char* MQTT_SERVER_IP = "192.168.x,x";
const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
const PROGMEM char* MQTT_USER = "user";
const PROGMEM char* MQTT_PASSWORD = "minhasenhamqtt";

// MQTT: topics
const char* MQTT_LIGHT_STATE_TOPIC = "iead/light_3/status";
const char* MQTT_LIGHT_COMMAND_TOPIC = "iead/light_3/switch";

// payloads by default (on/off)
const char* LIGHT_ON = "ON";
const char* LIGHT_OFF = "OFF";

const PROGMEM uint8_t LED_PIN = 5;
boolean m_light_state = false; // light is turned off by defaultif (mqttClient.connect(CLIENT_ID, sSW1Availability.c_str(),0, false, sSW1NotAvailable.c_str()))

WiFiClient wifiClient;
PubSubClient client(wifiClient);

// function called to publish the state of the light (on/off)
void publishLightState() {
  if (m_light_state) {
    client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true);
  } else {
    client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true);
  }
}

// function called to turn on/off the light
void setLightState() {
  if (m_light_state) {
    digitalWrite(LED_PIN, HIGH);
    Serial.println("INFO: Turn light on...");
  } else {
    digitalWrite(LED_PIN, LOW);
    Serial.println("INFO: Turn light off...");
  }
}

// function called when a MQTT message arrived
void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
  // concat the payload into a string
  String payload;
  for (uint8_t i = 0; i < p_length; i++) {
    payload.concat((char)p_payload[i]);
  }
  
  // handle message topic
  if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) {
    // test if the payload is equal to "ON" or "OFF"
    if (payload.equals(String(LIGHT_ON))) {
      if (m_light_state != true) {
        m_light_state = true;
        setLightState();
        publishLightState();
      }
    } else if (payload.equals(String(LIGHT_OFF))) {
      if (m_light_state != false) {
        m_light_state = false;
        setLightState();
        publishLightState();
      }
    }
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("INFO: Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
      Serial.println("INFO: connected");
      // Once connected, publish an announcement...
      publishLightState();
      // ... and resubscribe
      client.subscribe(MQTT_LIGHT_COMMAND_TOPIC);
    } else {
      Serial.print("ERROR: failed, rc=");
      Serial.print(client.state());
      Serial.println("DEBUG: try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  // init the serial
  Serial.begin(115200);

  // init the led
  pinMode(LED_PIN, OUTPUT);
  analogWriteRange(255);
  setLightState();

  // init the WiFi connection
  Serial.println();
  Serial.println();
  Serial.print("INFO: Connecting to ");
  WiFi.mode(WIFI_STA);
  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("INFO: WiFi connected");
  Serial.print("INFO: IP address: ");
  Serial.println(WiFi.localIP());

  // init the MQTT connection
  client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

ok pessoal, Já consegui por aqui. Esta tudo funcionando como o previsto.

obrigado,

Este tópico foi automaticamente fechado 90 dias após a última resposta. Novas respostas não são permitidas.


Copyright © 2017-2020. Todos os direitos reservados
CPHA.pt - info@cpha.pt


FAQ | Termos de Serviço/Regras | Política de Privacidade