Add MitsibishiAC
This commit is contained in:
448
MitsubishiAC/src/main.cpp
Normal file
448
MitsubishiAC/src/main.cpp
Normal file
@@ -0,0 +1,448 @@
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <Ticker.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
//#include <ArduinoJson.h>
|
||||
#include <HeatPump.h>
|
||||
|
||||
#define HOST_NAME "MitsubishiAC"
|
||||
|
||||
#define OTA_USE
|
||||
//#define RDEB
|
||||
//#define SDEB
|
||||
|
||||
#ifdef RDEB
|
||||
#include <RemoteDebug.h>
|
||||
#endif
|
||||
|
||||
#ifdef OTA_USE
|
||||
#include <ArduinoOTA.h>
|
||||
#endif
|
||||
|
||||
#define MAIN_TOPIC "home/bigroom/ac/"
|
||||
#define SET_TOPIC "/set"
|
||||
#define DEBUG_TOPIC "debug"
|
||||
#define TIMERS_TOPIC "/timers"
|
||||
#define STATUS_TOPIC "/status"
|
||||
|
||||
const char* ssid = "wf-home";
|
||||
const char* password = "0ndthnrf";
|
||||
const char* mqtt_server = "192.168.1.111";
|
||||
unsigned long cRun = millis();
|
||||
bool _debugMode;
|
||||
|
||||
HeatPump hp;
|
||||
|
||||
AsyncMqttClient mqttClient;
|
||||
Ticker mqttReconnectTimer;
|
||||
|
||||
WiFiEventHandler wifiConnectHandler;
|
||||
WiFiEventHandler wifiDisconnectHandler;
|
||||
Ticker wifiReconnectTimer;
|
||||
|
||||
#ifdef RDEB
|
||||
RemoteDebug Debug;
|
||||
#endif
|
||||
|
||||
void connectToWifi();
|
||||
void connectToMqtt();
|
||||
void onWifiConnect(const WiFiEventStationModeGotIP& event);
|
||||
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event);
|
||||
void onMqttConnect(bool sessionPresent);
|
||||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
|
||||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total);
|
||||
void hpSettingsChanged();
|
||||
void hpStatusChanged(heatpumpStatus currentStatus);
|
||||
void hpPacketDebug(byte* packet, unsigned int length, char* packetDirection);
|
||||
|
||||
void setup(){
|
||||
#ifdef SDEB
|
||||
Serial.begin(9600);
|
||||
#endif
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.hostname(HOST_NAME);
|
||||
// ArduinoOTA.onStart([]() {
|
||||
// Serial1.println("Start Update"); // "Начало OTA-апдейта"
|
||||
// });
|
||||
// ArduinoOTA.onEnd([]() {
|
||||
// Serial1.println("\nEnd Update"); // "Завершение OTA-апдейта"
|
||||
// });
|
||||
// ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
// //Serial1.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
// });
|
||||
// ArduinoOTA.onError([](ota_error_t error) {
|
||||
// Serial1.printf("Error[%u]: ", error);
|
||||
// if (error == OTA_AUTH_ERROR) Serial1.println("Auth Failed");
|
||||
// // "Ошибка при аутентификации"
|
||||
// else if (error == OTA_BEGIN_ERROR) Serial1.println("Begin Failed");
|
||||
// // "Ошибка при начале OTA-апдейта"
|
||||
// else if (error == OTA_CONNECT_ERROR) Serial1.println("Connect Failed");
|
||||
// // "Ошибка при подключении"
|
||||
// else if (error == OTA_RECEIVE_ERROR) Serial1.println("Receive Failed");
|
||||
// // "Ошибка при получении данных"
|
||||
// else if (error == OTA_END_ERROR) Serial1.println("End Failed");
|
||||
// // "Ошибка при завершении OTA-апдейта"
|
||||
// });
|
||||
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
|
||||
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
|
||||
|
||||
mqttClient.onConnect(onMqttConnect);
|
||||
mqttClient.onDisconnect(onMqttDisconnect);
|
||||
mqttClient.onMessage(onMqttMessage);
|
||||
mqttClient.setServer(mqtt_server, 1883);
|
||||
mqttClient.setClientId(HOST_NAME);
|
||||
|
||||
#ifdef OTA_USE
|
||||
ArduinoOTA.begin();
|
||||
#endif
|
||||
#ifdef RDEB
|
||||
Debug.begin(HOST_NAME); // Initialize the WiFi server
|
||||
Debug.setResetCmdEnabled(true); // Enable the reset command
|
||||
|
||||
Debug.showProfiler(true); // Profiler (Good to measure times, to optimize codes)
|
||||
Debug.showColors(true); // Colors
|
||||
#endif
|
||||
hp.setSettingsChangedCallback(hpSettingsChanged);
|
||||
hp.setStatusChangedCallback(hpStatusChanged);
|
||||
hp.setPacketCallback(hpPacketDebug);
|
||||
#ifndef SDEB
|
||||
hp.connect(&Serial);
|
||||
hp.enableAutoUpdate();
|
||||
hp.enableExternalUpdate();
|
||||
#else
|
||||
Serial.println(F("Connect WIFI"));
|
||||
#endif
|
||||
connectToWifi();
|
||||
}
|
||||
|
||||
void loop(){
|
||||
#ifndef SDEB
|
||||
hp.sync();
|
||||
#endif
|
||||
#ifdef OTA_USE
|
||||
if(WiFi.isConnected())
|
||||
ArduinoOTA.handle();
|
||||
#endif
|
||||
if((cRun + 4999) < millis()){
|
||||
#ifdef SDEB
|
||||
Serial.println(millis());
|
||||
#else
|
||||
hpStatusChanged(hp.getStatus());
|
||||
#endif
|
||||
cRun = millis();
|
||||
#ifdef RDEB
|
||||
debugD("$ul Loop Topic %s", cRun, MAIN_TOPIC TIMERS_TOPIC);
|
||||
#endif
|
||||
}
|
||||
#ifdef RDEB
|
||||
Debug.handle();
|
||||
#endif
|
||||
//yield();
|
||||
}
|
||||
|
||||
void connectToWifi() {
|
||||
#ifdef SDEB
|
||||
Serial.println(F("Connecting to Wi-Fi..."));
|
||||
#endif
|
||||
WiFi.begin(ssid, password);
|
||||
}
|
||||
|
||||
void connectToMqtt() {
|
||||
#ifdef SDEB
|
||||
Serial.println(F("Connecting to MQTT..."));
|
||||
#endif
|
||||
mqttClient.connect();
|
||||
}
|
||||
|
||||
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
|
||||
#ifdef SDEB
|
||||
Serial.println(F("Connected to Wi-Fi."));
|
||||
Serial.print(F("IP: "));
|
||||
Serial.println(WiFi.localIP());
|
||||
#endif
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
connectToMqtt();
|
||||
}
|
||||
|
||||
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
|
||||
#ifdef SDEB
|
||||
Serial.println(F("Disconnected from Wi-Fi."));
|
||||
#endif
|
||||
mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
|
||||
wifiReconnectTimer.once(2, connectToWifi);
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
}
|
||||
|
||||
void onMqttConnect(bool sessionPresent) {
|
||||
#ifdef SDEB
|
||||
Serial.println(F("Connected to MQTT..."));
|
||||
#endif
|
||||
// mqttClient.publish(MAIN_TOPIC "power_set", 1, false, "");
|
||||
// mqttClient.publish(MAIN_TOPIC "mode_set", 1, false, "");
|
||||
// mqttClient.publish(MAIN_TOPIC "temp_set", 1, false, "");
|
||||
// mqttClient.publish(MAIN_TOPIC "fan_set", 1, false, "");
|
||||
// mqttClient.publish(MAIN_TOPIC "vane_set", 1, false, "");
|
||||
// mqttClient.publish(MAIN_TOPIC "widevane_set", 1, false, "");
|
||||
//mqttClient.publish(MAIN_TOPIC DEBUG_TOPIC, 1, false, "");
|
||||
mqttClient.subscribe(MAIN_TOPIC "power_set", 1);
|
||||
mqttClient.subscribe(MAIN_TOPIC "mode_set", 1);
|
||||
mqttClient.subscribe(MAIN_TOPIC "temp_set", 1);
|
||||
mqttClient.subscribe(MAIN_TOPIC "fan_set", 1);
|
||||
mqttClient.subscribe(MAIN_TOPIC "vane_set", 1);
|
||||
mqttClient.subscribe(MAIN_TOPIC "widevane_set", 1);
|
||||
#ifdef RDEB
|
||||
debugD("MQTT Connect");
|
||||
#endif
|
||||
}
|
||||
|
||||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
||||
if (WiFi.isConnected()) {
|
||||
mqttReconnectTimer.once(2, connectToMqtt);
|
||||
}
|
||||
#ifdef RDEB
|
||||
debugD("MQTT DisConnect");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void hpSettingsChanged() {
|
||||
// const size_t bufferSize = JSON_OBJECT_SIZE(6);
|
||||
// DynamicJsonDocument root(bufferSize);
|
||||
|
||||
heatpumpSettings currentSettings = hp.getSettings();
|
||||
|
||||
// root["power"] = currentSettings.power;
|
||||
// root["mode"] = currentSettings.mode;
|
||||
// root["temperature"] = currentSettings.temperature;
|
||||
// root["fan"] = currentSettings.fan;
|
||||
// root["vane"] = currentSettings.vane;
|
||||
// root["wideVane"] = currentSettings.wideVane;
|
||||
mqttClient.publish(MAIN_TOPIC "power", 1, false, currentSettings.power);
|
||||
mqttClient.publish(MAIN_TOPIC "mode", 1, false, currentSettings.mode);
|
||||
char t[5];
|
||||
dtostrf(currentSettings.temperature, 4, 1, t);
|
||||
mqttClient.publish(MAIN_TOPIC "temp", 1, false, t);
|
||||
mqttClient.publish(MAIN_TOPIC "fan", 1, false, currentSettings.fan);
|
||||
mqttClient.publish(MAIN_TOPIC "vane", 1, false, currentSettings.vane);
|
||||
mqttClient.publish(MAIN_TOPIC "wideVane", 1, false, currentSettings.wideVane);
|
||||
//root["iSee"] = currentSettings.iSee;
|
||||
|
||||
// char buffer[512];
|
||||
// serializeJson(root, buffer);
|
||||
#ifdef RDEB
|
||||
debugD("SettingsChanged %s", buffer);
|
||||
#endif
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SettChgd: "));
|
||||
// Serial.println(buffer);
|
||||
#endif
|
||||
//bool retain = true;
|
||||
//mqttClient.publish(MAIN_TOPIC, 1, false, buffer);
|
||||
// if (!mqtt_client.publish(heatpump_topic, buffer, retain)) {
|
||||
// mqtt_client.publish(heatpump_debug_topic, "failed to publish to heatpump topic");
|
||||
// }
|
||||
}
|
||||
|
||||
void hpStatusChanged(heatpumpStatus currentStatus) {
|
||||
// send room temp and operating info
|
||||
// const size_t bufferSizeInfo = JSON_OBJECT_SIZE(2);
|
||||
// DynamicJsonDocument rootInfo(bufferSizeInfo);
|
||||
|
||||
// rootInfo["roomTemperature"] = currentStatus.roomTemperature;
|
||||
// rootInfo["operating"] = currentStatus.operating;
|
||||
|
||||
// char bufferInfo[512];
|
||||
// serializeJson(rootInfo, bufferInfo);
|
||||
// #ifdef SDEB
|
||||
// Serial.print(F("StatChgd: "));
|
||||
// Serial.println(bufferInfo);
|
||||
// #endif
|
||||
// #ifdef RDEB
|
||||
// debugD("StatusSend %s", bufferInfo);
|
||||
// #endif
|
||||
char t[5];
|
||||
dtostrf(currentStatus.roomTemperature, 4, 1, t);
|
||||
mqttClient.publish(MAIN_TOPIC "temperature", 1, false, t);
|
||||
mqttClient.publish(MAIN_TOPIC "operating", 1, false, currentStatus.operating == false ? "OFF" : "ON");
|
||||
//mqttClient.publish(MAIN_TOPIC STATUS_TOPIC, 1, false, bufferInfo);
|
||||
// if (!mqtt_client.publish(heatpump_status_topic, bufferInfo, true)) {
|
||||
// mqtt_client.publish(heatpump_debug_topic, "failed to publish to room temp and operation status to heatpump/status topic");
|
||||
// }
|
||||
|
||||
// send the timer info
|
||||
// const size_t bufferSizeTimers = JSON_OBJECT_SIZE(5);
|
||||
// DynamicJsonDocument rootTimers(bufferSizeTimers);
|
||||
|
||||
// rootTimers["mode"] = currentStatus.timers.mode;
|
||||
// rootTimers["onMins"] = currentStatus.timers.onMinutesSet;
|
||||
// rootTimers["onRemainMins"] = currentStatus.timers.onMinutesRemaining;
|
||||
// rootTimers["offMins"] = currentStatus.timers.offMinutesSet;
|
||||
// rootTimers["offRemainMins"] = currentStatus.timers.offMinutesRemaining;
|
||||
|
||||
// char bufferTimers[512];
|
||||
// serializeJson(rootTimers, bufferTimers);
|
||||
|
||||
#ifdef RDEB
|
||||
debugD("TimersSend %s", bufferTimers);
|
||||
#endif
|
||||
mqttClient.publish(MAIN_TOPIC "timerMode", 1, false, currentStatus.timers.mode);
|
||||
itoa(currentStatus.timers.onMinutesSet, t, 10);
|
||||
mqttClient.publish(MAIN_TOPIC "timerOnMinSet", 1, false, t);
|
||||
itoa(currentStatus.timers.onMinutesRemaining, t, 10);
|
||||
mqttClient.publish(MAIN_TOPIC "timerOnMinRem", 1, false, t);
|
||||
itoa(currentStatus.timers.offMinutesSet, t, 10);
|
||||
mqttClient.publish(MAIN_TOPIC "timerOffMinSet", 1, false, t);
|
||||
itoa(currentStatus.timers.offMinutesRemaining, t, 10);
|
||||
mqttClient.publish(MAIN_TOPIC "timerOffMinRem", 1, false, t);
|
||||
//mqttClient.publish(MAIN_TOPIC TIMERS_TOPIC, 1, false, bufferTimers);
|
||||
// if (!mqtt_client.publish(heatpump_timers_topic, bufferTimers, true)) {
|
||||
// mqtt_client.publish(heatpump_debug_topic, "failed to publish timer info to heatpump/status topic");
|
||||
// }
|
||||
}
|
||||
|
||||
void hpPacketDebug(byte* packet, unsigned int length, char* packetDirection) {
|
||||
if (_debugMode) {
|
||||
String message = packetDirection;
|
||||
message += " ";
|
||||
for (unsigned int idx = 0; idx < length; idx++) {
|
||||
if (packet[idx] < 16) {
|
||||
message += "0"; // pad single hex digits with a 0
|
||||
}
|
||||
message += String(packet[idx], HEX) + " ";
|
||||
}
|
||||
|
||||
// const size_t bufferSize = JSON_OBJECT_SIZE(6);
|
||||
// DynamicJsonDocument root(bufferSize);
|
||||
|
||||
// root[packetDirection] = message;
|
||||
|
||||
// char buffer[512];
|
||||
// serializeJson(root, buffer);
|
||||
|
||||
// #ifdef RDEB
|
||||
// debugD("DebugSend %s", buffer);
|
||||
// #endif
|
||||
mqttClient.publish(MAIN_TOPIC DEBUG_TOPIC, 1, false, message.c_str());
|
||||
// if (!mqtt_client.publish(heatpump_debug_topic, buffer)) {
|
||||
// mqtt_client.publish(heatpump_debug_topic, "failed to publish to heatpump/debug topic");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
|
||||
char message[len + 1];
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
message[i] = (char)payload[i];
|
||||
}
|
||||
message[len] = '\0';
|
||||
String mqtt = "Topic:";
|
||||
mqtt += topic;
|
||||
mqtt += " Payload:";
|
||||
mqtt += String(message);
|
||||
mqttClient.publish(MAIN_TOPIC "debug_mqtt", 1, false, mqtt.c_str());
|
||||
#ifdef SDEB
|
||||
Serial.print(F("MQTT msg: "));
|
||||
Serial.println(message);
|
||||
#endif
|
||||
#ifdef RDEB
|
||||
debugD("MQTT Message %s", message);
|
||||
#endif
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "power_set") == 0) {
|
||||
mqttClient.publish(MAIN_TOPIC "debug", 1, false, (String("Power set:") + String(message)).c_str());
|
||||
#ifdef SDEB
|
||||
Serial.print(F("Setpower: "));
|
||||
Serial.println(message);
|
||||
#else
|
||||
hp.setPowerSetting(atoi(message) == 1 ? "ON" : "OFF");
|
||||
#endif
|
||||
#ifdef RDEB
|
||||
debugD("SET Power %s", power);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "mode_set") == 0) {
|
||||
mqttClient.publish(MAIN_TOPIC "debug", 1, false, (String("Mode set:") + String(message)).c_str());
|
||||
#ifdef RDEB
|
||||
debugD("SET Mode %s", mode);
|
||||
#endif
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SetMode: "));
|
||||
Serial.println(message);
|
||||
#else
|
||||
hp.setModeSetting(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "temp_set") == 0) {
|
||||
float temperature = atof(message);
|
||||
mqttClient.publish(MAIN_TOPIC "debug", 1, false, (String("Temp set:") + String(message)).c_str());
|
||||
#ifdef RDEB
|
||||
debugD("SET Temp %f", temperature);
|
||||
#endif
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SetTemp: "));
|
||||
Serial.println(temperature);
|
||||
#else
|
||||
hp.setTemperature(temperature);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "fan_set") == 0) {
|
||||
mqttClient.publish(MAIN_TOPIC "debug", 1, false, (String("Fan set:") + String(message)).c_str());
|
||||
#ifdef RDEB
|
||||
debugD("SET Fan %s", fan);
|
||||
#endif
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SetFan: "));
|
||||
Serial.println(message);
|
||||
#else
|
||||
hp.setFanSpeed(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "vane_set") == 0) {
|
||||
mqttClient.publish(MAIN_TOPIC "debug", 1, false, (String("Vane set:") + String(message)).c_str());
|
||||
#ifdef RDEB
|
||||
debugD("SET Vane %s", vane);
|
||||
#endif
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SetVane: "));
|
||||
Serial.println(message);
|
||||
#else
|
||||
hp.setVaneSetting(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "wideVane_set") == 0) {
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SetwideVane: "));
|
||||
Serial.println(message);
|
||||
#else
|
||||
hp.setWideVaneSetting(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(topic, MAIN_TOPIC "remoteTemperature_set") == 0) {
|
||||
float temperature = atof(message);
|
||||
#ifdef RDEB
|
||||
debugD("SET RemTemp %f", temperature);
|
||||
#endif
|
||||
#ifdef SDEB
|
||||
Serial.print(F("SetTemp: "));
|
||||
Serial.println(temperature);
|
||||
#else
|
||||
hp.setRemoteTemperature(temperature);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SDEB
|
||||
// bool result = hp.update();
|
||||
|
||||
// if (!result) {
|
||||
// mqttClient.publish(MAIN_TOPIC DEBUG_TOPIC, 1, false, "heatpump: update() failed");
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user