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

Added support for controlling a second relay for cooling. #441

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 67 additions & 16 deletions include/mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
#define MQTT_lwt "espaltherma/LWT"

#define EEPROM_CHK 1
#define EEPROM_STATE 0
#define EEPROM_HEAT_STATE 0

#ifdef PIN_COOL
#define EEPROM_COOL_STATE 2
#endif

#define MQTT_attr "espaltherma/ATTR"
#define MQTT_lwt "espaltherma/LWT"

enum Mode { heating, cooling };

#ifdef JSONTABLE
char jsonbuff[MAX_MSG_SIZE] = "[{\0";
#else
Expand Down Expand Up @@ -53,22 +59,32 @@ void sendValues()
#endif
}

void saveEEPROM(uint8_t state){
EEPROM.write(EEPROM_STATE,state);
void saveEEPROM(uint8_t address, uint8_t state){
EEPROM.write(address,state);
EEPROM.commit();
}

void readEEPROM(){
if ('R' == EEPROM.read(EEPROM_CHK)){
digitalWrite(PIN_THERM,EEPROM.read(EEPROM_STATE));
mqttSerial.printf("Restoring previous state: %s",(EEPROM.read(EEPROM_STATE) == PIN_THERM_ACTIVE_STATE)? "On":"Off" );
digitalWrite(PIN_THERM,EEPROM.read(EEPROM_HEAT_STATE));
mqttSerial.printf("Restoring previous heating state: %s",(EEPROM.read(EEPROM_HEAT_STATE) == PIN_THERM_ACTIVE_STATE)? "On":"Off" );
#ifdef PIN_COOL
digitalWrite(PIN_COOL,EEPROM.read(EEPROM_COOL_STATE));
mqttSerial.printf("Restoring previous cooling state: %s",(EEPROM.read(EEPROM_COOL_STATE) == PIN_THERM_ACTIVE_STATE)? "On":"Off" );
#endif
}
else{
mqttSerial.printf("EEPROM not initialized (%d). Initializing...",EEPROM.read(EEPROM_CHK));
EEPROM.write(EEPROM_CHK,'R');
EEPROM.write(EEPROM_STATE,!PIN_THERM_ACTIVE_STATE);
EEPROM.write(EEPROM_HEAT_STATE,!PIN_THERM_ACTIVE_STATE);
#ifdef PIN_COOL
EEPROM.write(EEPROM_COOL_STATE,!PIN_THERM_ACTIVE_STATE);
#endif
EEPROM.commit();
digitalWrite(PIN_THERM,!PIN_THERM_ACTIVE_STATE);
#ifdef PIN_COOL
digitalWrite(PIN_COOL,!PIN_THERM_ACTIVE_STATE);
#endif
}
}

Expand All @@ -89,6 +105,12 @@ void reconnectMqtt()

// Subscribe
client.subscribe("espaltherma/POWER");

#ifdef PIN_COOL
client.publish("homeassistant/switch/espAltherma_cool/config", "{\"name\":\"Altherma_cooling\",\"cmd_t\":\"~/COOLING\",\"stat_t\":\"~/COOL_STATE\",\"pl_off\":\"OFF\",\"pl_on\":\"ON\",\"~\":\"espaltherma\"}", true);
client.subscribe("espaltherma/COOLING");
#endif

#ifdef PIN_SG1
// Smart Grid
client.publish("homeassistant/select/espAltherma/sg/config", "{\"availability\":[{\"topic\":\"espaltherma/LWT\",\"payload_available\":\"Online\",\"payload_not_available\":\"Offline\"}],\"availability_mode\":\"all\",\"unique_id\":\"espaltherma_sg\",\"device\":{\"identifiers\":[\"ESPAltherma\"],\"manufacturer\":\"ESPAltherma\",\"model\":\"M5StickC PLUS ESP32-PICO\",\"name\":\"ESPAltherma\"},\"icon\":\"mdi:solar-power\",\"name\":\"EspAltherma Smart Grid\",\"command_topic\":\"espaltherma/sg/set\",\"command_template\":\"{% if value == 'Free Running' %} 0 {% elif value == 'Forced Off' %} 1 {% elif value == 'Recommended On' %} 2 {% elif value == 'Forced On' %} 3 {% else %} 0 {% endif %}\",\"options\":[\"Free Running\",\"Forced Off\",\"Recommended On\",\"Forced On\"],\"state_topic\":\"espaltherma/sg/state\",\"value_template\":\"{% set mapper = { '0':'Free Running', '1':'Forced Off', '2':'Recommended On', '3':'Forced On' } %} {% set word = mapper[value] %} {{ word }}\"}", true);
Expand Down Expand Up @@ -124,25 +146,48 @@ void reconnectMqtt()
}
}

void callbackTherm(byte *payload, unsigned int length)
void setHeatPumpState(Mode mode, bool turn_on) {
// It is possible that the state is inversed in comparison to the original code for heating only, not sure why
uint8_t state = (turn_on) ? PIN_THERM_ACTIVE_STATE : !PIN_THERM_ACTIVE_STATE;
std::string value = (turn_on) ? "ON" : "OFF";

std::string topic = (mode == heating) ? "STATE" : "COOL_STATE";
unsigned int pin = (mode == heating) ? PIN_THERM : PIN_COOL;
uint8_t eeprom_address = (mode == heating) ? EEPROM_HEAT_STATE : EEPROM_COOL_STATE;

digitalWrite(pin, state);
saveEEPROM(eeprom_address, state);

client.publish(("espaltherma/" + topic).c_str(), value.c_str(), true);

std::string logmessage = "Turned " + topic + " " + value;
mqttSerial.println(logmessage.c_str());
}

void callbackHeatPumpState(byte *payload, unsigned int length, Mode mode)
{
payload[length] = '\0';

// Is it ON or OFF?
// Ok I'm not super proud of this, but it works :p
if (payload[1] == 'F')
{ //turn off
digitalWrite(PIN_THERM, !PIN_THERM_ACTIVE_STATE);
saveEEPROM(!PIN_THERM_ACTIVE_STATE);
client.publish("espaltherma/STATE", "OFF", true);
mqttSerial.println("Turned OFF");
setHeatPumpState(mode, false);
}
else if (payload[1] == 'N')
{ //turn on
digitalWrite(PIN_THERM, PIN_THERM_ACTIVE_STATE);
saveEEPROM(PIN_THERM_ACTIVE_STATE);
client.publish("espaltherma/STATE", "ON", true);
mqttSerial.println("Turned ON");
if (mode == heating) {
#ifdef PIN_COOL
setHeatPumpState(cooling, false);
#endif
setHeatPumpState(heating, true);
}
#ifdef PIN_COOL
else {
setHeatPumpState(heating, false);
setHeatPumpState(cooling, true);
}
#endif
}
else if (payload[0] == 'R')//R(eset/eboot)
{
Expand Down Expand Up @@ -232,8 +277,14 @@ void callback(char *topic, byte *payload, unsigned int length)

if (strcmp(topic, "espaltherma/POWER") == 0)
{
callbackTherm(payload, length);
callbackHeatPumpState(payload, length, heating);
}
#ifdef PIN_COOL
else if (strcmp(topic, "espaltherma/COOLING") == 0)
{
callbackHeatPumpState(payload, length, cooling);
}
#endif
#ifdef PIN_SG1
else if (strcmp(topic, "espaltherma/sg/set") == 0)
{
Expand Down
5 changes: 5 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ void setup()
pinMode(PIN_THERM, OUTPUT);
// digitalWrite(PIN_THERM, PIN_THERM_ACTIVE_STATE);

#ifdef PIN_COOL
pinMode(PIN_COOL, OUTPUT);
// digitalWrite(PIN_COOL, PIN_THERM_ACTIVE_STATE);
#endif

#ifdef SAFETY_RELAY_PIN
pinMode(SAFETY_RELAY_PIN, OUTPUT);
digitalWrite(SAFETY_RELAY_PIN, !SAFETY_RELAY_ACTIVE_STATE);
Expand Down
3 changes: 2 additions & 1 deletion src/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
#endif

#define PIN_THERM 0// Pin connected to the thermostat relay (normally open)
#define PIN_THERM_ACTIVE_STATE HIGH// State to trigger the thermostat relay
#define PIN_THERM_ACTIVE_STATE HIGH// State to trigger the thermostat/ cooling relay
#define PIN_COOL 4// Pin connected to the cooling relay (normally open)

//Smart grid control - Optional:
//Uncomment and set to enable SG mqtt functions
Expand Down