Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HVAC thermostat is not controllable from HASS #275

Open
andrewhack opened this issue Dec 4, 2024 · 6 comments
Open

HVAC thermostat is not controllable from HASS #275

andrewhack opened this issue Dec 4, 2024 · 6 comments

Comments

@andrewhack
Copy link

Hi,
Am I missing something - can't control the target temperature from HASS.
Changing the mode is working fine.
I am using the provided HVAC example with Arduino Mega and Ethernet shield.

These are the features which I am using

HAHVAC::TargetTemperatureFeature | HAHVAC::PowerFeature | HAHVAC::ModesFeature

image

@andrewhack
Copy link
Author

My investigation shows that mqtt "mode" and "target temp" entries are missing, just "current temp" is available.
I assume there is no initial or not complete mqtt setup.

Can somebody assist here?

@MarshallVisions
Copy link

MarshallVisions commented Dec 16, 2024

am having the same problem... find a solution by any chance? mine worked for over a year but stopped working. I think it stopped working after I started a new Home Assistant.

@simbycube
Copy link

same problem for me too.

@shotreal
Copy link

same issue here. If you publish something to the [...]/temp_cmd_t topic then itll work

@MarshallVisions
Copy link

MarshallVisions commented Jan 19, 2025

still not sure how I fixed it, but the following code works for me for being able to set the 'Target Temperature' and also show the 'Current Temperature'. Hope this helps someone. It's a retrofitted thermostat which fits on top of my dumb apartment thermostat and uses a servo to move the thermostat adjustment arm.

#include <Arduino.h>
#include <WiFi.h>
#include <ESP32Servo.h>
#include <DHT.h>
#include <ArduinoHA.h>

// WiFi Settings
const char *ssid = "MV-Terminal_2.4GHz";
const char *password = "************";
IPAddress local_IP(192, 168, 0, 215);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

// MQTT Settings
#define mqttServer IPAddress(192, 168, 0, 126)
// const int mqttPort = 1883;
const char *mqttUser = "MQTT-User";
const char *mqttPassword = "***********";

// DHT11 Settings
#define DHTPIN 4 // DHT11 data pin
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float dhtOffset = -5;
float dhtLastCheck;
float dhtCheckInterval = 1000;

// Home Assistant Settings
// Entity Settings
WiFiClient wifiClient;
HADevice device("RetroStat-Basic");
HAMqtt mqtt(wifiClient, device);
HAHVAC climate(
    "retrostat-hvac", HAHVAC::TargetTemperatureFeature);

HANumber humidity("RetroStat-Basic-Humidity");
HANumber dhtOffsetNumber("RetroStat-Basic-DHT-Offset");

// Servo Settings
Servo servo;
const int servoPin = 7;

// Temperature Settings
float currentTemperature = 20; // Initial temperature set to 20 degrees
float targetTemperature = 20;
const float minTemp = 10;
const float maxTemp = 35;

// Function declarations
void setServoPosition(int temp);
void onTargetTemperatureCommand(HANumeric temperature, HAHVAC *sender);
void onDhtOffsetCommand(HANumeric value, HANumber *sender);

void setup()
{
    Serial.begin(115200);
    dht.begin();
    servo.attach(servoPin, 500, 2500);

    // Connect to WiFi
    Serial.println("Connecting to WiFi...");
    // WiFi.config(local_IP, gateway, subnet);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("WiFi connected");

    // Connect to MQTT
    Serial.println("Connecting to MQTT...");
    mqtt.begin(mqttServer, 1883, mqttUser, mqttPassword);
    mqtt.setDataPrefix("homeassistant/climate"); // not fully sure about this one. defaults to "aha"

    // Initialize Home Assistant components
    device.setName("RetroStat Basic");
    device.setSoftwareVersion("2.0.0");
    device.setManufacturer("MarshallVisions");
    device.setModel("RS-Basic");
    device.enableSharedAvailability();
    device.enableLastWill();
    climate.setName("RetroStat");
    climate.setMinTemp(minTemp);
    climate.setMaxTemp(maxTemp);
    climate.setCurrentTemperature(currentTemperature);
    climate.setTargetTemperature(targetTemperature);
    climate.setRetain(true);
    climate.onTargetTemperatureCommand(onTargetTemperatureCommand);
    humidity.setName("Humidity");
    humidity.setRetain(true);
    dhtOffsetNumber.setName("DHT Temperature Offset");
    dhtOffsetNumber.setRetain(true);
    dhtOffsetNumber.onCommand(onDhtOffsetCommand);

    Serial.println("Setup complete.");
}

void loop()
{
    mqtt.loop();

    if (millis() - dhtLastCheck > dhtCheckInterval)
    {
        // Read temperature from DHT11
        float temp = dht.readTemperature() + dhtOffset;
        float hum = dht.readHumidity();
        currentTemperature = temp;
        climate.setCurrentTemperature((float)currentTemperature);
        humidity.setState(hum);
        dhtLastCheck = millis();
        Serial.print("Current temperature from DHT11: ");
        Serial.println(temp);
        Serial.print("Current humidity from DHT11: ");
        Serial.println(hum);
    }
}

void setServoPosition(int temp)
{
    int pos = map(temp, minTemp, maxTemp, 180, 0);
    Serial.print("Setting servo position to: ");
    Serial.println(pos);
    servo.write(pos);
}

// Function to handle target temperature command from Home Assistant
void onTargetTemperatureCommand(HANumeric temperature, HAHVAC *sender)
{
    float temperatureFloat = temperature.toFloat();
    if (temperatureFloat >= minTemp && temperatureFloat <= maxTemp)
    {
        targetTemperature = temperatureFloat;
        Serial.print("Target temperature command received. New target temperature: ");
        Serial.println(temperatureFloat);
        setServoPosition(targetTemperature);
        sender->setTargetTemperature(temperature); // report target temperature back to the HA panel
    }
}

void onDhtOffsetCommand(HANumeric value, HANumber *sender)
{
    float offsetFloat = value.toFloat();
    if (offsetFloat >= -10 && offsetFloat <= 10)
    {
        dhtOffset = offsetFloat;
        Serial.print("DHT value command received. New value: ");
        Serial.println(offsetFloat);
        dhtLastCheck = millis();
        sender->setState(dhtOffset);
    }
}

@andrewhack
Copy link
Author

andrewhack commented Jan 23, 2025

still not sure how I fixed it, but the following code works for me for being able to set the 'Target Temperature' and also show the 'Current Temperature'. Hope this helps someone. It's a retrofitted thermostat which fits on top of my dumb apartment thermostat and uses a servo to move the thermostat adjustment arm.

#include <Arduino.h>
#include <WiFi.h>
#include <ESP32Servo.h>
#include <DHT.h>
#include <ArduinoHA.h>

// WiFi Settings
const char *ssid = "MV-Terminal_2.4GHz";
const char *password = "***********";
IPAddress local_IP(192, 168, 0, 215);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

// MQTT Settings
#define mqttServer IPAddress(192, 168, 0, 126)
// const int mqttPort = 1883;
const char *mqttUser = "MQTT-User";
const char *mqttPassword = "***********";

// DHT11 Settings
#define DHTPIN 4 // DHT11 data pin
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float dhtOffset = -5;
float dhtLastCheck;
float dhtCheckInterval = 1000;

// Home Assistant Settings
// Entity Settings
WiFiClient wifiClient;
HADevice device("RetroStat-Basic");
HAMqtt mqtt(wifiClient, device);
HAHVAC climate(
    "retrostat-hvac", HAHVAC::TargetTemperatureFeature);

HANumber humidity("RetroStat-Basic-Humidity");
HANumber dhtOffsetNumber("RetroStat-Basic-DHT-Offset");

// Servo Settings
Servo servo;
const int servoPin = 7;

// Temperature Settings
float currentTemperature = 20; // Initial temperature set to 20 degrees
float targetTemperature = 20;
const float minTemp = 10;
const float maxTemp = 35;

// Function declarations
void setServoPosition(int temp);
void onTargetTemperatureCommand(HANumeric temperature, HAHVAC *sender);
void onDhtOffsetCommand(HANumeric value, HANumber *sender);

void setup()
{
    Serial.begin(115200);
    dht.begin();
    servo.attach(servoPin, 500, 2500);

    // Connect to WiFi
    Serial.println("Connecting to WiFi...");
    // WiFi.config(local_IP, gateway, subnet);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("WiFi connected");

    // Connect to MQTT
    Serial.println("Connecting to MQTT...");
    mqtt.begin(mqttServer, 1883, mqttUser, mqttPassword);
    mqtt.setDataPrefix("homeassistant/climate"); // not fully sure about this one. defaults to "aha"

    // Initialize Home Assistant components
    device.setName("RetroStat Basic");
    device.setSoftwareVersion("2.0.0");
    device.setManufacturer("MarshallVisions");
    device.setModel("RS-Basic");
    device.enableSharedAvailability();
    device.enableLastWill();
    climate.setName("RetroStat");
    climate.setMinTemp(minTemp);
    climate.setMaxTemp(maxTemp);
    climate.setCurrentTemperature(currentTemperature);
    climate.setTargetTemperature(targetTemperature);
    climate.setRetain(true);
    climate.onTargetTemperatureCommand(onTargetTemperatureCommand);
    humidity.setName("Humidity");
    humidity.setRetain(true);
    dhtOffsetNumber.setName("DHT Temperature Offset");
    dhtOffsetNumber.setRetain(true);
    dhtOffsetNumber.onCommand(onDhtOffsetCommand);

    Serial.println("Setup complete.");
}

void loop()
{
    mqtt.loop();

    if (millis() - dhtLastCheck > dhtCheckInterval)
    {
        // Read temperature from DHT11
        float temp = dht.readTemperature() + dhtOffset;
        float hum = dht.readHumidity();
        currentTemperature = temp;
        climate.setCurrentTemperature((float)currentTemperature);
        humidity.setState(hum);
        dhtLastCheck = millis();
        Serial.print("Current temperature from DHT11: ");
        Serial.println(temp);
        Serial.print("Current humidity from DHT11: ");
        Serial.println(hum);
    }
}

void setServoPosition(int temp)
{
    int pos = map(temp, minTemp, maxTemp, 180, 0);
    Serial.print("Setting servo position to: ");
    Serial.println(pos);
    servo.write(pos);
}

// Function to handle target temperature command from Home Assistant
void onTargetTemperatureCommand(HANumeric temperature, HAHVAC *sender)
{
    float temperatureFloat = temperature.toFloat();
    if (temperatureFloat >= minTemp && temperatureFloat <= maxTemp)
    {
        targetTemperature = temperatureFloat;
        Serial.print("Target temperature command received. New target temperature: ");
        Serial.println(temperatureFloat);
        setServoPosition(targetTemperature);
        sender->setTargetTemperature(temperature); // report target temperature back to the HA panel
    }
}

void onDhtOffsetCommand(HANumeric value, HANumber *sender)
{
    float offsetFloat = value.toFloat();
    if (offsetFloat >= -10 && offsetFloat <= 10)
    {
        dhtOffset = offsetFloat;
        Serial.print("DHT value command received. New value: ");
        Serial.println(offsetFloat);
        dhtLastCheck = millis();
        sender->setState(dhtOffset);
    }
}

Probably this create the missing MQTT entries - this is what I found (mentioned above)
Thank you for sharing this, I will test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants