-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #194 from IgorYbema/main
Release of version v1.0
- Loading branch information
Showing
25 changed files
with
1,739 additions
and
939 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,129 @@ | ||
#include <ESP8266WiFi.h> | ||
|
||
#include <ArduinoJson.h> | ||
|
||
#define PANASONICQUERYSIZE 110 | ||
extern byte panasonicQuery[PANASONICQUERYSIZE]; | ||
|
||
#define OPTIONALPCBQUERYSIZE 19 | ||
#define OPTIONALPCBSAVETIME 300 //save each 5 minutes the current optional pcb state into flash to have valid values during reboot | ||
extern byte optionalPCBQuery[OPTIONALPCBQUERYSIZE]; | ||
#define NUMBER_OF_OPTIONALPCB_TOPICS 13 | ||
|
||
static const char * optionalPcbTopics[] = { | ||
"Heat_Cool_Mode", | ||
"Compressor_State", | ||
"SmartGrid_Mode", | ||
"External_Thermostat_1_State", | ||
"External_Thermostat_2_State", | ||
"Demand_Control", | ||
"Pool_Temp", | ||
"Buffer_Temp", | ||
"Z1_Room_Temp", | ||
"Z1_Water_Temp", | ||
"Z2_Room_Temp", | ||
"Z2_Water_Temp", | ||
"Solar_Temp" | ||
}; | ||
|
||
static const byte optionalPcbBytes[] = { | ||
6, | ||
6, | ||
6, | ||
6, | ||
6, | ||
14, | ||
7, | ||
8, | ||
10, | ||
16, | ||
11, | ||
15, | ||
13 | ||
}; | ||
|
||
extern const char* mqtt_topic_values; | ||
extern const char* mqtt_topic_commands; | ||
extern const char* mqtt_topic_pcbvalues; | ||
extern const char* mqtt_topic_1wire; | ||
extern const char* mqtt_topic_s0; | ||
extern const char* mqtt_topic_pcb; | ||
extern const char* mqtt_logtopic; | ||
extern const char* mqtt_willtopic; | ||
extern const char* mqtt_iptopic; | ||
extern const char* mqtt_set_heatpump_state_topic; | ||
extern const char* mqtt_set_quiet_mode_topic; | ||
extern const char* mqtt_set_z1_heat_request_temperature_topic; | ||
extern const char* mqtt_set_z1_cool_request_temperature_topic; | ||
extern const char* mqtt_set_z2_heat_request_temperature_topic; | ||
extern const char* mqtt_set_z2_cool_request_temperature_topic; | ||
extern const char* mqtt_set_operationmode_topic; | ||
extern const char* mqtt_set_force_DHW_topic; | ||
extern const char* mqtt_set_force_defrost_topic; | ||
extern const char* mqtt_set_force_sterilization_topic; | ||
extern const char* mqtt_set_holiday_topic; | ||
extern const char* mqtt_set_powerful_topic; | ||
extern const char* mqtt_set_dhw_temp_topic; | ||
extern const char* mqtt_send_raw_value_topic; | ||
extern const char* mqtt_set_pump_topic; | ||
extern const char* mqtt_set_pumpspeed_topic; | ||
|
||
void send_heatpump_command(char* topic, char *msg,bool (*send_command)(byte*, int),void (*log_message)(char*)); | ||
void set_optionalpcb(char* topic, char *msg,void (*log_message)(char*)); | ||
unsigned int set_heatpump_state(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_pump(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_pump_speed(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_quiet_mode(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_z1_heat_request_temperature(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_z1_cool_request_temperature(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_z2_heat_request_temperature(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_z2_cool_request_temperature(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_force_DHW(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_force_defrost(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_force_sterilization(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_holiday_mode(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_powerful_mode(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_operation_mode(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_DHW_temp(char *msg, unsigned char *cmd, char *log_msg); | ||
unsigned int set_curves(char *msg, unsigned char *cmd,char *log_msg); | ||
unsigned int set_zones(char *msg, unsigned char *cmd,char *log_msg); | ||
unsigned int set_floor_heat_delta(char *msg, unsigned char *cmd,char *log_msg); | ||
unsigned int set_floor_cool_delta(char *msg, unsigned char *cmd,char *log_msg); | ||
unsigned int set_dhw_heat_delta(char *msg, unsigned char *cmd,char *log_msg); | ||
|
||
|
||
//optional pcb commands | ||
unsigned int set_heat_cool_mode(char *msg, char *log_msg); | ||
unsigned int set_compressor_state(char *msg, char *log_msg); | ||
unsigned int set_smart_grid_mode(char *msg, char *log_msg); | ||
unsigned int set_external_thermostat_1_state(char *msg, char *log_msg); | ||
unsigned int set_external_thermostat_2_state(char *msg, char *log_msg); | ||
unsigned int set_demand_control(char *msg, char *log_msg); | ||
unsigned int set_pool_temp(char *msg, char *log_msg); | ||
unsigned int set_buffer_temp(char *msg, char *log_msg); | ||
unsigned int set_z1_room_temp(char *msg, char *log_msg); | ||
unsigned int set_z1_water_temp(char *msg, char *log_msg); | ||
unsigned int set_z2_room_temp(char *msg, char *log_msg); | ||
unsigned int set_z2_water_temp(char *msg, char *log_msg); | ||
unsigned int set_solar_temp(char *msg, char *log_msg); | ||
unsigned int set_byte_9(char *msg, char *log_msg); | ||
|
||
|
||
|
||
|
||
struct { | ||
const char *name; | ||
unsigned int (*func)(char *msg, unsigned char *cmd, char *log_msg); | ||
} commands[] = { | ||
// set heatpump state to on by sending 1 | ||
{ "SetHeatpump", set_heatpump_state }, | ||
// set pump state to on by sending 1 | ||
{ "SetPump", set_pump }, | ||
// set pump speed | ||
{ "SetPumpSpeed", set_pump_speed }, | ||
// set 0 for Off mode, set 1 for Quiet mode 1, set 2 for Quiet mode 2, set 3 for Quiet mode 3 | ||
{ "SetQuietMode", set_quiet_mode }, | ||
// z1 heat request temp - set from -5 to 5 to get same temperature shift point or set direct temp | ||
{ "SetZ1HeatRequestTemperature", set_z1_heat_request_temperature }, | ||
// z1 cool request temp - set from -5 to 5 to get same temperature shift point or set direct temp | ||
{ "SetZ1CoolRequestTemperature", set_z1_cool_request_temperature }, | ||
// z2 heat request temp - set from -5 to 5 to get same temperature shift point or set direct temp | ||
{ "SetZ2HeatRequestTemperature", set_z2_heat_request_temperature }, | ||
// z2 cool request temp - set from -5 to 5 to get same temperature shift point or set direct temp | ||
{ "SetZ2CoolRequestTemperature", set_z2_cool_request_temperature }, | ||
// set mode to force DHW by sending 1 | ||
{ "SetForceDHW", set_force_DHW }, | ||
// set mode to force defrost by sending 1 | ||
{ "SetForceDefrost", set_force_defrost }, | ||
// set mode to force sterilization by sending 1 | ||
{ "SetForceSterilization", set_force_sterilization }, | ||
// set Holiday mode by sending 1, off will be 0 | ||
{ "SetHolidayMode", set_holiday_mode }, | ||
// set Powerful mode by sending 0 = off, 1 for 30min, 2 for 60min, 3 for 90 min | ||
{ "SetPowerfulMode", set_powerful_mode }, | ||
// set Heat pump operation mode 3 = DHW only, 0 = heat only, 1 = cool only, 2 = Auto, 4 = Heat+DHW, 5 = Cool+DHW, 6 = Auto + DHW | ||
{ "SetOperationMode", set_operation_mode }, | ||
// set DHW temperature by sending desired temperature between 40C-75C | ||
{ "SetDHWTemp", set_DHW_temp }, | ||
// set heat/cool curves on z1 and z2 using a json input | ||
{ "SetCurves", set_curves }, | ||
// set zones to active | ||
{ "SetZones", set_zones }, | ||
{ "SetFloorHeatDelta", set_floor_heat_delta }, | ||
{ "SetFloorCoolDelta", set_floor_cool_delta }, | ||
{ "SetDHWHeatDelta", set_dhw_heat_delta }, | ||
}; | ||
|
||
struct { | ||
const char *name; | ||
unsigned int (*func)(char *msg, char *log_msg); | ||
} optionalCommands[] = { | ||
// optional PCB | ||
{ "SetHeatCoolMode", set_heat_cool_mode }, | ||
{ "SetCompressorState", set_compressor_state }, | ||
{ "SetSmartGridMode", set_smart_grid_mode }, | ||
{ "SetExternalThermostat1State", set_external_thermostat_1_state }, | ||
{ "SetExternalThermostat2State", set_external_thermostat_2_state }, | ||
{ "SetDemandControl", set_demand_control }, | ||
{ "SetPoolTemp", set_pool_temp }, | ||
{ "SetBufferTemp", set_buffer_temp }, | ||
{ "SetZ1RoomTemp", set_z1_room_temp }, | ||
{ "SetZ1WaterTemp", set_z1_water_temp }, | ||
{ "SetZ2RoomTemp", set_z2_room_temp }, | ||
{ "SetZ2WaterTemp", set_z2_water_temp }, | ||
{ "SetSolarTemp", set_solar_temp }, | ||
{ "SetOptPCBByte9", set_byte_9 } | ||
}; | ||
|
||
void send_heatpump_command(char* topic, char *msg, bool (*send_command)(byte*, int), void (*log_message)(char*), bool optionalPCB); | ||
bool saveOptionalPCB(byte* command, int length); | ||
bool loadOptionalPCB(byte* command, int length); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include <OneWire.h> | ||
#include <DallasTemperature.h> | ||
#include <PubSubClient.h> | ||
#include "commands.h" | ||
#include "dallas.h" | ||
|
||
#define MQTT_RETAIN_VALUES 1 // do we retain 1wire values? | ||
|
||
#define MAXTEMPDIFFPERSEC 0.5 // what is the allowed temp difference per second which is allowed (to filter bad values) | ||
|
||
#define DALLASASYNC 0 //async dallas yes or no (default no, because async seems to break 1wire sometimes with current code) | ||
|
||
OneWire oneWire(ONE_WIRE_BUS); | ||
DallasTemperature DS18B20(&oneWire); | ||
|
||
//global array for 1wire data | ||
dallasDataStruct* actDallasData = 0; | ||
int dallasDevicecount = 0; | ||
|
||
|
||
unsigned long nextalldatatime_dallas = 0; | ||
|
||
unsigned long dallasTimer = 0; | ||
unsigned int updateAllDallasTime = 30000; // will be set using heishmonSettings | ||
unsigned int dallasTimerWait = 30000; // will be set using heishmonSettings | ||
|
||
void initDallasSensors(void (*log_message)(char*), unsigned int updateAllDallasTimeSettings, unsigned int dallasTimerWaitSettings) { | ||
char log_msg[256]; | ||
updateAllDallasTime = updateAllDallasTimeSettings; | ||
dallasTimerWait = dallasTimerWaitSettings; | ||
DS18B20.begin(); | ||
dallasDevicecount = DS18B20.getDeviceCount(); | ||
sprintf(log_msg, "Number of 1wire sensors on bus: %d", dallasDevicecount); log_message(log_msg); | ||
if ( dallasDevicecount > MAX_DALLAS_SENSORS) { | ||
dallasDevicecount = MAX_DALLAS_SENSORS; | ||
sprintf(log_msg, "Reached max 1wire sensor count. Only %d sensors will provide data.", dallasDevicecount); log_message(log_msg); | ||
} | ||
|
||
//init array | ||
actDallasData = new dallasDataStruct [dallasDevicecount]; | ||
for (int j = 0 ; j < dallasDevicecount; j++) { | ||
DS18B20.getAddress(actDallasData[j].sensor, j); | ||
} | ||
|
||
DS18B20.requestTemperatures(); | ||
for (int i = 0 ; i < dallasDevicecount; i++) { | ||
actDallasData[i].address[16] = '\0'; | ||
for (int x = 0; x < 8; x++) { | ||
// zero pad the address if necessary | ||
sprintf(&actDallasData[i].address[x * 2], "%02x", actDallasData[i].sensor[x]); | ||
} | ||
sprintf(log_msg, "Found 1wire sensor: %s", actDallasData[i].address ); log_message(log_msg); | ||
} | ||
if (DALLASASYNC) DS18B20.setWaitForConversion(false); //async 1wire during next loops | ||
} | ||
|
||
void readNewDallasTemp(PubSubClient &mqtt_client, void (*log_message)(char*), char* mqtt_topic_base) { | ||
char log_msg[256]; | ||
char mqtt_topic[256]; | ||
char valueStr[20]; | ||
bool updatenow = false; | ||
|
||
if (millis() > nextalldatatime_dallas) { | ||
updatenow = true; | ||
nextalldatatime_dallas = millis() + (1000 * updateAllDallasTime); | ||
} | ||
if (!(DALLASASYNC)) DS18B20.requestTemperatures(); | ||
for (int i = 0; i < dallasDevicecount; i++) { | ||
float temp = DS18B20.getTempC(actDallasData[i].sensor); | ||
if (temp < -120.0) { | ||
sprintf(log_msg, "Error 1wire sensor offline: %s", actDallasData[i].address); log_message(log_msg); | ||
} else { | ||
float allowedtempdiff = (((millis() - actDallasData[i].lastgoodtime)) / 1000.0) * MAXTEMPDIFFPERSEC; | ||
if ((actDallasData[i].temperature != -127.0) and ((temp > (actDallasData[i].temperature + allowedtempdiff)) or (temp < (actDallasData[i].temperature - allowedtempdiff)))) { | ||
sprintf(log_msg, "Filtering 1wire sensor temperature (%s). Delta to high. Current: %.2f Last: %.2f", actDallasData[i].address, temp, actDallasData[i].temperature); log_message(log_msg); | ||
} else { | ||
actDallasData[i].lastgoodtime = millis(); | ||
if ((updatenow) || (actDallasData[i].temperature != temp )) { //only update mqtt topic if temp changed or after each update timer | ||
actDallasData[i].temperature = temp; | ||
sprintf(log_msg, "Received 1wire sensor temperature (%s): %.2f", actDallasData[i].address, actDallasData[i].temperature); log_message(log_msg); | ||
sprintf(valueStr, "%.2f", actDallasData[i].temperature); | ||
sprintf(mqtt_topic, "%s/%s/%s", mqtt_topic_base, mqtt_topic_1wire, actDallasData[i].address); mqtt_client.publish(mqtt_topic, valueStr, MQTT_RETAIN_VALUES); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
void dallasLoop(PubSubClient &mqtt_client, void (*log_message)(char*), char* mqtt_topic_base) { | ||
if ((DALLASASYNC) && (millis() > (dallasTimer - 1000))) { | ||
DS18B20.requestTemperatures(); // get temperatures for next run 1 second before getting the temperatures (async) | ||
} | ||
if (millis() > dallasTimer) { | ||
log_message((char*)"Requesting new 1wire temperatures"); | ||
dallasTimer = millis() + (1000 * dallasTimerWait); | ||
readNewDallasTemp(mqtt_client, log_message, mqtt_topic_base); | ||
} | ||
} | ||
|
||
String dallasJsonOutput() { | ||
String output = "["; | ||
for (int i = 0; i < dallasDevicecount; i++) { | ||
output = output + "{"; | ||
output = output + "\"Sensor\": \"" + actDallasData[i].address + "\","; | ||
output = output + "\"Temperature\": \"" + actDallasData[i].temperature + "\""; | ||
output = output + "}"; | ||
if (i < dallasDevicecount - 1) output = output + ","; | ||
} | ||
output = output + "]"; | ||
return output; | ||
} | ||
|
||
String dallasTableOutput() { | ||
String output = ""; | ||
for (int i = 0; i < dallasDevicecount; i++) { | ||
output = output + "<tr>"; | ||
output = output + "<td>" + actDallasData[i].address + "</td>"; | ||
output = output + "<td>" + actDallasData[i].temperature + "</td>"; | ||
output = output + "</tr>"; | ||
} | ||
return output; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include <PubSubClient.h> | ||
#include <OneWire.h> | ||
#include <DallasTemperature.h> | ||
|
||
#define MAX_DALLAS_SENSORS 15 | ||
#define ONE_WIRE_BUS 4 // DS18B20 pin, for now a static config - should be in config menu later | ||
|
||
struct dallasDataStruct { | ||
float temperature = -127.0; | ||
unsigned long lastgoodtime = 0; | ||
DeviceAddress sensor; | ||
char address[17]; | ||
}; | ||
|
||
void dallasLoop(PubSubClient &mqtt_client, void (*log_message)(char*), char* mqtt_topic_base); | ||
void initDallasSensors(void (*log_message)(char*), unsigned int updataAllDallasTimeSettings, unsigned int dallasTimerWaitSettings); | ||
String dallasJsonOutput(void); | ||
String dallasTableOutput(void); |
Oops, something went wrong.