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]

View File

@ -45,14 +45,14 @@
* @param light_color light color of the QR code
* @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);
uint8_t * buf = lv_mem_alloc(buf_size);
uint8_t* buf = lv_mem_alloc(buf_size);
LV_ASSERT_MEM(buf);
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_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
* @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;
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;
}
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;
// 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;
// lv_coord_t obj_w = lv_obj_get_width(qrcode);
int qr_size = qrcodegen_getSize(qr_pixels);
int scale = 1;
int scaled = 0;
// int scale = 1;
// int scaled = 0;
// int qr_size = qrcodegen_getSize(qr_pixels);
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;
LV_LOG_ERROR("6 OK");
lv_img_header_t header;
lv_img_decoder_get_info(ext->src, &header);
LV_LOG_ERROR("7 OK");
lv_img_decoder_dsc_t dec_dsc;
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 x = 0; x < dec_dsc.header.w; x++) {
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;
}
@ -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
* @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);
lv_obj_del(qrcode);

View File

@ -55,7 +55,7 @@
// - They are completely thread-safe if the caller does not give the
// 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 int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
@ -135,7 +135,7 @@ static const int PENALTY_N4 = 10;
/*---- High-level QR Code encoding functions ----*/
// 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)
{
@ -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
// 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);
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]));
int bitLen = 0;
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(seg->numChars, numCharCountBits(seg->mode, version), qrcode, &bitLen);
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
uint8_t generator[qrcodegen_REED_SOLOMON_DEGREE_MAX];
calcReedSolomonGenerator(blockEccLen, generator);
const uint8_t * dat = data;
const uint8_t* dat = data;
for(int i = 0; i < numBlocks; i++) {
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);
for(int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data
if(j == shortBlockDataLen) k -= numShortBlocks;
@ -782,7 +782,7 @@ static bool getBit(int x, int i)
/*---- Segment handling ----*/
// Public function - see documentation comment in header file.
bool qrcodegen_isAlphanumeric(const char * text)
bool qrcodegen_isAlphanumeric(const char* text)
{
char buffer[64];
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.
bool qrcodegen_isNumeric(const char * text)
bool qrcodegen_isNumeric(const char* text)
{
assert(text != NULL);
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.
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);
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.
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];
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;
int accumCount = 0;
for(; *text != '\0'; text++) {
const char * temp = strchr(buffer, *text); // ALPHANUMERIC_CHARSET
const char* temp = strchr(buffer, *text); // ALPHANUMERIC_CHARSET
assert(temp != NULL);
accumData = accumData * 45 + (unsigned int)(temp - buffer); // ALPHANUMERIC_CHARSET
accumCount++;
@ -963,8 +963,8 @@ testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int
assert(segs != NULL || len == 0);
long result = 0;
for(size_t i = 0; i < len; i++) {
int numChars = segs[i].numChars;
int bitLength = segs[i].bitLength;
int16_t numChars = segs[i].numChars;
int16_t bitLength = segs[i].bitLength;
assert(0 <= numChars && numChars <= INT16_MAX);
assert(0 <= bitLength && bitLength <= INT16_MAX);
int ccbits = numCharCountBits(segs[i].mode, version);

View File

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

View File

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

View File

@ -5,6 +5,7 @@
#include "Arduino.h"
#include <Esp.h>
#include <WiFi.h>
#include "esp_system.h"
#include "hasp_conf.h"
@ -21,6 +22,24 @@
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()
{
ESP.restart();
@ -73,6 +92,11 @@ const char* Esp32Device::get_chip_model()
// model += chip_info.revision;
}
const char* Esp32Device::get_hardware_id()
{
return _hardware_id.c_str();
}
void Esp32Device::set_backlight_pin(uint8_t pin)
{
_backlight_pin = pin;

View File

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

View File

@ -5,6 +5,7 @@
#include "Arduino.h"
#include <Esp.h>
#include <ESP8266WiFi.h>
#include "esp8266.h"
@ -15,6 +16,25 @@
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()
{
ESP.restart();
@ -46,6 +66,11 @@ const char* Esp8266Device::get_chip_model()
return "ESP8266";
}
const char* Esp8266Device::get_hardware_id()
{
return _hardware_id.c_str();
}
void Esp8266Device::set_backlight_pin(uint8_t pin)
{
_backlight_pin = pin;

View File

@ -14,15 +14,7 @@ namespace dev {
class Esp8266Device : public BaseDevice {
public:
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;
}
Esp8266Device();
void reboot() override;
void show_info() override;
@ -31,6 +23,7 @@ class Esp8266Device : public BaseDevice {
void set_hostname(const char*);
const char* get_core_version();
const char* get_chip_model();
const char* get_hardware_id();
void set_backlight_pin(uint8_t pin) override;
void set_backlight_level(uint8_t val) override;
@ -47,6 +40,7 @@ class Esp8266Device : public BaseDevice {
private:
std::string _hostname;
std::string _hardware_id;
std::string _core_version;
uint8_t _backlight_pin;

View File

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

View File

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

View File

@ -30,6 +30,7 @@ const char* Stm32f4Device::get_hostname()
{
return _hostname.c_str();
}
void Stm32f4Device::set_hostname(const char* hostname)
{
_hostname = hostname;
@ -40,6 +41,14 @@ const char* Stm32f4Device::get_core_version()
// 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)
{
_backlight_pin = pin;

View File

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

View File

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

View File

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

View File

@ -278,14 +278,17 @@ void haspProgressMsg(const __FlashStringHelper* msg)
/*Add a custom apply callback*/
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) {
case LV_THEME_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
// _lv_style_list_add_style(list, &my_style);
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)
{
const char** map_p = lv_btnmatrix_get_map_array(obj);
// const char** map_p = lv_btnmatrix_get_map_array(obj);
// Create new map
// Reserve memory for JsonDocument
@ -1078,7 +1078,6 @@ static void hasp_process_arc_attribute(lv_obj_t* obj, const char* attr_p, uint16
bool update)
{
// We already know it's a arc object
int16_t intval = atoi(payload);
uint16_t val = atoi(payload);
char* attr = (char*)attr_p;
@ -1122,7 +1121,6 @@ static void hasp_process_lmeter_attribute(lv_obj_t* obj, const char* attr_p, uin
bool update)
{
// We already know it's a linemeter object
int16_t intval = atoi(payload);
uint16_t val = atoi(payload);
uint16_t line_count = lv_linemeter_get_line_count(obj);
@ -1794,6 +1792,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attr_p, const char* p
default:
hasp_local_style_attr(obj, attr, attr_hash, payload, update);
goto attribute_found;
}
attribute_found:

View File

@ -42,7 +42,7 @@ extern uint8_t hasp_sleep_state;
dispatch_conf_t dispatch_setings = {.teleperiod = 300};
uint32_t dispatchLastMillis;
uint32_t dispatchLastMillis = -3000000; // force discovery
uint8_t nCommands = 0;
haspCommand_t commands[18];
@ -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)
{
#if HASP_USE_GPIO > 0
int16_t val;
uint8_t pin;
@ -238,6 +240,7 @@ static void dispatch_gpio(const char* topic, const char* payload)
} else {
LOG_WARNING(TAG_MSGR, F("Invalid pin %s"), topic);
}
#endif
}
// objectattribute=value
@ -882,6 +885,41 @@ void dispatch_current_state()
/******************************************* 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
void dispatch_output_statusupdate(const char*, const char*)
{
@ -905,11 +943,11 @@ void dispatch_output_statusupdate(const char*, const char*)
strcat(data, buffer);
#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());
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());
strcat(data, buffer);
@ -1020,6 +1058,7 @@ void dispatchEverySecond()
if(dispatch_setings.teleperiod > 0 && (millis() - dispatchLastMillis) >= dispatch_setings.teleperiod * 1000) {
dispatchLastMillis += dispatch_setings.teleperiod * 1000;
dispatch_output_statusupdate(NULL, NULL);
dispatch_send_discovery(NULL, NULL);
}
}
#else

View File

@ -43,8 +43,6 @@ static void event_delete_object(lv_obj_t* obj)
case LV_HASP_BTNMATRIX:
my_btnmatrix_map_clear(obj);
_LV_WIN_PART_REAL_LAST;
_LV_WIN_PART_VIRTUAL_LAST;
break;
case LV_HASP_GAUGE:
@ -463,9 +461,7 @@ void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event)
/* Get the new value */
char buffer[128];
char property[36];
uint16_t val = 0;
uint16_t max = 0;
val = lv_btnmatrix_get_active_btn(obj);
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;
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);
// 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);
time_t t = curTime.tv_sec;
tm* timeinfo = localtime(&t);
int milli = curTime.tv_usec / 1000;
debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput);
if(timeinfo->tm_year >= 120) {
int milli = curTime.tv_usec / 1000;
char buffer[24];
strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S", timeinfo); // Literal String
// strftime(buffer, sizeof(buffer), "[%H:%M:%S.", timeinfo); // Literal String
#ifdef ARDUINO
_logOutput->printf(PSTR("%s.%03lu]"), buffer, curTime.tv_usec / 1000);
_logOutput->printf(PSTR("%s.%03lu]"), buffer, milli);
#else
debug_print(_logOutput, PSTR("%s.%03lu]"), buffer, curTime.tv_usec / 1000);
debug_print(_logOutput, PSTR("%s.%03lu]"), buffer, milli);
#endif
} else {

View File

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

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Subscribed 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_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_CLIENT_LOGIN_FROM "Client login from %s"
@ -87,7 +87,7 @@
#define D_DISPATCH_REBOOT "Rebooting the MCU now!"
#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_OTA_CHECK_UPDATE "Checking updates URL: %s"

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Feliratkozva: %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_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_CLIENT_LOGIN_FROM "Kliens bejelentkezés innen: %s"
@ -87,7 +87,7 @@
#define D_DISPATCH_REBOOT "Az MCU most újraindul!"
#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_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_NOT_SUBSCRIBED "Inschrijving op %s mislukt"
#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_CLIENT_LOGIN_FROM "Client aangemeld van %s"
@ -86,7 +86,7 @@
#define D_DISPATCH_REBOOT "De MCU wordt herstart!"
#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_OTA_CHECK_UPDATE "Controle update URL: %s"

View File

@ -47,7 +47,7 @@
#define D_MQTT_SUBSCRIBED "Abonat la %s"
#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_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_CLIENT_LOGIN_FROM "Conectare client de la %s"
@ -87,7 +87,7 @@
#define D_DISPATCH_REBOOT "MCU-ul repornește acum!"
#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_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__);
// 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) {
loop();
// std::cout << "HSetup OK\n";
}
printf("endrunning\n");
LOG_TRACE(TAG_MAIN, "main loop completed");
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_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);
bool mqttIsConnected();

View File

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

View File

@ -123,7 +123,7 @@ void connlost(void* context, char* cause)
}
// 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
if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), length);

View File

@ -6,6 +6,7 @@
#include <stdint.h>
#include "hasp_conf.h"
#include "hasplib.h"
#if HASP_USE_MQTT > 0
#ifdef USE_PAHO
@ -50,23 +51,22 @@
#include <OsWrapper.h>
#endif
#define ADDRESS "10.1.0.208:1883"
#define CLIENTID "test1123"
#define TOPIC "hasp/plate35/"
// #define ADDRESS "10.1.0.208:1883"
// #define CLIENTID "test1123"
// #define TOPIC "hasp/plate35/"
#define QOS 1
#define TIMEOUT 1000L
char mqttNodeTopic[24] = "hasp/plate35/";
const char* mqttGroupTopic = "hasp/plates/";
// char mqttNodeTopic[24];
// char mqttGroupTopic[24];
std::string mqttNodeTopic;
std::string mqttGroupTopic;
std::string mqttLwtTopic;
bool mqttEnabled = false;
bool mqttHAautodiscover = true;
////////////////////////////////////////////////////////////////////////////////////////////////////
// These defaults may be overwritten with values saved by the web interface
#ifndef MQTT_HOST
#define MQTT_HOST "";
#define MQTT_HOST "10.1.0.208";
#endif
#ifndef MQTT_PORT
@ -74,17 +74,15 @@ bool mqttHAautodiscover = true;
#endif
#ifndef MQTT_USER
#define MQTT_USER "";
#define MQTT_USER "hasp";
#endif
#ifndef MQTT_PASSW
#define MQTT_PASSW "";
#endif
#ifndef MQTT_NODENAME
#define MQTT_NODENAME "";
#define MQTT_PASSW "hasp";
#endif
#ifndef MQTT_GROUPNAME
#define MQTT_GROUPNAME "";
#define MQTT_GROUPNAME "plates";
#endif
#ifndef MQTT_PREFIX
@ -93,11 +91,10 @@ bool mqttHAautodiscover = true;
#define LWT_TOPIC "LWT"
char mqttServer[16] = MQTT_HOST;
char mqttUser[23] = MQTT_USER;
char mqttPassword[32] = MQTT_PASSW;
// char mqttNodeName[16] = MQTT_NODENAME;
char mqttGroupName[16] = MQTT_GROUPNAME;
std::string mqttServer = MQTT_HOST;
std::string mqttUser = MQTT_USER;
std::string mqttPassword = MQTT_PASSW;
std::string mqttGroupName = MQTT_GROUPNAME;
uint16_t mqttPort = MQTT_PORT;
MQTTClient mqtt_client;
@ -120,7 +117,7 @@ void connlost(void* context, char* cause)
}
// 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
if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
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);
if(topic == strstr(topic, mqttNodeTopic)) { // startsWith mqttNodeTopic
if(topic == strstr(topic, mqttNodeTopic.c_str())) { // startsWith mqttNodeTopic
// 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
topic += strlen(mqttGroupTopic); // shorten topic
topic += mqttGroupTopic.length(); // shorten topic
dispatch_topic_payload(topic, (const char*)payload);
return;
@ -163,12 +160,8 @@ static void mqtt_message_cb(char* topic, char* payload, unsigned int length)
if(!strcasecmp_P((char*)payload, PSTR("offline"))) {
{
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"));
// /*bool res =*/mqttClient.publish(tmp_topic, msg, true);
mqttPublish(tmp_topic, msg, strlen(msg), true);
mqttPublish(mqttLwtTopic.c_str(), msg, strlen(msg), true);
}
} 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];
memcpy(msg, (char*)message->payload, message->payloadlen);
msg[message->payloadlen] = '\0';
@ -200,10 +190,10 @@ void mqtt_subscribe(void* context, const char* topic)
MQTTClient client = (MQTTClient)context;
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) {
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;
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) {
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 ===== */
bool mqttIsConnected()
{
return connected == 1;
return MQTTClient_isConnected(mqtt_client);
}
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);
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);
}
int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
{
char tmp_topic[strlen(mqttNodeTopic) + 20];
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%sstate/p%ub%u"), mqttNodeTopic, pageid, btnid);
char tmp_topic[mqttNodeTopic.length() + 20];
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);
}
@ -264,24 +256,29 @@ static void onConnect(void* context)
{
MQTTClient client = (MQTTClient)context;
connected = 1;
std::string topic;
printf("Successful connection\n");
LOG_VERBOSE(TAG_MQTT, "Successful connection");
mqtt_subscribe(mqtt_client, TOPIC "command/#");
// mqtt_subscribe(mqtt_client, TOPIC "command");
mqtt_subscribe(mqtt_client, TOPIC "light/#");
mqtt_subscribe(mqtt_client, TOPIC "brightness/#");
mqtt_subscribe(mqtt_client, "hass/status");
topic = mqttGroupTopic + "command/#";
mqtt_subscribe(mqtt_client, topic.c_str());
topic = mqttNodeTopic + "command/#";
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 */
#ifdef HASP_USE_HA
if(mqttHAautodiscover) mqtt_subscribe(mqtt_client, "homeassistant/status");
topic = "homeassistant/status";
mqtt_subscribe(mqtt_client, topic.c_str());
#endif
mqttPublish(TOPIC LWT_TOPIC, "online", 6, true);
mqtt_send_object_state(0, 0, "connected");
std::cout << std::endl;
mqttPublish(mqttLwtTopic.c_str(), "online", 6, true);
}
void mqttStart()
@ -291,8 +288,8 @@ void mqttStart()
int rc;
int ch;
if((rc = MQTTClient_create(&mqtt_client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) !=
MQTTCLIENT_SUCCESS) {
if((rc = MQTTClient_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
NULL)) != MQTTCLIENT_SUCCESS) {
printf("Failed to create client, return code %d\n", rc);
rc = EXIT_FAILURE;
return;
@ -308,13 +305,13 @@ void mqttStart()
conn_opts.will->message = "offline";
conn_opts.will->qos = 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.cleansession = 1;
conn_opts.username = "hasp";
conn_opts.password = "hasp";
conn_opts.username = mqttUser.c_str();
conn_opts.password = mqttPassword.c_str();
if((rc = MQTTClient_connect(mqtt_client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
printf("Failed to start connect, return code %d\n", rc);
@ -361,16 +358,30 @@ void mqttStop()
// 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()
{
int topicLen;
char* topicName; // Freed by msgarrvd
MQTTClient_message* message; // Freed by msgarrvd
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){};

View File

@ -144,6 +144,13 @@ int mqtt_send_state(const char* subtopic, const char* payload)
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
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
build_flags =
${env.build_flags}
-D HASP_MODEL="MacOS X App"
; ----- Monitor
-D TFT_WIDTH=240
-D TFT_HEIGHT=320

View File

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

View File

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

View File

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

View File

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

View File

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