diff --git a/idf_component.yml b/idf_component.yml new file mode 100644 index 00000000..111f399a --- /dev/null +++ b/idf_component.yml @@ -0,0 +1,7 @@ +version: "1.2.0" +description: "Midea UART protocol library for ESP-IDF and Arduino" +url: "https://github.com/dudanov/MideaUART" +repository: "https://github.com/dudanov/MideaUART.git" +dependencies: + idf: + version: ">=5.0" diff --git a/include/Appliance/AirConditioner/AirConditioner.h b/include/Appliance/AirConditioner/AirConditioner.h index cc783c34..6501edb1 100644 --- a/include/Appliance/AirConditioner/AirConditioner.h +++ b/include/Appliance/AirConditioner/AirConditioner.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include "Appliance/ApplianceBase.h" #include "Appliance/AirConditioner/Capabilities.h" #include "Appliance/AirConditioner/StatusData.h" diff --git a/include/Appliance/AirConditioner/Capabilities.h b/include/Appliance/AirConditioner/Capabilities.h index e9be1b38..00c8d92b 100644 --- a/include/Appliance/AirConditioner/Capabilities.h +++ b/include/Appliance/AirConditioner/Capabilities.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include namespace dudanov { diff --git a/include/Appliance/AirConditioner/StatusData.h b/include/Appliance/AirConditioner/StatusData.h index 04a4c975..f67e11fb 100644 --- a/include/Appliance/AirConditioner/StatusData.h +++ b/include/Appliance/AirConditioner/StatusData.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include "Frame/FrameData.h" namespace dudanov { diff --git a/include/Appliance/ApplianceBase.h b/include/Appliance/ApplianceBase.h index cc19a938..e9a8ee45 100644 --- a/include/Appliance/ApplianceBase.h +++ b/include/Appliance/ApplianceBase.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include "Helpers/Platform.h" #include "Frame/Frame.h" #include "Frame/FrameData.h" #include "Helpers/Timer.h" diff --git a/include/Frame/Frame.h b/include/Frame/Frame.h index 5af10abe..f621a575 100644 --- a/include/Frame/Frame.h +++ b/include/Frame/Frame.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include #include "Frame/FrameData.h" #include "Helpers/Helpers.h" diff --git a/include/Frame/FrameData.h b/include/Frame/FrameData.h index cab3b5b9..23bd4427 100644 --- a/include/Frame/FrameData.h +++ b/include/Frame/FrameData.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include class IPAddress; diff --git a/include/Helpers/Helpers.h b/include/Helpers/Helpers.h index d114d929..d1efd24e 100644 --- a/include/Helpers/Helpers.h +++ b/include/Helpers/Helpers.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include namespace dudanov { diff --git a/include/Helpers/Log.h b/include/Helpers/Log.h index e4069a9a..7c1b87d8 100644 --- a/include/Helpers/Log.h +++ b/include/Helpers/Log.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" namespace dudanov { @@ -17,7 +17,9 @@ namespace dudanov { #endif void sv_log_printf_(int level, const char *tag, int line, const char *format, ...); +#ifdef ARDUINO void sv_log_printf_(int level, const char *tag, int line, const __FlashStringHelper *format, ...); +#endif #if LOG_LEVEL >= LOG_LEVEL_VERY_VERBOSE #define sv_log_vv(tag, format, ...) \ diff --git a/include/Helpers/Logger.h b/include/Helpers/Logger.h index 9d8da3d5..daeeb89f 100644 --- a/include/Helpers/Logger.h +++ b/include/Helpers/Logger.h @@ -1,5 +1,5 @@ #pragma once -#include +#include "Helpers/Platform.h" #include #include diff --git a/include/Helpers/Platform.h b/include/Helpers/Platform.h new file mode 100644 index 00000000..34e37117 --- /dev/null +++ b/include/Helpers/Platform.h @@ -0,0 +1,78 @@ +#pragma once + +#ifdef ARDUINO +#include +#include +#else +// ESP-IDF compatibility layer +#include +#include +#include +#include +#include + +#include "esp_timer.h" +#include "esp_random.h" + +// millis() replacement +inline unsigned long millis() { + return (unsigned long)(esp_timer_get_time() / 1000ULL); +} + +// random() replacement +inline long random(long max) { + return esp_random() % max; +} + +inline long random(long min, long max) { + return min + (esp_random() % (max - min)); +} + +// String replacement - use std::string +using String = std::string; + +// F() macro - no-op on ESP-IDF (no flash strings needed) +#define F(x) x + +// __FlashStringHelper - just const char* on ESP-IDF +using __FlashStringHelper = const char; + +// Stream interface for ESP-IDF +class Stream { + public: + virtual ~Stream() = default; + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual size_t write(uint8_t data) = 0; + virtual size_t write(const uint8_t *data, size_t size) = 0; + virtual void flush() = 0; +}; + +// IPAddress for ESP-IDF +class IPAddress { + public: + IPAddress() : addr_{0, 0, 0, 0} {} + IPAddress(uint8_t a, uint8_t b, uint8_t c, uint8_t d) : addr_{a, b, c, d} {} + uint8_t operator[](int index) const { return addr_[index]; } + private: + uint8_t addr_[4]; +}; + +#endif // ARDUINO + +// WiFi availability detection +#ifdef ARDUINO_ARCH_ESP8266 + // ESP8266 always has WiFi + #define HAS_WIFI 1 +// ESP32 family: check chip capabilities +#elif __has_include("soc/soc_caps.h") + #include "soc/soc_caps.h" + #ifdef SOC_WIFI_SUPPORTED + #define HAS_WIFI 1 + #else + #define HAS_WIFI 0 + #endif +#else + #define HAS_WIFI 0 +#endif diff --git a/library.json b/library.json index 4eb19431..9abd92de 100644 --- a/library.json +++ b/library.json @@ -19,6 +19,6 @@ "license": "MIT", "dependencies": { }, - "frameworks": "arduino", + "frameworks": ["arduino", "espidf"], "platforms": ["espressif8266", "espressif32"] } \ No newline at end of file diff --git a/src/Appliance/ApplianceBase.cpp b/src/Appliance/ApplianceBase.cpp index 66a27da3..30aa310d 100644 --- a/src/Appliance/ApplianceBase.cpp +++ b/src/Appliance/ApplianceBase.cpp @@ -1,9 +1,17 @@ #include "Appliance/ApplianceBase.h" #include "Helpers/Log.h" -#ifdef ARDUINO_ARCH_ESP32 -#include + +#ifdef ARDUINO + #ifdef ARDUINO_ARCH_ESP32 + #include + #else + #include + #endif #else -#include + #if HAS_WIFI + #include "esp_wifi.h" + #include "esp_netif.h" + #endif #endif namespace dudanov { @@ -108,6 +116,9 @@ void ApplianceBase::m_handler(const Frame &frame) { this->m_onRequest(frame); } +#if HAS_WIFI + +#ifdef ARDUINO static uint8_t getSignalStrength() { const int32_t dbm = WiFi.RSSI(); if (dbm > -63) @@ -119,11 +130,59 @@ static uint8_t getSignalStrength() { return 1; } +static bool isWifiConnected() { + return WiFi.isConnected(); +} + +static IPAddress getLocalIP() { + return WiFi.localIP(); +} +#else +// ESP-IDF implementations +static uint8_t getSignalStrength() { + wifi_ap_record_t ap_info; + if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) { + int32_t dbm = ap_info.rssi; + if (dbm > -63) return 4; + if (dbm > -75) return 3; + if (dbm > -88) return 2; + } + return 1; +} + +static bool isWifiConnected() { + wifi_ap_record_t ap_info; + return esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK; +} + +static IPAddress getLocalIP() { + esp_netif_ip_info_t ip_info; + esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) { + return IPAddress( + ip_info.ip.addr & 0xFF, + (ip_info.ip.addr >> 8) & 0xFF, + (ip_info.ip.addr >> 16) & 0xFF, + (ip_info.ip.addr >> 24) & 0xFF + ); + } + return IPAddress(); +} +#endif // ARDUINO + +#else // !HAS_WIFI + +static uint8_t getSignalStrength() { return 0; } +static bool isWifiConnected() { return false; } +static IPAddress getLocalIP() { return IPAddress(); } + +#endif // HAS_WIFI + void ApplianceBase::m_sendNetworkNotify(FrameType msgType) { NetworkNotifyData notify{}; - notify.setConnected(WiFi.isConnected()); + notify.setConnected(isWifiConnected()); notify.setSignalStrength(getSignalStrength()); - notify.setIP(WiFi.localIP()); + notify.setIP(getLocalIP()); notify.appendCRC(); if (msgType == NETWORK_NOTIFY) { LOG_D(TAG, "Enqueuing a DEVICE_NETWORK(0x0D) notification..."); diff --git a/src/Frame/FrameData.cpp b/src/Frame/FrameData.cpp index c4e776c6..d36348f1 100644 --- a/src/Frame/FrameData.cpp +++ b/src/Frame/FrameData.cpp @@ -1,5 +1,13 @@ #include "Frame/FrameData.h" -#include +#include "Helpers/Platform.h" + +#ifndef PROGMEM +#define PROGMEM +#endif + +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const uint8_t *)(addr)) +#endif namespace dudanov { namespace midea { diff --git a/src/Helpers/Log.cpp b/src/Helpers/Log.cpp index 719c2765..30eec6e6 100644 --- a/src/Helpers/Log.cpp +++ b/src/Helpers/Log.cpp @@ -16,6 +16,7 @@ void sv_log_printf_(int level, const char *tag, int line, const char *format, .. va_end(arg); } +#ifdef ARDUINO void sv_log_printf_(int level, const char *tag, int line, const __FlashStringHelper *format, ...) { if (logger_ == nullptr) return; @@ -24,5 +25,6 @@ void sv_log_printf_(int level, const char *tag, int line, const __FlashStringHel logger_(level, tag, line, format, arg); va_end(arg); } +#endif } // namespace dudanov diff --git a/src/Helpers/Timer.cpp b/src/Helpers/Timer.cpp index e07ac49f..d72c1412 100644 --- a/src/Helpers/Timer.cpp +++ b/src/Helpers/Timer.cpp @@ -1,4 +1,4 @@ -#include +#include "Helpers/Platform.h" #include "Helpers/Timer.h" namespace dudanov {