Added basic device control.

This commit is contained in:
Chris Giacofei 2023-01-27 10:58:31 -05:00
parent fc80a43331
commit a9788e82a6
2 changed files with 118 additions and 41 deletions

View File

@ -4,7 +4,7 @@
#include <PubSubClient.h> #include <PubSubClient.h>
#include <OneWire.h> #include <OneWire.h>
#include <DallasTemperature.h> #include <DallasTemperature.h>
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <Tools.h> #include <Tools.h>
#include <secrets.h> #include <secrets.h>
@ -31,17 +31,17 @@ const char version[] = "0.0.1";
#ifndef DEVICE_NAME #ifndef DEVICE_NAME
#define DEVICE_NAME "MQTT Thermostat" #define DEVICE_NAME "MQTT Thermostat"
#endif #endif
#ifndef DEVICE_MDL #ifndef DEVICE_MDL
#define DEVICE_MDL "Thermostat" #define DEVICE_MDL "Thermostat"
#endif #endif
#ifndef DEVICE_MF #ifndef DEVICE_MF
#define DEVICE_MF "" #define DEVICE_MF ""
#endif #endif
#ifndef ROOT #ifndef ROOT
#define ROOT "thermostat/" #define ROOT "thermostat/"
#endif #endif
@ -55,24 +55,22 @@ const char version[] = "0.0.1";
#define TOPIC_LIMIT 4 #define TOPIC_LIMIT 4
#define OFF 0 //~ #define OFF 0
#define COOL 1 //~ #define COOL 1
#define HEAT 2 //~ #define HEAT 2
#define AUTO 3 //~ #define AUTO 3
#define TEMP 0
#define TEMP_HI 1
#define TEMP_LO 2
uint8_t CHILLER_SP = 70; uint8_t CHILLER_SP = 70;
uint8_t FERMA_SP = 70; uint8_t FERMA_SP = 70;
uint8_t FERMB_SP = 70; uint8_t FERMB_SP = 70;
uint8_t CHILLER_MD = OFF;
uint8_t FERMA_MD = OFF;
uint8_t FERMB_MD = OFF;
//~ typedef void (*ptr)(uint8_t*, uint8_t*); //~ typedef void (*ptr)(uint8_t*, uint8_t*);
//typedef ptr (*pm)(); //typedef ptr (*pm)();
struct CommandTopic { struct CommandTopic {
//~ ptr CmdFunc; //~ ptr CmdFunc;
byte* Setting; byte* Setting;
@ -100,6 +98,8 @@ struct ControlDevice {
String action_state; String action_state;
String swing_topic; String swing_topic;
String swing_state; String swing_state;
byte heat_pin;
byte cool_pin;
Mode mode; Mode mode;
SetPoint setpoints[3]; SetPoint setpoints[3];
bool dual; bool dual;
@ -108,15 +108,76 @@ struct ControlDevice {
float UpdateTemperature(DallasTemperature *sensors, DeviceAddress glycol_tank) { float UpdateTemperature(DallasTemperature *sensors, DeviceAddress glycol_tank) {
// method 2 - faster // method 2 - faster
float tempC = sensors->getTempC(glycol_tank); float tempC = sensors->getTempC(glycol_tank);
if(tempC == DEVICE_DISCONNECTED_C) if(tempC == DEVICE_DISCONNECTED_C)
{ {
Serial.println("Error: Could not read temperature data"); Serial.println("Error: Could not read temperature data");
return 0; return 0;
} }
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" Temp F: ");
return DallasTemperature::toFahrenheit(tempC); return DallasTemperature::toFahrenheit(tempC);
} }
bool DeviceLoop(ControlDevice &device, DallasTemperature *sensors) {
Serial.println(device.name);
float dsTemp = UpdateTemperature(sensors, device.temp_sensor);
String initial_action = device.action_state;
if (device.mode.Setting == "auto") {
int setHi = device.setpoints[TEMP_HI].Setting;
int setLo = device.setpoints[TEMP_LO].Setting;
if ((setLo <= dsTemp) && (dsTemp <= setHi)) { // Within Temp Range
device.action_state = ACTION_IDLE;
digitalWrite(device.cool_pin, LOW);
digitalWrite(device.heat_pin, LOW);
} else if (dsTemp < setLo) { // Needs Heat
device.action_state = ACTION_HEATING;
digitalWrite(device.cool_pin, LOW);
digitalWrite(device.heat_pin, HIGH);
} else if (dsTemp > setHi) { // Needs Cooling
device.action_state = ACTION_COOLING;
digitalWrite(device.cool_pin, HIGH);
digitalWrite(device.heat_pin, LOW);
}
}
int setTemp = device.setpoints[TEMP].Setting;
if (device.mode.Setting == "cool") {
if (dsTemp > setTemp) { // Needs Cooling
device.action_state = ACTION_COOLING;
digitalWrite(device.cool_pin, HIGH);
digitalWrite(device.heat_pin, LOW);
} else {
device.action_state = ACTION_IDLE;
digitalWrite(device.cool_pin, LOW);
digitalWrite(device.heat_pin, LOW);
}
}
if (device.mode.Setting == "heat") {
if (dsTemp < setTemp) { // Needs Cooling
device.action_state = ACTION_HEATING;
digitalWrite(device.cool_pin, LOW);
digitalWrite(device.heat_pin, HIGH);
} else {
device.action_state = ACTION_IDLE;
digitalWrite(device.cool_pin, LOW);
digitalWrite(device.heat_pin, LOW);
}
}
if (device.mode.Setting == "off") {
device.action_state = ACTION_IDLE;
}
if (initial_action != device.action_state) {
return true;
}
return false;
}
#endif #endif

View File

@ -88,8 +88,8 @@ void climateDevice(String name, byte ds18b20[], bool multimode=false) {
ControlDevice device; ControlDevice device;
device.dual = false; device.dual = false;
device.name = name; device.name = name;
device.topic_root = topic_root; device.topic_root = "brewhouse/" + slugify(name) + "/";
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
device.temp_sensor[i] = ds18b20[i]; device.temp_sensor[i] = ds18b20[i];
} }
@ -161,26 +161,24 @@ void climateDevice(String name, byte ds18b20[], bool multimode=false) {
hass_comm.mqtt_discovery(config_topic, entity); hass_comm.mqtt_discovery(config_topic, entity);
} }
void SendUpdate() { void SendUpdate(ControlDevice device) {
int setpoint_count = 0; int setpoint_count = 0;
float device_temp; float device_temp;
for (int i=0;i<TOTAL_DEVICES;i++) { device_temp = UpdateTemperature(&sensors, device.temp_sensor);
device_temp = UpdateTemperature(&sensors, DEVICE_LIST[i].temp_sensor); hass_comm.publish_data(device.current_temp_topic, String(device_temp));
hass_comm.publish_data(DEVICE_LIST[i].current_temp_topic, String(device_temp)); hass_comm.publish_data(device.mode.StateTopic, device.mode.Setting);
hass_comm.publish_data(DEVICE_LIST[i].mode.StateTopic, DEVICE_LIST[i].mode.Setting); hass_comm.publish_data(device.action_topic, device.action_state);
hass_comm.publish_data(DEVICE_LIST[i].action_topic, ACTION_COOLING); bool dual_mode = device.dual;
bool dual_mode = DEVICE_LIST[i].dual;
if (dual_mode) { if (dual_mode) {
setpoint_count = 3; setpoint_count = 3;
} else { } else {
setpoint_count = 1; setpoint_count = 1;
} }
for (int j=0;j<setpoint_count;j++) { for (int i=0;i<setpoint_count;i++) {
hass_comm.publish_data(DEVICE_LIST[i].setpoints[j].StateTopic, String(DEVICE_LIST[i].setpoints[j].Setting)); hass_comm.publish_data(device.setpoints[i].StateTopic, String(device.setpoints[i].Setting));
} }
}
} }
void setup() { void setup() {
@ -206,16 +204,34 @@ void setup() {
climateDevice("Fermenter 1", fermA_ds18b20,true); climateDevice("Fermenter 1", fermA_ds18b20,true);
climateDevice("Fermenter 2", fermB_ds18b20,true); climateDevice("Fermenter 2", fermB_ds18b20,true);
SendUpdate(); SendUpdate(DEVICE_LIST[0]);
SendUpdate(DEVICE_LIST[1]);
SendUpdate(DEVICE_LIST[2]);
lastMillis = millis(); lastMillis = millis();
} }
void loop() { void loop() {
currentMillis = millis(); currentMillis = millis();
if (currentMillis - lastMillis >= 10000) { if (currentMillis - lastMillis >= 10000) {
if (DeviceLoop(DEVICE_LIST[0], &sensors)) {
Serial.println("Ouput state changed.");
SendUpdate(DEVICE_LIST[0]);
}
if (DeviceLoop(DEVICE_LIST[1], &sensors)) {
Serial.println("Ouput state changed.");
SendUpdate(DEVICE_LIST[1]);
}
if (DeviceLoop(DEVICE_LIST[2], &sensors)) {
Serial.println("Ouput state changed.");
SendUpdate(DEVICE_LIST[2]);
}
sensors.requestTemperatures(); sensors.requestTemperatures();
SendUpdate(); SendUpdate(DEVICE_LIST[0]);
SendUpdate(DEVICE_LIST[1]);
SendUpdate(DEVICE_LIST[2]);
lastMillis = currentMillis; lastMillis = currentMillis;
} }