Merge branch 'gpio-redesign' into revert-154-master

This commit is contained in:
fvanroie 2021-04-25 22:00:52 +02:00
commit 8cd8ed61c7
37 changed files with 295 additions and 167 deletions

View File

@ -1,4 +1,4 @@
name: Build master branch name: Build branch
on: [push, workflow_dispatch] on: [push, workflow_dispatch]

View File

@ -45,14 +45,14 @@
* @param light_color light color of the QR code * @param light_color light color of the QR code
* @return pointer to the created QR code object * @return pointer to the created QR code object
*/ */
lv_obj_t * lv_qrcode_create(lv_obj_t * parent, lv_coord_t size, lv_color_t dark_color, lv_color_t light_color) lv_obj_t* lv_qrcode_create(lv_obj_t* parent, lv_coord_t size, lv_color_t dark_color, lv_color_t light_color)
{ {
uint32_t buf_size = LV_CANVAS_BUF_SIZE_INDEXED_1BIT(size, size); uint32_t buf_size = LV_CANVAS_BUF_SIZE_INDEXED_1BIT(size, size);
uint8_t * buf = lv_mem_alloc(buf_size); uint8_t* buf = lv_mem_alloc(buf_size);
LV_ASSERT_MEM(buf); LV_ASSERT_MEM(buf);
if(buf == NULL) return NULL; if(buf == NULL) return NULL;
lv_obj_t * canvas = lv_canvas_create(parent, NULL); lv_obj_t* canvas = lv_canvas_create(parent, NULL);
lv_canvas_set_buffer(canvas, buf, size, size, LV_IMG_CF_INDEXED_1BIT); lv_canvas_set_buffer(canvas, buf, size, size, LV_IMG_CF_INDEXED_1BIT);
lv_canvas_set_palette(canvas, 0, dark_color); lv_canvas_set_palette(canvas, 0, dark_color);
@ -90,7 +90,7 @@ lv_obj_t * lv_qrcode_create(lv_obj_t * parent, lv_coord_t size, lv_color_t dark_
* @param data_len length of data in bytes * @param data_len length of data in bytes
* @return LV_RES_OK: if no error; LV_RES_INV: on error * @return LV_RES_OK: if no error; LV_RES_INV: on error
*/ */
lv_res_t lv_qrcode_update(lv_obj_t * qrcode, const void * data, uint32_t data_len) lv_res_t lv_qrcode_update(lv_obj_t* qrcode, const void* data, uint32_t data_len)
{ {
lv_color_t c; lv_color_t c;
c.full = 1; c.full = 1;
@ -124,7 +124,7 @@ lv_res_t lv_qrcode_update(lv_obj_t * qrcode, const void * data, uint32_t data_le
return LV_RES_OK; return LV_RES_OK;
} }
lv_res_t lv_qrcode_update2(lv_obj_t * qrcode, const void * data, uint32_t data_len) lv_res_t lv_qrcode_update2(lv_obj_t* qrcode, const void* data, uint32_t data_len)
{ {
lv_color_t c; lv_color_t c;
// c.full = 1; // c.full = 1;
@ -143,31 +143,27 @@ lv_res_t lv_qrcode_update2(lv_obj_t * qrcode, const void * data, uint32_t data_l
if(!ok) return LV_RES_INV; if(!ok) return LV_RES_INV;
// lv_coord_t obj_w = lv_obj_get_width(qrcode); // lv_coord_t obj_w = lv_obj_get_width(qrcode);
int qr_size = qrcodegen_getSize(qr_pixels); // int scale = 1;
int scale = 1; // int scaled = 0;
int scaled = 0; // int qr_size = qrcodegen_getSize(qr_pixels);
int margin = 0; int margin = 0;
LV_LOG_ERROR("5 OK");
lv_img_ext_t * ext = (lv_img_ext_t *)lv_obj_get_ext_attr(qrcode); lv_img_ext_t* ext = (lv_img_ext_t*)lv_obj_get_ext_attr(qrcode);
if(!ext || !ext->src) return LV_RES_INV; if(!ext || !ext->src) return LV_RES_INV;
LV_LOG_ERROR("6 OK");
lv_img_header_t header; lv_img_header_t header;
lv_img_decoder_get_info(ext->src, &header); lv_img_decoder_get_info(ext->src, &header);
LV_LOG_ERROR("7 OK");
lv_img_decoder_dsc_t dec_dsc; lv_img_decoder_dsc_t dec_dsc;
lv_res_t res = lv_img_decoder_open(&dec_dsc, ext->src, LV_COLOR_CYAN); lv_res_t res = lv_img_decoder_open(&dec_dsc, ext->src, LV_COLOR_CYAN);
LV_LOG_ERROR("8 OK"); (void)res; // unused
for(int y = 0; y < dec_dsc.header.h; y++) { for(int y = 0; y < dec_dsc.header.h; y++) {
for(int x = 0; x < dec_dsc.header.w; x++) { for(int x = 0; x < dec_dsc.header.w; x++) {
c = qrcodegen_getModule(qr_pixels, x, y) ? LV_COLOR_WHITE : LV_COLOR_BLACK; c = qrcodegen_getModule(qr_pixels, x, y) ? LV_COLOR_WHITE : LV_COLOR_BLACK;
lv_img_buf_set_px_color(dec_dsc.src, x + margin, y + margin, c); lv_img_buf_set_px_color((lv_img_dsc_t*)dec_dsc.src, x + margin, y + margin, c);
} }
} }
LV_LOG_ERROR("9 OK");
return LV_RES_OK; return LV_RES_OK;
} }
@ -176,9 +172,9 @@ lv_res_t lv_qrcode_update2(lv_obj_t * qrcode, const void * data, uint32_t data_l
* Delete a QR code object * Delete a QR code object
* @param qrcode pointer to a QR code obejct * @param qrcode pointer to a QR code obejct
*/ */
void lv_qrcode_delete(lv_obj_t * qrcode) void lv_qrcode_delete(lv_obj_t* qrcode)
{ {
lv_img_dsc_t * img = lv_canvas_get_img(qrcode); lv_img_dsc_t* img = lv_canvas_get_img(qrcode);
lv_mem_free(img->data); lv_mem_free(img->data);
lv_mem_free(img); lv_mem_free(img);
lv_obj_del(qrcode); lv_obj_del(qrcode);

View File

@ -55,7 +55,7 @@
// - They are completely thread-safe if the caller does not give the // - They are completely thread-safe if the caller does not give the
// same writable buffer to concurrent calls to these functions. // same writable buffer to concurrent calls to these functions.
testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int * bitLen); testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int* bitLen);
testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]); testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]);
testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl); testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
@ -135,7 +135,7 @@ static const int PENALTY_N4 = 10;
/*---- High-level QR Code encoding functions ----*/ /*---- High-level QR Code encoding functions ----*/
// Public function - see documentation comment in header file. // Public function - see documentation comment in header file.
bool qrcodegen_encodeText(const char * text, uint8_t tempBuffer[], uint8_t qrcode[], enum qrcodegen_Ecc ecl, bool qrcodegen_encodeText(const char* text, uint8_t tempBuffer[], uint8_t qrcode[], enum qrcodegen_Ecc ecl,
int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl) int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl)
{ {
@ -187,7 +187,7 @@ bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcod
// Appends the given number of low-order bits of the given value to the given byte-based // Appends the given number of low-order bits of the given value to the given byte-based
// bit buffer, increasing the bit length. Requires 0 <= numBits <= 16 and val < 2^numBits. // bit buffer, increasing the bit length. Requires 0 <= numBits <= 16 and val < 2^numBits.
testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int * bitLen) testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int* bitLen)
{ {
assert(0 <= numBits && numBits <= 16 && (unsigned long)val >> numBits == 0); assert(0 <= numBits && numBits <= 16 && (unsigned long)val >> numBits == 0);
for(int i = numBits - 1; i >= 0; i--, (*bitLen)++) buffer[*bitLen >> 3] |= ((val >> i) & 1) << (7 - (*bitLen & 7)); for(int i = numBits - 1; i >= 0; i--, (*bitLen)++) buffer[*bitLen >> 3] |= ((val >> i) & 1) << (7 - (*bitLen & 7));
@ -235,7 +235,7 @@ bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], siz
memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0])); memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0]));
int bitLen = 0; int bitLen = 0;
for(size_t i = 0; i < len; i++) { for(size_t i = 0; i < len; i++) {
const struct qrcodegen_Segment * seg = &segs[i]; const struct qrcodegen_Segment* seg = &segs[i];
appendBitsToBuffer((int)seg->mode, 4, qrcode, &bitLen); appendBitsToBuffer((int)seg->mode, 4, qrcode, &bitLen);
appendBitsToBuffer(seg->numChars, numCharCountBits(seg->mode, version), qrcode, &bitLen); appendBitsToBuffer(seg->numChars, numCharCountBits(seg->mode, version), qrcode, &bitLen);
for(int j = 0; j < seg->bitLength; j++) for(int j = 0; j < seg->bitLength; j++)
@ -305,10 +305,10 @@ testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ec
// (not concatenate) the bytes into a single sequence // (not concatenate) the bytes into a single sequence
uint8_t generator[qrcodegen_REED_SOLOMON_DEGREE_MAX]; uint8_t generator[qrcodegen_REED_SOLOMON_DEGREE_MAX];
calcReedSolomonGenerator(blockEccLen, generator); calcReedSolomonGenerator(blockEccLen, generator);
const uint8_t * dat = data; const uint8_t* dat = data;
for(int i = 0; i < numBlocks; i++) { for(int i = 0; i < numBlocks; i++) {
int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1); int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1);
uint8_t * ecc = &data[dataLen]; // Temporary storage uint8_t* ecc = &data[dataLen]; // Temporary storage
calcReedSolomonRemainder(dat, datLen, generator, blockEccLen, ecc); calcReedSolomonRemainder(dat, datLen, generator, blockEccLen, ecc);
for(int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data for(int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data
if(j == shortBlockDataLen) k -= numShortBlocks; if(j == shortBlockDataLen) k -= numShortBlocks;
@ -782,7 +782,7 @@ static bool getBit(int x, int i)
/*---- Segment handling ----*/ /*---- Segment handling ----*/
// Public function - see documentation comment in header file. // Public function - see documentation comment in header file.
bool qrcodegen_isAlphanumeric(const char * text) bool qrcodegen_isAlphanumeric(const char* text)
{ {
char buffer[64]; char buffer[64];
snprintf_P(buffer, sizeof(buffer), ALPHANUMERIC_CHARSET); snprintf_P(buffer, sizeof(buffer), ALPHANUMERIC_CHARSET);
@ -795,7 +795,7 @@ bool qrcodegen_isAlphanumeric(const char * text)
} }
// Public function - see documentation comment in header file. // Public function - see documentation comment in header file.
bool qrcodegen_isNumeric(const char * text) bool qrcodegen_isNumeric(const char* text)
{ {
assert(text != NULL); assert(text != NULL);
for(; *text != '\0'; text++) { for(; *text != '\0'; text++) {
@ -860,7 +860,7 @@ struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, u
} }
// Public function - see documentation comment in header file. // Public function - see documentation comment in header file.
struct qrcodegen_Segment qrcodegen_makeNumeric(const char * digits, uint8_t buf[]) struct qrcodegen_Segment qrcodegen_makeNumeric(const char* digits, uint8_t buf[])
{ {
assert(digits != NULL); assert(digits != NULL);
struct qrcodegen_Segment result; struct qrcodegen_Segment result;
@ -893,7 +893,7 @@ struct qrcodegen_Segment qrcodegen_makeNumeric(const char * digits, uint8_t buf[
} }
// Public function - see documentation comment in header file. // Public function - see documentation comment in header file.
struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char * text, uint8_t buf[]) struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char* text, uint8_t buf[])
{ {
char buffer[64]; char buffer[64];
snprintf_P(buffer, sizeof(buffer), ALPHANUMERIC_CHARSET); snprintf_P(buffer, sizeof(buffer), ALPHANUMERIC_CHARSET);
@ -911,7 +911,7 @@ struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char * text, uint8_t b
unsigned int accumData = 0; unsigned int accumData = 0;
int accumCount = 0; int accumCount = 0;
for(; *text != '\0'; text++) { for(; *text != '\0'; text++) {
const char * temp = strchr(buffer, *text); // ALPHANUMERIC_CHARSET const char* temp = strchr(buffer, *text); // ALPHANUMERIC_CHARSET
assert(temp != NULL); assert(temp != NULL);
accumData = accumData * 45 + (unsigned int)(temp - buffer); // ALPHANUMERIC_CHARSET accumData = accumData * 45 + (unsigned int)(temp - buffer); // ALPHANUMERIC_CHARSET
accumCount++; accumCount++;
@ -963,8 +963,8 @@ testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int
assert(segs != NULL || len == 0); assert(segs != NULL || len == 0);
long result = 0; long result = 0;
for(size_t i = 0; i < len; i++) { for(size_t i = 0; i < len; i++) {
int numChars = segs[i].numChars; int16_t numChars = segs[i].numChars;
int bitLength = segs[i].bitLength; int16_t bitLength = segs[i].bitLength;
assert(0 <= numChars && numChars <= INT16_MAX); assert(0 <= numChars && numChars <= INT16_MAX);
assert(0 <= bitLength && bitLength <= INT16_MAX); assert(0 <= bitLength && bitLength <= INT16_MAX);
int ccbits = numCharCountBits(segs[i].mode, version); int ccbits = numCharCountBits(segs[i].mode, version);

View File

@ -59,9 +59,9 @@ build_flags =
; -- Hasp build options ---------------------------- ; -- Hasp build options ----------------------------
-D HASP_VER_MAJ=0 -D HASP_VER_MAJ=0
-D HASP_VER_MIN=5 -D HASP_VER_MIN=6
-D HASP_VER_REV=0 -D HASP_VER_REV=0
-D HASP_LOG_LEVEL=LOG_LEVEL_OUTPUT -D HASP_LOG_LEVEL=LOG_LEVEL_TRACE
${override.build_flags} ${override.build_flags}
; -- Shared library dependencies in all environments ; -- Shared library dependencies in all environments
@ -125,7 +125,7 @@ build_flags =
-D HASP_USE_CONFIG=1 ; Native application, not library -D HASP_USE_CONFIG=1 ; Native application, not library
-D LV_LOG_TRACE_TIMER=1 -D LV_LOG_TRACE_TIMER=1
; -- LittleFS build options ------------------------ ; -- LittleFS build options ------------------------
-D CONFIG_LITTLEFS_FOR_IDF_3_2 ;-D CONFIG_LITTLEFS_FOR_IDF_3_2 ; obsolete in IDF 3.3
lib_ignore = lib_ignore =
GxTFT GxTFT

View File

@ -41,7 +41,11 @@ class BaseDevice {
{ {
return ""; return "";
} }
virtual const char* get_model();
virtual const char* get_hardware_id()
{
return "";
}
virtual void init() virtual void init()
{} {}
virtual void show_info() virtual void show_info()

View File

@ -5,6 +5,7 @@
#include "Arduino.h" #include "Arduino.h"
#include <Esp.h> #include <Esp.h>
#include <WiFi.h>
#include "esp_system.h" #include "esp_system.h"
#include "hasp_conf.h" #include "hasp_conf.h"
@ -21,6 +22,24 @@
namespace dev { namespace dev {
Esp32Device::Esp32Device()
{
_hostname = MQTT_NODENAME;
_backlight_invert = (TFT_BACKLIGHT_ON == LOW);
_backlight_power = 1;
_backlight_level = 255;
_backlight_pin = TFT_BCKL;
/* fill unique identifier with wifi mac */
byte mac[6];
WiFi.macAddress(mac);
_hardware_id.reserve(13);
for(int i = 0; i < 6; ++i) {
if(mac[i] < 0x10) _hardware_id += "0";
_hardware_id += String(mac[i], HEX).c_str();
}
}
void Esp32Device::reboot() void Esp32Device::reboot()
{ {
ESP.restart(); ESP.restart();
@ -73,6 +92,11 @@ const char* Esp32Device::get_chip_model()
// model += chip_info.revision; // model += chip_info.revision;
} }
const char* Esp32Device::get_hardware_id()
{
return _hardware_id.c_str();
}
void Esp32Device::set_backlight_pin(uint8_t pin) void Esp32Device::set_backlight_pin(uint8_t pin)
{ {
_backlight_pin = pin; _backlight_pin = pin;

View File

@ -14,14 +14,8 @@ namespace dev {
class Esp32Device : public BaseDevice { class Esp32Device : public BaseDevice {
public: public:
Esp32Device() Esp32Device();
{
_hostname = MQTT_NODENAME;
_backlight_invert = (TFT_BACKLIGHT_ON == LOW);
_backlight_power = 1;
_backlight_level = 255;
_backlight_pin = TFT_BCKL;
}
void reboot() override; void reboot() override;
void show_info() override; void show_info() override;
@ -29,6 +23,7 @@ class Esp32Device : public BaseDevice {
void set_hostname(const char*); void set_hostname(const char*);
const char* get_core_version(); const char* get_core_version();
const char* get_chip_model(); const char* get_chip_model();
const char* get_hardware_id();
void set_backlight_pin(uint8_t pin) override; void set_backlight_pin(uint8_t pin) override;
void set_backlight_level(uint8_t val) override; void set_backlight_level(uint8_t val) override;
@ -45,6 +40,7 @@ class Esp32Device : public BaseDevice {
private: private:
std::string _hostname; std::string _hostname;
std::string _hardware_id;
uint8_t _backlight_pin; uint8_t _backlight_pin;
uint8_t _backlight_level; uint8_t _backlight_level;

View File

@ -5,6 +5,7 @@
#include "Arduino.h" #include "Arduino.h"
#include <Esp.h> #include <Esp.h>
#include <ESP8266WiFi.h>
#include "esp8266.h" #include "esp8266.h"
@ -15,6 +16,25 @@
namespace dev { namespace dev {
Esp8266Device::Esp8266Device()
{
_hostname = MQTT_NODENAME;
_backlight_invert = (TFT_BACKLIGHT_ON == LOW);
_backlight_power = 1;
_backlight_level = 255;
_core_version = ESP.getCoreVersion().c_str();
_backlight_pin = TFT_BCKL;
/* fill unique identifier with wifi mac */
byte mac[6];
WiFi.macAddress(mac);
_hardware_id.reserve(13);
for(int i = 0; i < 6; ++i) {
if(mac[i] < 0x10) _hardware_id += "0";
_hardware_id += String(mac[i], HEX).c_str();
}
}
void Esp8266Device::reboot() void Esp8266Device::reboot()
{ {
ESP.restart(); ESP.restart();
@ -46,6 +66,11 @@ const char* Esp8266Device::get_chip_model()
return "ESP8266"; return "ESP8266";
} }
const char* Esp8266Device::get_hardware_id()
{
return _hardware_id.c_str();
}
void Esp8266Device::set_backlight_pin(uint8_t pin) void Esp8266Device::set_backlight_pin(uint8_t pin)
{ {
_backlight_pin = pin; _backlight_pin = pin;

View File

@ -14,15 +14,7 @@ namespace dev {
class Esp8266Device : public BaseDevice { class Esp8266Device : public BaseDevice {
public: public:
Esp8266Device() Esp8266Device();
{
_hostname = MQTT_NODENAME;
_backlight_invert = (TFT_BACKLIGHT_ON == LOW);
_backlight_power = 1;
_backlight_level = 255;
_core_version = ESP.getCoreVersion().c_str();
_backlight_pin = TFT_BCKL;
}
void reboot() override; void reboot() override;
void show_info() override; void show_info() override;
@ -31,6 +23,7 @@ class Esp8266Device : public BaseDevice {
void set_hostname(const char*); void set_hostname(const char*);
const char* get_core_version(); const char* get_core_version();
const char* get_chip_model(); const char* get_chip_model();
const char* get_hardware_id();
void set_backlight_pin(uint8_t pin) override; void set_backlight_pin(uint8_t pin) override;
void set_backlight_level(uint8_t val) override; void set_backlight_level(uint8_t val) override;
@ -47,6 +40,7 @@ class Esp8266Device : public BaseDevice {
private: private:
std::string _hostname; std::string _hostname;
std::string _hardware_id;
std::string _core_version; std::string _core_version;
uint8_t _backlight_pin; uint8_t _backlight_pin;

View File

@ -30,7 +30,7 @@ PosixDevice::PosixDevice()
// LOG_VERBOSE(0,"Version: %s", uts.version); // LOG_VERBOSE(0,"Version: %s", uts.version);
// LOG_VERBOSE(0,"Machine: %s", uts.machine); // LOG_VERBOSE(0,"Machine: %s", uts.machine);
char version[128]; char version[256];
snprintf(version, sizeof(version), "%s %s", uts.sysname, uts.release); snprintf(version, sizeof(version), "%s %s", uts.sysname, uts.release);
_core_version = version; _core_version = version;
_chip_model = uts.machine; _chip_model = uts.machine;
@ -66,21 +66,29 @@ const char* PosixDevice::get_hostname()
{ {
return _hostname.c_str(); return _hostname.c_str();
} }
void PosixDevice::set_hostname(const char* hostname) void PosixDevice::set_hostname(const char* hostname)
{ {
_hostname = hostname; _hostname = hostname;
monitor_title(hostname); monitor_title(hostname);
// SDL_SetWindowTitle(monitor.window, hostname); // SDL_SetWindowTitle(monitor.window, hostname);
} }
const char* PosixDevice::get_core_version() const char* PosixDevice::get_core_version()
{ {
return _core_version.c_str(); return _core_version.c_str();
} }
const char* PosixDevice::get_chip_model() const char* PosixDevice::get_chip_model()
{ {
return _chip_model.c_str(); return _chip_model.c_str();
} }
const char* PosixDevice::get_hardware_id()
{
return "223344556677";
}
void PosixDevice::set_backlight_pin(uint8_t pin) void PosixDevice::set_backlight_pin(uint8_t pin)
{ {
// PosixDevice::backlight_pin = pin; // PosixDevice::backlight_pin = pin;

View File

@ -38,6 +38,7 @@ class PosixDevice : public BaseDevice {
void set_hostname(const char*); void set_hostname(const char*);
const char* get_core_version(); const char* get_core_version();
const char* get_chip_model(); const char* get_chip_model();
const char* get_hardware_id();
void set_backlight_pin(uint8_t pin); void set_backlight_pin(uint8_t pin);
void set_backlight_level(uint8_t val); void set_backlight_level(uint8_t val);

View File

@ -30,6 +30,7 @@ const char* Stm32f4Device::get_hostname()
{ {
return _hostname.c_str(); return _hostname.c_str();
} }
void Stm32f4Device::set_hostname(const char* hostname) void Stm32f4Device::set_hostname(const char* hostname)
{ {
_hostname = hostname; _hostname = hostname;
@ -40,6 +41,14 @@ const char* Stm32f4Device::get_core_version()
// return ESP.getCoreVersion().c_str(); // return ESP.getCoreVersion().c_str();
} }
const char* Stm32f4Device::get_hardware_id()
{
// https://stm32duinoforum.com/forum/viewtopic_f_29_t_2909_start_10.html
// Serial.println("UID [HEX] : "+String(*(uint32_t*)(UID_BASE), HEX)+" "+String(*(uint32_t*)(UID_BASE+0x04),
// HEX)+" "+String(*(uint32_t*)(UID_BASE+0x08), HEX));
return _hardware_id.c_str();
}
void Stm32f4Device::set_backlight_pin(uint8_t pin) void Stm32f4Device::set_backlight_pin(uint8_t pin)
{ {
_backlight_pin = pin; _backlight_pin = pin;

View File

@ -30,6 +30,7 @@ class Stm32f4Device : public BaseDevice {
void set_hostname(const char*); void set_hostname(const char*);
const char* get_core_version(); const char* get_core_version();
const char* get_chip_model(); const char* get_chip_model();
const char* get_chip_hardware_id();
void set_backlight_pin(uint8_t pin) override; void set_backlight_pin(uint8_t pin) override;
void set_backlight_level(uint8_t val) override; void set_backlight_level(uint8_t val) override;
@ -46,6 +47,7 @@ class Stm32f4Device : public BaseDevice {
private: private:
std::string _hostname; std::string _hostname;
std::string _hardware_id;
uint8_t _backlight_pin; uint8_t _backlight_pin;
uint8_t _backlight_level; uint8_t _backlight_level;

View File

@ -55,11 +55,17 @@ const char* Win32Device::get_core_version()
{ {
return _core_version.c_str(); return _core_version.c_str();
} }
const char* Win32Device::get_chip_model() const char* Win32Device::get_chip_model()
{ {
return "SDL2"; return "SDL2";
} }
const char* Win32Device::get_hardware_id()
{
return "112233445566";
}
void Win32Device::set_backlight_pin(uint8_t pin) void Win32Device::set_backlight_pin(uint8_t pin)
{ {
// Win32Device::_backlight_pin = pin; // Win32Device::_backlight_pin = pin;

View File

@ -59,6 +59,7 @@ class Win32Device : public BaseDevice {
void set_hostname(const char*); void set_hostname(const char*);
const char* get_core_version(); const char* get_core_version();
const char* get_chip_model(); const char* get_chip_model();
const char* get_hardware_id();
void set_backlight_pin(uint8_t pin); void set_backlight_pin(uint8_t pin);
void set_backlight_level(uint8_t val); void set_backlight_level(uint8_t val);

View File

@ -278,14 +278,17 @@ void haspProgressMsg(const __FlashStringHelper* msg)
/*Add a custom apply callback*/ /*Add a custom apply callback*/
static void custom_font_apply_cb(lv_theme_t* th, lv_obj_t* obj, lv_theme_style_t name) static void custom_font_apply_cb(lv_theme_t* th, lv_obj_t* obj, lv_theme_style_t name)
{ {
lv_style_list_t* list; /* lv_style_list_t* list;
switch(name) { switch(name) {
case LV_THEME_BTN: case LV_THEME_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN); list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
// _lv_style_list_add_style(list, &my_style); // _lv_style_list_add_style(list, &my_style);
break; break;
} default:
// nothing
;
} */
} }
/** /**

View File

@ -322,7 +322,7 @@ void my_btnmatrix_map_clear(lv_obj_t* obj)
static void my_btnmatrix_map_create(lv_obj_t* obj, const char* payload) static void my_btnmatrix_map_create(lv_obj_t* obj, const char* payload)
{ {
const char** map_p = lv_btnmatrix_get_map_array(obj); // const char** map_p = lv_btnmatrix_get_map_array(obj);
// Create new map // Create new map
// Reserve memory for JsonDocument // Reserve memory for JsonDocument
@ -1078,8 +1078,7 @@ static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16
bool update) bool update)
{ {
// We already know it's a arc object // We already know it's a arc object
int16_t intval = atoi(payload); uint16_t val = atoi(payload);
uint16_t val = atoi(payload);
char* attr = (char*)attr_p; char* attr = (char*)attr_p;
if(*attr == '.') attr++; // strip leading '.' if(*attr == '.') attr++; // strip leading '.'
@ -1122,8 +1121,7 @@ static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr_p, uin
bool update) bool update)
{ {
// We already know it's a linemeter object // We already know it's a linemeter object
int16_t intval = atoi(payload); uint16_t val = atoi(payload);
uint16_t val = atoi(payload);
uint16_t line_count = lv_linemeter_get_line_count(obj); uint16_t line_count = lv_linemeter_get_line_count(obj);
uint16_t angle = lv_linemeter_get_scale_angle(obj); uint16_t angle = lv_linemeter_get_scale_angle(obj);
@ -1794,6 +1792,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p
default: default:
hasp_local_style_attr(obj, attr, attr_hash, payload, update); hasp_local_style_attr(obj, attr, attr_hash, payload, update);
goto attribute_found;
} }
attribute_found: attribute_found:

View File

@ -42,8 +42,8 @@ extern uint8_t hasp_sleep_state;
dispatch_conf_t dispatch_setings = {.teleperiod = 300}; dispatch_conf_t dispatch_setings = {.teleperiod = 300};
uint32_t dispatchLastMillis; uint32_t dispatchLastMillis = -3000000; // force discovery
uint8_t nCommands = 0; uint8_t nCommands = 0;
haspCommand_t commands[18]; haspCommand_t commands[18];
struct moodlight_t struct moodlight_t
@ -208,6 +208,8 @@ static inline bool dispatch_parse_button_attribute(const char* topic_p, const ch
static void dispatch_gpio(const char* topic, const char* payload) static void dispatch_gpio(const char* topic, const char* payload)
{ {
#if HASP_USE_GPIO > 0
int16_t val; int16_t val;
uint8_t pin; uint8_t pin;
@ -238,6 +240,7 @@ static void dispatch_gpio(const char* topic, const char* payload)
} else { } else {
LOG_WARNING(TAG_MSGR, F("Invalid pin %s"), topic); LOG_WARNING(TAG_MSGR, F("Invalid pin %s"), topic);
} }
#endif
} }
// objectattribute=value // objectattribute=value
@ -882,6 +885,41 @@ void dispatch_current_state()
/******************************************* Command Wrapper Functions *********************************/ /******************************************* Command Wrapper Functions *********************************/
// Periodically publish a JSON string indicating system status
void dispatch_send_discovery(const char*, const char*)
{
#if HASP_USE_MQTT > 0
char data[512];
{
char buffer[128];
haspGetVersion(buffer, sizeof(buffer));
snprintf_P(data, sizeof(data),
PSTR("{\"node\":\"%s\",\"manufacturer\":\"" D_MANUFACTURER
"\",\"model\":\"%s\",\"hwid\":\"%s\",\"version\":\"%s\",\"numPages\":%u}"),
haspDevice.get_hostname(), haspDevice.get_model(), haspDevice.get_hardware_id(), buffer,
haspPages.count());
}
switch(mqtt_send_discovery(data)) {
case MQTT_ERR_OK:
LOG_TRACE(TAG_MQTT_PUB, F("discovery => %s"), data);
break;
case MQTT_ERR_PUB_FAIL:
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " discovery => %s"), data);
break;
case MQTT_ERR_NO_CONN:
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED));
break;
default:
LOG_ERROR(TAG_MQTT, F(D_ERROR_UNKNOWN));
}
dispatchLastMillis = millis();
#endif
}
// Periodically publish a JSON string indicating system status // Periodically publish a JSON string indicating system status
void dispatch_output_statusupdate(const char*, const char*) void dispatch_output_statusupdate(const char*, const char*)
{ {
@ -905,11 +943,11 @@ void dispatch_output_statusupdate(const char*, const char*)
strcat(data, buffer); strcat(data, buffer);
#endif #endif
snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"core\":\"%s\","), snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%zu,\"heapFrag\":%u,\"core\":\"%s\","),
haspDevice.get_free_heap(), haspDevice.get_heap_fragmentation(), haspDevice.get_core_version()); haspDevice.get_free_heap(), haspDevice.get_heap_fragmentation(), haspDevice.get_core_version());
strcat(data, buffer); strcat(data, buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("\"canUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"), snprintf_P(buffer, sizeof(buffer), PSTR("\"canUpdate\":\"false\",\"page\":%u,\"numPages\":%zu,"),
haspPages.get(), haspPages.count()); haspPages.get(), haspPages.count());
strcat(data, buffer); strcat(data, buffer);
@ -1020,6 +1058,7 @@ void dispatchEverySecond()
if(dispatch_setings.teleperiod > 0 && (millis() - dispatchLastMillis) >= dispatch_setings.teleperiod * 1000) { if(dispatch_setings.teleperiod > 0 && (millis() - dispatchLastMillis) >= dispatch_setings.teleperiod * 1000) {
dispatchLastMillis += dispatch_setings.teleperiod * 1000; dispatchLastMillis += dispatch_setings.teleperiod * 1000;
dispatch_output_statusupdate(NULL, NULL); dispatch_output_statusupdate(NULL, NULL);
dispatch_send_discovery(NULL, NULL);
} }
} }
#else #else

View File

@ -43,8 +43,6 @@ static void event_delete_object(lv_obj_t* obj)
case LV_HASP_BTNMATRIX: case LV_HASP_BTNMATRIX:
my_btnmatrix_map_clear(obj); my_btnmatrix_map_clear(obj);
_LV_WIN_PART_REAL_LAST;
_LV_WIN_PART_VIRTUAL_LAST;
break; break;
case LV_HASP_GAUGE: case LV_HASP_GAUGE:
@ -463,9 +461,7 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event)
/* Get the new value */ /* Get the new value */
char buffer[128]; char buffer[128];
char property[36];
uint16_t val = 0; uint16_t val = 0;
uint16_t max = 0;
val = lv_btnmatrix_get_active_btn(obj); val = lv_btnmatrix_get_active_btn(obj);
if(val != LV_BTNMATRIX_BTN_NONE) { if(val != LV_BTNMATRIX_BTN_NONE) {
@ -480,10 +476,6 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event)
last_value_sent = val; last_value_sent = val;
event_object_selection_changed(obj, hasp_event_id, val, buffer); event_object_selection_changed(obj, hasp_event_id, val, buffer);
// if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); // if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max);
// set the property
// snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val);
// attr_out_str(obj, property, buffer);
} }
/** /**

View File

@ -60,19 +60,19 @@ static void debugPrintTimestamp(int level, Print* _logOutput)
int rslt = gettimeofday(&curTime, NULL); int rslt = gettimeofday(&curTime, NULL);
time_t t = curTime.tv_sec; time_t t = curTime.tv_sec;
tm* timeinfo = localtime(&t); tm* timeinfo = localtime(&t);
int milli = curTime.tv_usec / 1000;
debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput); debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput);
if(timeinfo->tm_year >= 120) { if(timeinfo->tm_year >= 120) {
int milli = curTime.tv_usec / 1000;
char buffer[24]; char buffer[24];
strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S", timeinfo); // Literal String strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S", timeinfo); // Literal String
// strftime(buffer, sizeof(buffer), "[%H:%M:%S.", timeinfo); // Literal String // strftime(buffer, sizeof(buffer), "[%H:%M:%S.", timeinfo); // Literal String
#ifdef ARDUINO #ifdef ARDUINO
_logOutput->printf(PSTR("%s.%03lu]"), buffer, curTime.tv_usec / 1000); _logOutput->printf(PSTR("%s.%03lu]"), buffer, milli);
#else #else
debug_print(_logOutput, PSTR("%s.%03lu]"), buffer, curTime.tv_usec / 1000); debug_print(_logOutput, PSTR("%s.%03lu]"), buffer, milli);
#endif #endif
} else { } else {

View File

@ -190,6 +190,7 @@ void guiSetup(void)
disp_drv.ver_res = TFT_HEIGHT; disp_drv.ver_res = TFT_HEIGHT;
} }
lv_disp_t* display = lv_disp_drv_register(&disp_drv); lv_disp_t* display = lv_disp_drv_register(&disp_drv);
(void)display; // unused
/* Initialize Filesystems */ /* Initialize Filesystems */
#if LV_USE_FS_IF != 0 #if LV_USE_FS_IF != 0

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Subscribed to %s" #define D_MQTT_SUBSCRIBED "Subscribed to %s"
#define D_MQTT_NOT_SUBSCRIBED "Failed to subscribe to %s" #define D_MQTT_NOT_SUBSCRIBED "Failed to subscribe to %s"
#define D_MQTT_HA_AUTO_DISCOVERY "Register HA auto-discovery" #define D_MQTT_HA_AUTO_DISCOVERY "Register HA auto-discovery"
#define D_MQTT_PAYLOAD_TOO_LONG "Payload too long (%d bytes)" #define D_MQTT_PAYLOAD_TOO_LONG "Payload too long (%zu bytes)"
#define D_TELNET_CLOSING_CONNECTION "Closing session from %s" #define D_TELNET_CLOSING_CONNECTION "Closing session from %s"
#define D_TELNET_CLIENT_LOGIN_FROM "Client login from %s" #define D_TELNET_CLIENT_LOGIN_FROM "Client login from %s"
@ -87,7 +87,7 @@
#define D_DISPATCH_REBOOT "Rebooting the MCU now!" #define D_DISPATCH_REBOOT "Rebooting the MCU now!"
#define D_JSON_FAILED "JSON parsing failed:" #define D_JSON_FAILED "JSON parsing failed:"
#define D_JSONL_FAILED "JSONL parsing failed at line %d" #define D_JSONL_FAILED "JSONL parsing failed at line %zu"
#define D_JSONL_SUCCEEDED "Jsonl fully parsed" #define D_JSONL_SUCCEEDED "Jsonl fully parsed"
#define D_OTA_CHECK_UPDATE "Checking updates URL: %s" #define D_OTA_CHECK_UPDATE "Checking updates URL: %s"

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Feliratkozva: %s" #define D_MQTT_SUBSCRIBED "Feliratkozva: %s"
#define D_MQTT_NOT_SUBSCRIBED "Nem sikerült feliratkozni: %s" #define D_MQTT_NOT_SUBSCRIBED "Nem sikerült feliratkozni: %s"
#define D_MQTT_HA_AUTO_DISCOVERY "Regisztrálás HA automatikus felfedezésre" #define D_MQTT_HA_AUTO_DISCOVERY "Regisztrálás HA automatikus felfedezésre"
#define D_MQTT_PAYLOAD_TOO_LONG "$$$Payload too long (%d bytes)" #define D_MQTT_PAYLOAD_TOO_LONG "$$$Payload too long (%zu bytes)"
#define D_TELNET_CLOSING_CONNECTION "Munkamenet befejezése %s-el" #define D_TELNET_CLOSING_CONNECTION "Munkamenet befejezése %s-el"
#define D_TELNET_CLIENT_LOGIN_FROM "Kliens bejelentkezés innen: %s" #define D_TELNET_CLIENT_LOGIN_FROM "Kliens bejelentkezés innen: %s"
@ -87,7 +87,7 @@
#define D_DISPATCH_REBOOT "Az MCU most újraindul!" #define D_DISPATCH_REBOOT "Az MCU most újraindul!"
#define D_JSON_FAILED "JSON elemzése nem sikerült:" #define D_JSON_FAILED "JSON elemzése nem sikerült:"
#define D_JSONL_FAILED "JSONL elemzése meghiúsult a %d vonalnál" #define D_JSONL_FAILED "JSONL elemzése meghiúsult a %zu vonalnál"
#define D_JSONL_SUCCEEDED "JSONL teljes körűen elemezve" #define D_JSONL_SUCCEEDED "JSONL teljes körűen elemezve"
#define D_OTA_CHECK_UPDATE "A frissítések ellenőrzése az URL-en: %s" #define D_OTA_CHECK_UPDATE "A frissítések ellenőrzése az URL-en: %s"

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Ingeschreven op %s" #define D_MQTT_SUBSCRIBED "Ingeschreven op %s"
#define D_MQTT_NOT_SUBSCRIBED "Inschrijving op %s mislukt" #define D_MQTT_NOT_SUBSCRIBED "Inschrijving op %s mislukt"
#define D_MQTT_HA_AUTO_DISCOVERY "Registeren HA auto-configuratie" #define D_MQTT_HA_AUTO_DISCOVERY "Registeren HA auto-configuratie"
#define D_MQTT_PAYLOAD_TOO_LONG "Payload is te lang (%d bytes)" #define D_MQTT_PAYLOAD_TOO_LONG "Payload is te lang (%zu bytes)"
#define D_TELNET_CLOSING_CONNECTION "Sessie sluiten van %s" #define D_TELNET_CLOSING_CONNECTION "Sessie sluiten van %s"
#define D_TELNET_CLIENT_LOGIN_FROM "Client aangemeld van %s" #define D_TELNET_CLIENT_LOGIN_FROM "Client aangemeld van %s"
@ -86,7 +86,7 @@
#define D_DISPATCH_REBOOT "De MCU wordt herstart!" #define D_DISPATCH_REBOOT "De MCU wordt herstart!"
#define D_JSON_FAILED "JSON verwerking mislukt:" #define D_JSON_FAILED "JSON verwerking mislukt:"
#define D_JSONL_FAILED "JSONL verwerking mislukt op lijn %d" #define D_JSONL_FAILED "JSONL verwerking mislukt op lijn %zu"
#define D_JSONL_SUCCEEDED "Jsonl volledig verwerkt" #define D_JSONL_SUCCEEDED "Jsonl volledig verwerkt"
#define D_OTA_CHECK_UPDATE "Controle update URL: %s" #define D_OTA_CHECK_UPDATE "Controle update URL: %s"

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Abonat la %s" #define D_MQTT_SUBSCRIBED "Abonat la %s"
#define D_MQTT_NOT_SUBSCRIBED "Abonarea la %s a eșuat" #define D_MQTT_NOT_SUBSCRIBED "Abonarea la %s a eșuat"
#define D_MQTT_HA_AUTO_DISCOVERY "Înregistrare la auto-descoperire în HA" #define D_MQTT_HA_AUTO_DISCOVERY "Înregistrare la auto-descoperire în HA"
#define D_MQTT_PAYLOAD_TOO_LONG "$$$Payload too long (%d bytes)" #define D_MQTT_PAYLOAD_TOO_LONG "$$$Payload too long (%zu bytes)"
#define D_TELNET_CLOSING_CONNECTION "Terminarea sesiunii de la %s" #define D_TELNET_CLOSING_CONNECTION "Terminarea sesiunii de la %s"
#define D_TELNET_CLIENT_LOGIN_FROM "Conectare client de la %s" #define D_TELNET_CLIENT_LOGIN_FROM "Conectare client de la %s"
@ -87,7 +87,7 @@
#define D_DISPATCH_REBOOT "MCU-ul repornește acum!" #define D_DISPATCH_REBOOT "MCU-ul repornește acum!"
#define D_JSON_FAILED "Analiza JSON a eșuat:" #define D_JSON_FAILED "Analiza JSON a eșuat:"
#define D_JSONL_FAILED "Analiza JSONL a eșuat la linia %d" #define D_JSONL_FAILED "Analiza JSONL a eșuat la linia %zu"
#define D_JSONL_SUCCEEDED "Analiza JSONL completă" #define D_JSONL_SUCCEEDED "Analiza JSONL completă"
#define D_OTA_CHECK_UPDATE "Verificare la URL-ul actualizărilor: %s" #define D_OTA_CHECK_UPDATE "Verificare la URL-ul actualizărilor: %s"

View File

@ -266,15 +266,15 @@ int main(int argc, char* argv[])
// printf("%s %d\n", __FILE__, __LINE__); // printf("%s %d\n", __FILE__, __LINE__);
// fflush(stdout); // fflush(stdout);
printf("pre setup\n");
setup();
printf("to loop\n");
LOG_NOTICE(TAG_MAIN, "pre setup");
setup();
LOG_TRACE(TAG_MAIN, "loop started");
while(isRunning) { while(isRunning) {
loop(); loop();
// std::cout << "HSetup OK\n";
} }
printf("endrunning\n"); LOG_TRACE(TAG_MAIN, "main loop completed");
return 0; return 0;
} }

View File

@ -30,6 +30,7 @@ void mqttStop();
int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload); int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload);
int mqtt_send_state(const char* subtopic, const char* payload); int mqtt_send_state(const char* subtopic, const char* payload);
int mqtt_send_discovery(const char* payload);
int mqttPublish(const char* topic, const char* payload, size_t len, bool retain); int mqttPublish(const char* topic, const char* payload, size_t len, bool retain);
bool mqttIsConnected(); bool mqttIsConnected();

View File

@ -17,8 +17,8 @@
#define RETAINED true #define RETAINED true
// extern char mqttNodeName[16]; // extern char mqttNodeName[16];
extern char mqttNodeTopic[24]; extern std::string mqttNodeTopic;
extern char mqttGroupTopic[24]; extern std::string mqttGroupTopic;
extern bool mqttEnabled; extern bool mqttEnabled;
extern bool mqttHAautodiscover; extern bool mqttHAautodiscover;

View File

@ -123,7 +123,7 @@ void connlost(void* context, char* cause)
} }
// Receive incoming messages // Receive incoming messages
static void mqtt_message_cb(char* topic, char* payload, unsigned int length) static void mqtt_message_cb(char* topic, char* payload, size_t length)
{ // Handle incoming commands from MQTT { // Handle incoming commands from MQTT
if(length + 1 >= MQTT_MAX_PACKET_SIZE) { if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), length); LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), length);

View File

@ -6,6 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include "hasp_conf.h" #include "hasp_conf.h"
#include "hasplib.h"
#if HASP_USE_MQTT > 0 #if HASP_USE_MQTT > 0
#ifdef USE_PAHO #ifdef USE_PAHO
@ -50,23 +51,22 @@
#include <OsWrapper.h> #include <OsWrapper.h>
#endif #endif
#define ADDRESS "10.1.0.208:1883" // #define ADDRESS "10.1.0.208:1883"
#define CLIENTID "test1123" // #define CLIENTID "test1123"
#define TOPIC "hasp/plate35/" // #define TOPIC "hasp/plate35/"
#define QOS 1 #define QOS 1
#define TIMEOUT 1000L #define TIMEOUT 1000L
char mqttNodeTopic[24] = "hasp/plate35/"; std::string mqttNodeTopic;
const char* mqttGroupTopic = "hasp/plates/"; std::string mqttGroupTopic;
// char mqttNodeTopic[24]; std::string mqttLwtTopic;
// char mqttGroupTopic[24];
bool mqttEnabled = false; bool mqttEnabled = false;
bool mqttHAautodiscover = true; bool mqttHAautodiscover = true;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// These defaults may be overwritten with values saved by the web interface // These defaults may be overwritten with values saved by the web interface
#ifndef MQTT_HOST #ifndef MQTT_HOST
#define MQTT_HOST ""; #define MQTT_HOST "10.1.0.208";
#endif #endif
#ifndef MQTT_PORT #ifndef MQTT_PORT
@ -74,17 +74,15 @@ bool mqttHAautodiscover = true;
#endif #endif
#ifndef MQTT_USER #ifndef MQTT_USER
#define MQTT_USER ""; #define MQTT_USER "hasp";
#endif #endif
#ifndef MQTT_PASSW #ifndef MQTT_PASSW
#define MQTT_PASSW ""; #define MQTT_PASSW "hasp";
#endif
#ifndef MQTT_NODENAME
#define MQTT_NODENAME "";
#endif #endif
#ifndef MQTT_GROUPNAME #ifndef MQTT_GROUPNAME
#define MQTT_GROUPNAME ""; #define MQTT_GROUPNAME "plates";
#endif #endif
#ifndef MQTT_PREFIX #ifndef MQTT_PREFIX
@ -93,12 +91,11 @@ bool mqttHAautodiscover = true;
#define LWT_TOPIC "LWT" #define LWT_TOPIC "LWT"
char mqttServer[16] = MQTT_HOST; std::string mqttServer = MQTT_HOST;
char mqttUser[23] = MQTT_USER; std::string mqttUser = MQTT_USER;
char mqttPassword[32] = MQTT_PASSW; std::string mqttPassword = MQTT_PASSW;
// char mqttNodeName[16] = MQTT_NODENAME; std::string mqttGroupName = MQTT_GROUPNAME;
char mqttGroupName[16] = MQTT_GROUPNAME; uint16_t mqttPort = MQTT_PORT;
uint16_t mqttPort = MQTT_PORT;
MQTTClient mqtt_client; MQTTClient mqtt_client;
@ -120,7 +117,7 @@ void connlost(void* context, char* cause)
} }
// Receive incoming messages // Receive incoming messages
static void mqtt_message_cb(char* topic, char* payload, unsigned int length) static void mqtt_message_cb(char* topic, char* payload, size_t length)
{ // Handle incoming commands from MQTT { // Handle incoming commands from MQTT
if(length + 1 >= MQTT_MAX_PACKET_SIZE) { if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), length); LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), length);
@ -131,15 +128,15 @@ static void mqtt_message_cb(char* topic, char* payload, unsigned int length)
LOG_TRACE(TAG_MQTT_RCV, F("%s = %s"), topic, (char*)payload); LOG_TRACE(TAG_MQTT_RCV, F("%s = %s"), topic, (char*)payload);
if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic if(topic == strstr(topic, mqttNodeTopic.c_str())) { // startsWith mqttNodeTopic
// Node topic // Node topic
topic += strlen(mqttNodeTopic); // shorten topic topic += mqttNodeTopic.length(); // shorten topic
} else if(topic == strstr(topic, mqttGroupTopic)) { // startsWith mqttGroupTopic } else if(topic == strstr(topic, mqttGroupTopic.c_str())) { // startsWith mqttGroupTopic
// Group topic // Group topic
topic += strlen(mqttGroupTopic); // shorten topic topic += mqttGroupTopic.length(); // shorten topic
dispatch_topic_payload(topic, (const char*)payload); dispatch_topic_payload(topic, (const char*)payload);
return; return;
@ -163,12 +160,8 @@ static void mqtt_message_cb(char* topic, char* payload, unsigned int length)
if(!strcasecmp_P((char*)payload, PSTR("offline"))) { if(!strcasecmp_P((char*)payload, PSTR("offline"))) {
{ {
char msg[8]; char msg[8];
char tmp_topic[strlen(mqttNodeTopic) + 8];
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" LWT_TOPIC), mqttNodeTopic);
snprintf_P(msg, sizeof(msg), PSTR("online")); snprintf_P(msg, sizeof(msg), PSTR("online"));
mqttPublish(mqttLwtTopic.c_str(), msg, strlen(msg), true);
// /*bool res =*/mqttClient.publish(tmp_topic, msg, true);
mqttPublish(tmp_topic, msg, strlen(msg), true);
} }
} else { } else {
@ -179,11 +172,8 @@ static void mqtt_message_cb(char* topic, char* payload, unsigned int length)
} }
} }
int msgarrvd(void* context, char* topicName, int topicLen, MQTTClient_message* message) int mqtt_message_arrived(void* context, char* topicName, int topicLen, MQTTClient_message* message)
{ {
// printf("MQT RCV >> ");
// printf("%s => %.*s (%d)\n", topicName, message->payloadlen, (char *)message->payload, message->payloadlen);
char msg[message->payloadlen + 1]; char msg[message->payloadlen + 1];
memcpy(msg, (char*)message->payload, message->payloadlen); memcpy(msg, (char*)message->payload, message->payloadlen);
msg[message->payloadlen] = '\0'; msg[message->payloadlen] = '\0';
@ -200,10 +190,10 @@ void mqtt_subscribe(void* context, const char* topic)
MQTTClient client = (MQTTClient)context; MQTTClient client = (MQTTClient)context;
int rc; int rc;
printf("Subscribing to topic %s\n", topic);
//\nfor client %s using QoS%d\n\n", topic, CLIENTID, QOS);
if((rc = MQTTClient_subscribe(client, topic, QOS)) != MQTTCLIENT_SUCCESS) { if((rc = MQTTClient_subscribe(client, topic, QOS)) != MQTTCLIENT_SUCCESS) {
printf("Failed to start subscribe, return code %d\n", rc); LOG_WARNING(TAG_MQTT, D_BULLET D_MQTT_NOT_SUBSCRIBED, topic); // error code rc
} else {
LOG_VERBOSE(TAG_MQTT, D_BULLET D_MQTT_SUBSCRIBED, topic);
} }
} }
@ -222,7 +212,7 @@ int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
pubmsg.retained = retain; pubmsg.retained = retain;
MQTTClient_publishMessage(mqtt_client, topic, &pubmsg, &token); MQTTClient_publishMessage(mqtt_client, topic, &pubmsg, &token);
int rc = MQTTClient_waitForCompletion(mqtt_client, token, TIMEOUT); int rc = MQTTClient_waitForCompletion(mqtt_client, token, TIMEOUT); // time to wait in milliseconds
if(rc != MQTTCLIENT_SUCCESS) { if(rc != MQTTCLIENT_SUCCESS) {
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload); LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload);
@ -233,30 +223,32 @@ int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
} }
} }
// static bool mqttPublish(const char* topic, const char* payload, bool retain)
// {
// return mqttPublish(topic, payload, strlen(payload), retain);
// }
/* ===== Public HASP MQTT functions ===== */ /* ===== Public HASP MQTT functions ===== */
bool mqttIsConnected() bool mqttIsConnected()
{ {
return connected == 1; return MQTTClient_isConnected(mqtt_client);
} }
int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload) int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload)
{ {
char tmp_topic[strlen(mqttNodeTopic) + 20]; char tmp_topic[mqttNodeTopic.length() + 20];
// printf(("%sstate/%s\n"), mqttNodeTopic, subtopic); // printf(("%sstate/%s\n"), mqttNodeTopic, subtopic);
snprintf_P(tmp_topic, sizeof(tmp_topic), ("%sstate/%s"), mqttNodeTopic, subtopic); snprintf_P(tmp_topic, sizeof(tmp_topic), ("%sstate/%s"), mqttNodeTopic.c_str(), subtopic);
return mqttPublish(tmp_topic, payload, strlen(payload), false);
}
int mqtt_send_discovery(const char* payload)
{
char tmp_topic[20];
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/discovery"));
return mqttPublish(tmp_topic, payload, strlen(payload), false); return mqttPublish(tmp_topic, payload, strlen(payload), false);
} }
int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload) int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
{ {
char tmp_topic[strlen(mqttNodeTopic) + 20]; char tmp_topic[mqttNodeTopic.length() + 20];
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic, pageid, btnid); snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic.c_str(), pageid, btnid);
return mqttPublish(tmp_topic, payload, strlen(payload), false); return mqttPublish(tmp_topic, payload, strlen(payload), false);
} }
@ -264,24 +256,29 @@ static void onConnect(void* context)
{ {
MQTTClient client = (MQTTClient)context; MQTTClient client = (MQTTClient)context;
connected = 1; connected = 1;
std::string topic;
printf("Successful connection\n"); LOG_VERBOSE(TAG_MQTT, "Successful connection");
mqtt_subscribe(mqtt_client, TOPIC "command/#"); topic = mqttGroupTopic + "command/#";
// mqtt_subscribe(mqtt_client, TOPIC "command"); mqtt_subscribe(mqtt_client, topic.c_str());
mqtt_subscribe(mqtt_client, TOPIC "light/#");
mqtt_subscribe(mqtt_client, TOPIC "brightness/#"); topic = mqttNodeTopic + "command/#";
mqtt_subscribe(mqtt_client, "hass/status"); mqtt_subscribe(mqtt_client, topic.c_str());
topic = mqttGroupTopic + "config/#";
mqtt_subscribe(mqtt_client, topic.c_str());
topic = mqttNodeTopic + "config/#";
mqtt_subscribe(mqtt_client, topic.c_str());
/* Home Assistant auto-configuration */ /* Home Assistant auto-configuration */
#ifdef HASP_USE_HA #ifdef HASP_USE_HA
if(mqttHAautodiscover) mqtt_subscribe(mqtt_client, "homeassistant/status"); topic = "homeassistant/status";
mqtt_subscribe(mqtt_client, topic.c_str());
#endif #endif
mqttPublish(TOPIC LWT_TOPIC, "online", 6, true); mqttPublish(mqttLwtTopic.c_str(), "online", 6, true);
mqtt_send_object_state(0, 0, "connected");
std::cout << std::endl;
} }
void mqttStart() void mqttStart()
@ -291,8 +288,8 @@ void mqttStart()
int rc; int rc;
int ch; int ch;
if((rc = MQTTClient_create(&mqtt_client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != if((rc = MQTTClient_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
MQTTCLIENT_SUCCESS) { NULL)) != MQTTCLIENT_SUCCESS) {
printf("Failed to create client, return code %d\n", rc); printf("Failed to create client, return code %d\n", rc);
rc = EXIT_FAILURE; rc = EXIT_FAILURE;
return; return;
@ -308,13 +305,13 @@ void mqttStart()
conn_opts.will->message = "offline"; conn_opts.will->message = "offline";
conn_opts.will->qos = 1; conn_opts.will->qos = 1;
conn_opts.will->retained = 1; conn_opts.will->retained = 1;
conn_opts.will->topicName = "hasp/plate35/LWT"; conn_opts.will->topicName = mqttLwtTopic.c_str();
conn_opts.keepAliveInterval = 20; conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1; conn_opts.cleansession = 1;
conn_opts.username = "hasp"; conn_opts.username = mqttUser.c_str();
conn_opts.password = "hasp"; conn_opts.password = mqttPassword.c_str();
if((rc = MQTTClient_connect(mqtt_client, &conn_opts)) != MQTTCLIENT_SUCCESS) { if((rc = MQTTClient_connect(mqtt_client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
printf("Failed to start connect, return code %d\n", rc); printf("Failed to start connect, return code %d\n", rc);
@ -361,16 +358,30 @@ void mqttStop()
// return rc; // return rc;
} }
void mqttSetup(){}; void mqttSetup()
{
mqttNodeTopic = MQTT_PREFIX;
mqttNodeTopic += "/";
mqttNodeTopic += haspDevice.get_hostname();
mqttNodeTopic += "/";
mqttGroupTopic = MQTT_PREFIX;
mqttGroupTopic += "/";
mqttGroupTopic += mqttGroupName;
mqttGroupTopic += "/";
mqttLwtTopic = mqttNodeTopic;
mqttLwtTopic += LWT_TOPIC;
}
char* topicName;
int topicLen;
MQTTClient_message* message;
void mqttLoop() void mqttLoop()
{ {
int topicLen;
char* topicName; // Freed by msgarrvd
MQTTClient_message* message; // Freed by msgarrvd
int rc = MQTTClient_receive(mqtt_client, &topicName, &topicLen, &message, 4); int rc = MQTTClient_receive(mqtt_client, &topicName, &topicLen, &message, 4);
if(rc == MQTTCLIENT_SUCCESS && message) msgarrvd(mqtt_client, topicName, topicLen, message); if(rc == MQTTCLIENT_SUCCESS && message) mqtt_message_arrived(mqtt_client, topicName, topicLen, message);
}; };
void mqttEvery5Seconds(bool wifiIsConnected){}; void mqttEvery5Seconds(bool wifiIsConnected){};

View File

@ -144,6 +144,13 @@ int mqtt_send_state(const char* subtopic, const char* payload)
return mqttPublish(tmp_topic, payload, false); return mqttPublish(tmp_topic, payload, false);
} }
int mqtt_send_discovery(const char* payload)
{
char tmp_topic[20];
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/discovery"));
return mqttPublish(tmp_topic, payload, false);
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Receive incoming messages // Receive incoming messages
static void mqtt_message_cb(char* topic, byte* payload, unsigned int length) static void mqtt_message_cb(char* topic, byte* payload, unsigned int length)

View File

@ -6,6 +6,8 @@ extra_scripts =
tools/linux_build_extra.py tools/linux_build_extra.py
build_flags = build_flags =
${env.build_flags} ${env.build_flags}
-D HASP_MODEL="MacOS X App"
; ----- Monitor ; ----- Monitor
-D TFT_WIDTH=240 -D TFT_WIDTH=240
-D TFT_HEIGHT=320 -D TFT_HEIGHT=320

View File

@ -12,6 +12,7 @@ board = esp32dev
build_flags = build_flags =
${env.build_flags} ${env.build_flags}
${esp32.build_flags} ${esp32.build_flags}
-D HASP_MODEL="Arduitouch ESP32"
;region -- TFT_eSPI build options ------------------------ ;region -- TFT_eSPI build options ------------------------
${lcd.lolin24} ${lcd.lolin24}

View File

@ -12,6 +12,7 @@ board = wemos_d1_mini32
build_flags = build_flags =
${env.build_flags} ${env.build_flags}
${esp32.build_flags} ${esp32.build_flags}
-D HASP_MODEL="ESP32 D1 Mini"
;region -- TFT_eSPI build options ------------------------ ;region -- TFT_eSPI build options ------------------------
${lcd.lolin24} ${lcd.lolin24}

View File

@ -19,6 +19,7 @@ build_flags =
${env.build_flags} ${env.build_flags}
${esp32.build_flags} ${esp32.build_flags}
${esp32.ps_ram} ${esp32.ps_ram}
-D HASP_MODEL="Lolin D32 Pro"
;region -- TFT_eSPI build options ------------------------ ;region -- TFT_eSPI build options ------------------------
${lcd.lolin24} ${lcd.lolin24}

View File

@ -5,6 +5,8 @@ extra_scripts =
tools/linux_build_extra.py tools/linux_build_extra.py
build_flags = build_flags =
${env.build_flags} ${env.build_flags}
-D HASP_MODEL="Linux App"
; ----- Monitor ; ----- Monitor
-D TFT_WIDTH=240 -D TFT_WIDTH=240
-D TFT_HEIGHT=320 -D TFT_HEIGHT=320

View File

@ -5,6 +5,8 @@ extra_scripts =
tools/windows_build_extra.py tools/windows_build_extra.py
build_flags = build_flags =
${env.build_flags} ${env.build_flags}
-D HASP_MODEL="Windows App"
; ----- Monitor ; ----- Monitor
-D TFT_WIDTH=240 -D TFT_WIDTH=240
-D TFT_HEIGHT=320 -D TFT_HEIGHT=320