Thermostat pour piloter jusqu'à 4 radiateurs avec fil pilote
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

199 lines
4.8 KiB

/*
main_pilot_wire_control.ino
Switches on or off several heaters.
*/
#include <Ticker.h>
#include "EspMQTTClient.h"
#define LWD_TIMEOUT_MS 15000
EspMQTTClient client(
"rico2",
"xxxxx",
"192.168.1.2", // MQTT Broker server ip
"", // Can be omitted if not needed
"", // Can be omitted if not needed
"pilote-general", // Client name that uniquely identify your device
1883 // The MQTT port, default to 1883. this line can be omitted
);
enum rooms {
LIVING_ROOM,
ROOM_SO,
ROOM_RICO,
BATHROOM,
NB_HEATERS
};
struct heater {
int pin;
enum rooms room;
const char *topic;
MessageReceivedCallback callback;
os_timer_t keep_alive_timer;
};
static struct heater heaters[NB_HEATERS];
const int led_pin = 2;
#define led_on(state) do {\
digitalWrite(led_pin, (state) ? LOW : HIGH); \
} while (0)
#define heater_on(pin) do {\
digitalWrite(pin, LOW); \
} while(0)
#define heater_off(pin) do {\
digitalWrite(pin, HIGH); \
} while(0)
// loop watchdog variables
unsigned long lwdTime = 0;
unsigned long lwdTimeout = LWD_TIMEOUT_MS;
Ticker lwdTicker;
void reset_timer(enum rooms room)
{
os_timer_t *timer = &(heaters[room].keep_alive_timer);
os_timer_disarm(timer);
os_timer_setfn(timer, shutdown_heater, &(heaters[room].room));
os_timer_arm(timer, 3600000, false);
}
void ICACHE_RAM_ATTR lwdtcb(void)
{
if (((millis() - lwdTime) > LWD_TIMEOUT_MS) || ((lwdTimeout - lwdTime) != LWD_TIMEOUT_MS))
{
ESP.restart();
}
}
void lwdtFeed(void) {
lwdTime = millis();
lwdTimeout = lwdTime + LWD_TIMEOUT_MS;
}
void handle_message(enum rooms room, const String &message)
{
Serial.println(message);
if (message.equals("0") || message.equalsIgnoreCase("off") || message.equalsIgnoreCase("false")) {
heater_off(heaters[room].pin);
}
if (message.equals("1") || message.equalsIgnoreCase("on") || message.equalsIgnoreCase("true")) {
heater_on(heaters[room].pin);
}
reset_timer(room);
}
void living_room_callback(const String &message)
{
handle_message(LIVING_ROOM, message);
}
void room_so_callback(const String &message)
{
handle_message(ROOM_SO, message);
}
void room_rico_callback(const String &message)
{
handle_message(ROOM_RICO, message);
}
void bathroom_callback(const String &message)
{
handle_message(BATHROOM, message);
}
void shutdown_heater(void *arg)
{
enum rooms room = *(enum rooms *)arg;
// if we didn't receive a message for an hour,
// shutdown the heater
Serial.print("No MQTT message for one hour on topic ");
Serial.print(heaters[room].topic);
Serial.println(", switching off.");
heater_off(heaters[room].pin);
}
void setup()
{
unsigned i;
heaters[LIVING_ROOM].room = LIVING_ROOM;
heaters[ROOM_SO].room = ROOM_SO;
heaters[ROOM_RICO].room = ROOM_RICO;
heaters[BATHROOM].room = BATHROOM;
heaters[LIVING_ROOM].pin = 4;
heaters[ROOM_SO].pin = 14;
heaters[ROOM_RICO].pin = 12;
heaters[BATHROOM].pin = 13;
heaters[LIVING_ROOM].topic = "chauffage/salon";
heaters[ROOM_SO].topic = "chauffage/chambre_rico";
heaters[ROOM_RICO].topic = "chauffage/chambre_so";
heaters[BATHROOM].topic = "chauffage/sdb";
heaters[LIVING_ROOM].callback = living_room_callback;
heaters[ROOM_SO].callback = room_so_callback;
heaters[ROOM_RICO].callback = room_rico_callback;
heaters[BATHROOM].callback = bathroom_callback;
lwdTicker.attach_ms(LWD_TIMEOUT_MS / 2, lwdtcb);
for (i = 0; i < NB_HEATERS; i++) {
pinMode(heaters[i].pin, OUTPUT);
heater_off(heaters[i].pin);
}
pinMode(led_pin, OUTPUT);
Serial.begin(115200);
// Optionnal functionnalities of EspMQTTClient :
client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password").
for (i = 0; i < NB_HEATERS; i++) {
os_timer_setfn(&(heaters[i].keep_alive_timer), shutdown_heater, &(heaters[i].room));
os_timer_arm(&(heaters[i].keep_alive_timer), 3600000, false);
}
}
// This function is called once everything is connected (Wifi and MQTT)
// WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient
void onConnectionEstablished()
{
for (unsigned i = 0; i < NB_HEATERS; i++) {
client.subscribe(heaters[i].topic, heaters[i].callback);
}
}
void loop()
{
static unsigned int counter;
static bool led_state = false;
lwdtFeed();
client.loop();
if (!client.isConnected()) {
// if something wrong happens, switch off the heater
for (unsigned i = 0; i < NB_HEATERS; i++) {
heater_off(heaters[i].pin);
}
}
// blink ESP blue led to show that we are alive
if (((led_state) && (counter % 1000 == 0)) || (!led_state && (counter % 30000 == 0))) {
led_state = !led_state;
led_on(led_state);
}
counter++;
}