mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
Merge pull request #631 from kuba2k2/feature/pc-port
Improve PC port feature support (Win32/Linux)
This commit is contained in:
commit
837061b380
6
.github/workflows/build.yaml
vendored
6
.github/workflows/build.yaml
vendored
@ -154,7 +154,7 @@ jobs:
|
||||
- name: Enable Linux platform from platformio_override.ini
|
||||
run: |
|
||||
sed 's/; user_setups\/linux/user_setups\/linux/g' platformio_override-template.ini > platformio_override.ini
|
||||
mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
|
||||
mkdir -p .pio/libdeps/linux_sdl/paho/src
|
||||
- name: Install SDL2 library
|
||||
run: |
|
||||
sudo apt-get update
|
||||
@ -168,10 +168,10 @@ jobs:
|
||||
- name: Enable Linux platform from platformio_override.ini
|
||||
run: |
|
||||
sed -i 's/; user_setups\/linux/user_setups\/linux/g' platformio_override.ini
|
||||
mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
|
||||
mkdir -p .pio/libdeps/linux_sdl/paho/src
|
||||
- name: Install SDL2 library
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libsdl2-dev
|
||||
- name: Run PlatformIO
|
||||
run: pio run -e linux_sdl_64bits
|
||||
run: pio run -e linux_sdl
|
||||
|
4
.github/workflows/build_linux.yaml
vendored
4
.github/workflows/build_linux.yaml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
environments:
|
||||
- linux_sdl_64bits
|
||||
- linux_sdl
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -43,7 +43,7 @@ jobs:
|
||||
- name: Enable Linux platform from platformio_override.ini
|
||||
run: |
|
||||
sed -i 's/; user_setups\/linux/user_setups\/linux/g' platformio_override.ini
|
||||
mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
|
||||
mkdir -p .pio/libdeps/linux_sdl/paho/src
|
||||
- name: Install SDL2 library
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -39,7 +39,7 @@ jobs:
|
||||
- name: Enable Linux platform from platformio_override.ini
|
||||
run: |
|
||||
sed -i 's/; user_setups\/linux/user_setups\/linux/g' platformio_override.ini
|
||||
mkdir -p .pio/libdeps/linux_sdl_64bits/paho/src
|
||||
mkdir -p .pio/libdeps/linux_sdl/paho/src
|
||||
- name: Install SDL2 library
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
@ -1,3 +1,4 @@
|
||||
#if USE_MONITOR
|
||||
#include <unistd.h>
|
||||
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
|
||||
#include <SDL2/SDL.h>
|
||||
@ -53,3 +54,4 @@ void hal_loop(void)
|
||||
// lv_task_handler();
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
@ -33,6 +33,11 @@
|
||||
|
||||
#define HASP_USE_APP 1
|
||||
|
||||
/* Validate that build target was specified */
|
||||
#if HASP_TARGET_ARDUINO + HASP_TARGET_PC != 1
|
||||
#error "Build target invalid! Set *one* of: HASP_TARGET_ARDUINO, HASP_TARGET_PC"
|
||||
#endif
|
||||
|
||||
#ifndef HASP_USE_DEBUG
|
||||
#define HASP_USE_DEBUG 1
|
||||
#endif
|
||||
@ -65,6 +70,10 @@
|
||||
#define HASP_USE_MQTT (HASP_HAS_NETWORK)
|
||||
#endif
|
||||
|
||||
#ifndef HASP_USE_MQTT_ASYNC
|
||||
#define HASP_USE_MQTT_ASYNC (HASP_TARGET_PC)
|
||||
#endif
|
||||
|
||||
#ifndef HASP_USE_WIREGUARD
|
||||
#define HASP_USE_WIREGUARD (HASP_HAS_NETWORK)
|
||||
#endif
|
||||
@ -190,6 +199,46 @@
|
||||
|
||||
#define HASP_OBJECT_NOTATION "p%ub%u"
|
||||
|
||||
#ifndef HASP_ATTRIBUTE_FAST_MEM
|
||||
#define HASP_ATTRIBUTE_FAST_MEM
|
||||
#endif
|
||||
|
||||
#ifndef IRAM_ATTR
|
||||
#define IRAM_ATTR
|
||||
#endif
|
||||
|
||||
#ifndef FPSTR
|
||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper*>(pstr_pointer))
|
||||
#endif
|
||||
|
||||
#ifndef PGM_P
|
||||
#define PGM_P const char*
|
||||
#endif
|
||||
|
||||
/* Workarounds for PC build */
|
||||
#if HASP_TARGET_PC
|
||||
#ifndef __FlashStringHelper
|
||||
typedef char __FlashStringHelper;
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && !defined(String)
|
||||
#include <iostream>
|
||||
using String = std::string;
|
||||
#endif
|
||||
|
||||
#ifndef F
|
||||
#define F(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef PSTR
|
||||
#define PSTR(x) x
|
||||
#endif
|
||||
|
||||
#ifndef PROGMEM
|
||||
#define PROGMEM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Includes */
|
||||
#ifdef WINDOWS
|
||||
#include "winsock2.h"
|
||||
@ -281,7 +330,7 @@ static WiFiSpiClass WiFi;
|
||||
#if HASP_USE_MQTT > 0
|
||||
#include "mqtt/hasp_mqtt.h"
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
#define HASP_USE_PAHO
|
||||
#else
|
||||
#define HASP_USE_ESP_MQTT
|
||||
@ -326,52 +375,27 @@ static WiFiSpiClass WiFi;
|
||||
#include "sys/svc/hasp_slave.h"
|
||||
#endif
|
||||
|
||||
#ifndef HASP_ATTRIBUTE_FAST_MEM
|
||||
#define HASP_ATTRIBUTE_FAST_MEM
|
||||
#endif
|
||||
|
||||
#ifndef IRAM_ATTR
|
||||
#define IRAM_ATTR
|
||||
#endif
|
||||
|
||||
#ifndef FPSTR
|
||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper*>(pstr_pointer))
|
||||
#endif
|
||||
|
||||
#ifndef PGM_P
|
||||
#define PGM_P const char*
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#ifndef __FlashStringHelper
|
||||
#define __FlashStringHelper char
|
||||
#endif
|
||||
|
||||
#ifndef F
|
||||
#define F(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef PSTR
|
||||
#define PSTR(x) x
|
||||
#endif
|
||||
|
||||
#ifndef PROGMEM
|
||||
#define PROGMEM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS)
|
||||
#include <Windows.h>
|
||||
#define delay Sleep
|
||||
#endif
|
||||
|
||||
#if defined(POSIX)
|
||||
#ifdef USE_MONITOR
|
||||
#define delay SDL_Delay
|
||||
#else
|
||||
#define delay msleep
|
||||
#endif
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#endif
|
||||
|
||||
#if HASP_TARGET_PC
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if USE_MONITOR
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
#define snprintf_P snprintf
|
||||
#define memcpy_P memcpy
|
||||
@ -380,7 +404,13 @@ static WiFiSpiClass WiFi;
|
||||
#define strcpy_P strcpy
|
||||
#define strstr_P strstr
|
||||
#define halRestartMcu()
|
||||
#if USE_MONITOR
|
||||
#define millis SDL_GetTicks
|
||||
#elif defined(WINDOWS)
|
||||
#define millis Win32Millis
|
||||
#elif defined(POSIX)
|
||||
#define millis PosixMillis
|
||||
#endif
|
||||
|
||||
#define DEC 10
|
||||
#define HEX 16
|
||||
|
@ -12,15 +12,15 @@
|
||||
#include "user_config_override.h"
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
#define HASP_RANDOM(x) rand() % x
|
||||
#elif defined(ARDUINO)
|
||||
#elif HASP_TARGET_ARDUINO
|
||||
#define HASP_RANDOM(x) random(x)
|
||||
#else
|
||||
#define HASP_RANDOM(x) random() % x
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
#define LOG_OUTPUT(x, ...) printf(__VA_ARGS__)
|
||||
#else
|
||||
|
||||
|
@ -227,7 +227,9 @@ typedef void* lv_fs_drv_user_data_t;
|
||||
//# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash
|
||||
#endif
|
||||
#endif /*LV_USE_FS_IF*/
|
||||
#if HASP_TARGET_ARDUINO
|
||||
#define LV_FS_PC_PATH "/littlefs"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -125,7 +125,11 @@
|
||||
#define USE_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if USE_WINDOWS
|
||||
#ifndef USE_WIN32DRV
|
||||
#define USE_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if USE_WINDOWS || USE_WIN32DRV
|
||||
#define WINDOW_HOR_RES 480
|
||||
#define WINDOW_VER_RES 320
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#if !(defined(WINDOWS) || defined(POSIX) || defined(STM32F7xx))
|
||||
#if !(HASP_TARGET_PC || defined(STM32F7xx))
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdio.h>
|
||||
|
@ -6,11 +6,11 @@
|
||||
[platformio]
|
||||
extra_configs =
|
||||
; Uncomment or edit the lines to show more User Setups in the PIO sidebar
|
||||
; user_setups/darwin_sdl/*.ini
|
||||
; user_setups/darwin/*.ini
|
||||
; user_setups/esp32/*.ini
|
||||
; user_setups/esp32s2/*.ini
|
||||
; user_setups/esp32s3/*.ini
|
||||
; user_setups/linux_sdl/*.ini
|
||||
; user_setups/linux/*.ini
|
||||
; user_setups/stm32f4xx/*.ini
|
||||
; user_setups/win32/*.ini
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "Arduino.h"
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
#include <cstdint>
|
||||
#endif
|
||||
#if defined(POSIX)
|
||||
@ -30,6 +30,9 @@ class BaseDevice {
|
||||
public:
|
||||
bool has_battery = false;
|
||||
bool has_backligth_control = true;
|
||||
#if HASP_TARGET_PC
|
||||
bool pc_is_running = true;
|
||||
#endif
|
||||
|
||||
virtual void reboot()
|
||||
{}
|
||||
|
@ -19,7 +19,15 @@
|
||||
#include "hasp_conf.h"
|
||||
#include "hasp_debug.h"
|
||||
|
||||
#ifdef USE_MONITOR
|
||||
#include "display/monitor.h"
|
||||
#elif USE_FBDEV
|
||||
#include "display/fbdev.h"
|
||||
#include "drv/tft/tft_driver.h"
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
|
||||
// extern monitor_t monitor;
|
||||
|
||||
@ -35,12 +43,6 @@ PosixDevice::PosixDevice()
|
||||
_core_version = "unknown";
|
||||
_chip_model = "unknown";
|
||||
} else {
|
||||
// LOG_VERBOSE(0,"Sysname: %s", uts.sysname);
|
||||
// LOG_VERBOSE(0,"Nodename: %s", uts.nodename);
|
||||
// LOG_VERBOSE(0,"Release: %s", uts.release);
|
||||
// LOG_VERBOSE(0,"Version: %s", uts.version);
|
||||
// LOG_VERBOSE(0,"Machine: %s", uts.machine);
|
||||
|
||||
char version[256];
|
||||
snprintf(version, sizeof(version), "%s %s", uts.sysname, uts.release);
|
||||
_core_version = version;
|
||||
@ -53,6 +55,32 @@ PosixDevice::PosixDevice()
|
||||
_backlight_level = 255;
|
||||
}
|
||||
|
||||
void PosixDevice::set_config(const JsonObject& settings)
|
||||
{
|
||||
configOutput(settings, 0);
|
||||
#if USE_FBDEV
|
||||
if(settings["fbdev"].is<std::string>()) {
|
||||
haspTft.fbdev_path = "/dev/" + settings["fbdev"].as<std::string>();
|
||||
}
|
||||
#if USE_EVDEV
|
||||
if(settings["evdev"].is<std::string>()) {
|
||||
haspTft.evdev_names.push_back(settings["evdev"].as<std::string>());
|
||||
}
|
||||
if(settings["evdevs"].is<JsonArray>()) {
|
||||
for(auto v : settings["evdevs"].as<JsonArray>()) {
|
||||
haspTft.evdev_names.push_back(v.as<std::string>());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(settings["bldev"].is<std::string>()) {
|
||||
haspDevice.backlight_device = settings["bldev"].as<std::string>();
|
||||
}
|
||||
if(settings["blmax"].is<int>()) {
|
||||
haspDevice.backlight_max = settings["blmax"];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PosixDevice::reboot()
|
||||
{}
|
||||
void PosixDevice::show_info()
|
||||
@ -62,15 +90,16 @@ void PosixDevice::show_info()
|
||||
if(uname(&uts) < 0) {
|
||||
LOG_ERROR(0, "uname() error");
|
||||
} else {
|
||||
LOG_VERBOSE(0, "Sysname: %s", uts.sysname);
|
||||
LOG_VERBOSE(0, "Nodename: %s", uts.nodename);
|
||||
LOG_VERBOSE(0, "Release: %s", uts.release);
|
||||
LOG_VERBOSE(0, "Version: %s", uts.version);
|
||||
LOG_VERBOSE(0, "Machine: %s", uts.machine);
|
||||
LOG_VERBOSE(0, "Sysname : %s", uts.sysname);
|
||||
LOG_VERBOSE(0, "Nodename : %s", uts.nodename);
|
||||
LOG_VERBOSE(0, "Release : %s", uts.release);
|
||||
LOG_VERBOSE(0, "Version : %s", uts.version);
|
||||
LOG_VERBOSE(0, "Machine : %s", uts.machine);
|
||||
}
|
||||
|
||||
LOG_VERBOSE(0, "Processor : %s", "unknown");
|
||||
LOG_VERBOSE(0, "CPU freq. : %i MHz", 0);
|
||||
LOG_VERBOSE(0, "Processor : %s", get_chip_model());
|
||||
LOG_VERBOSE(0, "CPU freq. : %i MHz", get_cpu_frequency());
|
||||
LOG_VERBOSE(0, "OS Version : %s", get_core_version());
|
||||
}
|
||||
|
||||
const char* PosixDevice::get_hostname()
|
||||
@ -81,8 +110,11 @@ const char* PosixDevice::get_hostname()
|
||||
void PosixDevice::set_hostname(const char* hostname)
|
||||
{
|
||||
_hostname = hostname;
|
||||
#if USE_MONITOR
|
||||
monitor_title(hostname);
|
||||
// SDL_SetWindowTitle(monitor.window, hostname);
|
||||
#elif USE_FBDEV
|
||||
// fbdev doesn't really have a title bar
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* PosixDevice::get_core_version()
|
||||
@ -146,13 +178,35 @@ void PosixDevice::update_backlight()
|
||||
{
|
||||
uint8_t level = _backlight_power ? _backlight_level : 0;
|
||||
if(_backlight_invert) level = 255 - level;
|
||||
#if USE_MONITOR
|
||||
monitor_backlight(level);
|
||||
// SDL_SetTextureColorMod(monitor.texture, level, level, level);
|
||||
// window_update(&monitor);
|
||||
// monitor.sdl_refr_qry = true;
|
||||
// monitor_sdl_refr(NULL);
|
||||
// const lv_area_t area = {1,1,0,0};
|
||||
// monitor_flush(NULL,&area,NULL);
|
||||
#elif USE_FBDEV
|
||||
// set display backlight, if possible
|
||||
if(backlight_device != "") {
|
||||
if(backlight_max == 0) {
|
||||
std::ifstream f;
|
||||
f.open("/sys/class/backlight/" + backlight_device + "/max_brightness");
|
||||
if(!f.fail()) {
|
||||
f >> backlight_max;
|
||||
f.close();
|
||||
} else {
|
||||
perror("Max brightness read failed");
|
||||
}
|
||||
}
|
||||
|
||||
int brightness = map(level, 0, 255, 0, backlight_max);
|
||||
LOG_VERBOSE(0, "Setting brightness to %d/255 (%d)", level, brightness);
|
||||
|
||||
std::ofstream f;
|
||||
f.open("/sys/class/backlight/" + backlight_device + "/brightness");
|
||||
if(!f.fail()) {
|
||||
f << brightness;
|
||||
f.close();
|
||||
} else {
|
||||
perror("Brightness write failed (are you root?)");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t PosixDevice::get_free_max_block()
|
||||
@ -192,6 +246,12 @@ bool PosixDevice::is_system_pin(uint8_t pin)
|
||||
return false;
|
||||
}
|
||||
|
||||
void PosixDevice::run_thread(void (*func)(void*), void* arg)
|
||||
{
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, (void* (*)(void*))func, arg);
|
||||
}
|
||||
|
||||
#ifndef TARGET_OS_MAC
|
||||
long PosixDevice::get_uptime()
|
||||
{
|
||||
@ -221,6 +281,25 @@ long PosixDevice::get_uptime()
|
||||
|
||||
} // namespace dev
|
||||
|
||||
static time_t tv_sec_start = 0;
|
||||
|
||||
unsigned long PosixMillis()
|
||||
{
|
||||
struct timespec spec;
|
||||
clock_gettime(CLOCK_REALTIME, &spec);
|
||||
if(tv_sec_start == 0) {
|
||||
tv_sec_start = spec.tv_sec;
|
||||
}
|
||||
unsigned long msec1 = (spec.tv_sec - tv_sec_start) * 1000;
|
||||
unsigned long msec2 = spec.tv_nsec / 1e6;
|
||||
return msec1 + msec2;
|
||||
}
|
||||
|
||||
void msleep(unsigned long millis)
|
||||
{
|
||||
usleep(millis * 1000);
|
||||
}
|
||||
|
||||
dev::PosixDevice haspDevice;
|
||||
|
||||
#endif // POSIX
|
||||
|
@ -31,6 +31,8 @@ class PosixDevice : public BaseDevice {
|
||||
public:
|
||||
PosixDevice();
|
||||
|
||||
void set_config(const JsonObject& settings);
|
||||
|
||||
void reboot() override;
|
||||
void show_info() override;
|
||||
|
||||
@ -56,6 +58,12 @@ class PosixDevice : public BaseDevice {
|
||||
|
||||
bool is_system_pin(uint8_t pin) override;
|
||||
|
||||
void run_thread(void (*func)(void*), void* arg);
|
||||
|
||||
public:
|
||||
std::string backlight_device;
|
||||
int backlight_max = 0;
|
||||
|
||||
private:
|
||||
std::string _hostname;
|
||||
std::string _core_version;
|
||||
@ -71,6 +79,9 @@ class PosixDevice : public BaseDevice {
|
||||
|
||||
} // namespace dev
|
||||
|
||||
extern unsigned long PosixMillis();
|
||||
extern void msleep(unsigned long millis);
|
||||
|
||||
using dev::PosixDevice;
|
||||
extern dev::PosixDevice haspDevice;
|
||||
|
||||
|
@ -11,7 +11,11 @@
|
||||
#include "hasp_conf.h"
|
||||
#include "hasp_debug.h"
|
||||
|
||||
#if USE_MONITOR
|
||||
#include "display/monitor.h"
|
||||
#elif USE_WIN32DRV
|
||||
#include "win32drv/win32drv.h"
|
||||
#endif
|
||||
|
||||
namespace dev {
|
||||
|
||||
@ -21,11 +25,33 @@ static inline void native_cpuid(unsigned int* eax, unsigned int* ebx, unsigned i
|
||||
asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "0"(*eax), "2"(*ecx) : "memory");
|
||||
}
|
||||
|
||||
void Win32Device::reboot()
|
||||
{}
|
||||
|
||||
void Win32Device::show_info()
|
||||
Win32Device::Win32Device()
|
||||
{
|
||||
char buffer[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD length = sizeof(buffer);
|
||||
|
||||
if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameNetBIOS, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameDnsHostname, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsHostname, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsDomain, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else {
|
||||
_hostname = "localhost";
|
||||
}
|
||||
|
||||
// Get the Windows version.
|
||||
DWORD dwBuild = 0;
|
||||
DWORD dwVersion = GetVersion();
|
||||
DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||
DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
||||
if(dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
|
||||
|
||||
char version[128];
|
||||
snprintf(version, sizeof(version), "Windows %d.%d.%d", dwMajorVersion, dwMinorVersion, dwBuild);
|
||||
_core_version = version;
|
||||
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
eax = 0;
|
||||
@ -35,10 +61,23 @@ void Win32Device::show_info()
|
||||
memcpy(vendor, &ebx, 4);
|
||||
memcpy(vendor + 4, &edx, 4);
|
||||
memcpy(vendor + 8, &ecx, 4);
|
||||
vendor[12] = '\0';
|
||||
vendor[12] = '\0';
|
||||
_chip_model = vendor;
|
||||
|
||||
LOG_VERBOSE(0, F("Processor : %s"), vendor);
|
||||
// _backlight_pin = -1;
|
||||
_backlight_power = 1;
|
||||
_backlight_invert = 0;
|
||||
_backlight_level = 255;
|
||||
}
|
||||
|
||||
void Win32Device::reboot()
|
||||
{}
|
||||
|
||||
void Win32Device::show_info()
|
||||
{
|
||||
LOG_VERBOSE(0, F("Processor : %s"), get_chip_model());
|
||||
LOG_VERBOSE(0, F("CPU freq. : %i MHz"), get_cpu_frequency());
|
||||
LOG_VERBOSE(0, F("OS Version : %s"), get_core_version());
|
||||
}
|
||||
|
||||
const char* Win32Device::get_hostname()
|
||||
@ -48,8 +87,11 @@ const char* Win32Device::get_hostname()
|
||||
void Win32Device::set_hostname(const char* hostname)
|
||||
{
|
||||
_hostname = hostname;
|
||||
#if USE_MONITOR
|
||||
monitor_title(hostname);
|
||||
// SDL_SetWindowTitle(monitor.window, hostname);
|
||||
#elif USE_WIN32DRV
|
||||
lv_win32_set_title(hostname);
|
||||
#endif
|
||||
}
|
||||
const char* Win32Device::get_core_version()
|
||||
{
|
||||
@ -58,7 +100,7 @@ const char* Win32Device::get_core_version()
|
||||
|
||||
const char* Win32Device::get_chip_model()
|
||||
{
|
||||
return "SDL2";
|
||||
return _chip_model.c_str();
|
||||
}
|
||||
|
||||
const char* Win32Device::get_hardware_id()
|
||||
@ -112,7 +154,9 @@ void Win32Device::update_backlight()
|
||||
{
|
||||
uint8_t level = _backlight_power ? _backlight_level : 0;
|
||||
if(_backlight_invert) level = 255 - level;
|
||||
#if USE_MONITOR
|
||||
monitor_backlight(level);
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t Win32Device::get_free_max_block()
|
||||
@ -143,6 +187,11 @@ bool Win32Device::is_system_pin(uint8_t pin)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Win32Device::run_thread(void (*func)(void*), void* arg)
|
||||
{
|
||||
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL);
|
||||
}
|
||||
|
||||
long Win32Device::get_uptime()
|
||||
{
|
||||
return GetTickCount64() / 1000;
|
||||
@ -150,6 +199,11 @@ long Win32Device::get_uptime()
|
||||
|
||||
} // namespace dev
|
||||
|
||||
long Win32Millis()
|
||||
{
|
||||
return GetTickCount64();
|
||||
}
|
||||
|
||||
dev::Win32Device haspDevice;
|
||||
|
||||
#endif // WINDOWS
|
||||
#endif // WINDOWS
|
||||
|
@ -18,39 +18,7 @@ namespace dev {
|
||||
class Win32Device : public BaseDevice {
|
||||
|
||||
public:
|
||||
Win32Device()
|
||||
{
|
||||
char buffer[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
DWORD length = sizeof(buffer);
|
||||
|
||||
if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameNetBIOS, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNameDnsHostname, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsHostname, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else if(GetComputerNameExA((COMPUTER_NAME_FORMAT)ComputerNamePhysicalDnsDomain, buffer, &length)) {
|
||||
_hostname = buffer;
|
||||
} else {
|
||||
_hostname = "localhost";
|
||||
}
|
||||
|
||||
// Get the Windows version.
|
||||
DWORD dwBuild = 0;
|
||||
DWORD dwVersion = GetVersion();
|
||||
DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||
DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
||||
if(dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
|
||||
|
||||
char version[128];
|
||||
snprintf(version, sizeof(version), "Windows %d.%d-%d", dwMajorVersion, dwMinorVersion, dwBuild);
|
||||
_core_version = version;
|
||||
|
||||
// _backlight_pin = -1;
|
||||
_backlight_power = 1;
|
||||
_backlight_invert = 0;
|
||||
_backlight_level = 255;
|
||||
}
|
||||
Win32Device();
|
||||
|
||||
void reboot() override;
|
||||
void show_info() override;
|
||||
@ -77,9 +45,12 @@ class Win32Device : public BaseDevice {
|
||||
|
||||
bool is_system_pin(uint8_t pin) override;
|
||||
|
||||
void run_thread(void (*func)(void*), void* arg);
|
||||
|
||||
private:
|
||||
std::string _hostname;
|
||||
std::string _core_version;
|
||||
std::string _chip_model;
|
||||
|
||||
uint8_t _backlight_pin;
|
||||
uint8_t _backlight_level;
|
||||
@ -91,9 +62,11 @@ class Win32Device : public BaseDevice {
|
||||
|
||||
} // namespace dev
|
||||
|
||||
extern long Win32Millis();
|
||||
|
||||
using dev::Win32Device;
|
||||
extern dev::Win32Device haspDevice;
|
||||
|
||||
#endif // WINDOWS
|
||||
|
||||
#endif // HASP_DEVICE_WINDOWS_H
|
||||
#endif // HASP_DEVICE_WINDOWS_H
|
||||
|
@ -77,9 +77,15 @@ class BaseTft {
|
||||
#elif defined(STM32F7)
|
||||
#warning Building for STM32F7xx Tfts
|
||||
#include "tft_driver_tftespi.h"
|
||||
#elif defined(WINDOWS) || defined(POSIX)
|
||||
#elif USE_MONITOR && HASP_TARGET_PC
|
||||
// #warning Building for SDL2
|
||||
#include "tft_driver_sdl2.h"
|
||||
#elif USE_WIN32DRV && HASP_TARGET_PC
|
||||
// #warning Building for Win32Drv
|
||||
#include "tft_driver_win32drv.h"
|
||||
#elif USE_FBDEV && HASP_TARGET_PC
|
||||
// #warning Building for POSIX fbdev
|
||||
#include "tft_driver_posix_fbdev.h"
|
||||
#else
|
||||
// #warning Building for Generic Tfts
|
||||
using dev::BaseTft;
|
||||
|
251
src/drv/tft/tft_driver_posix_fbdev.cpp
Normal file
251
src/drv/tft/tft_driver_posix_fbdev.cpp
Normal file
@ -0,0 +1,251 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#if USE_FBDEV && HASP_TARGET_PC
|
||||
|
||||
#include "hasplib.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "display/fbdev.h"
|
||||
|
||||
#include "drv/tft/tft_driver.h"
|
||||
#include "tft_driver_posix_fbdev.h"
|
||||
|
||||
#if USE_EVDEV || USE_BSD_EVDEV
|
||||
#include "indev/evdev.h"
|
||||
#endif
|
||||
|
||||
#include "dev/device.h"
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_gui.h"
|
||||
|
||||
#ifdef HASP_CUSTOMIZE_BOOTLOGO
|
||||
#include "custom/bootlogo.h" // Sketch tab header for xbm images
|
||||
#else
|
||||
#include "custom/bootlogo_template.h" // Sketch tab header for xbm images
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <linux/vt.h>
|
||||
|
||||
#if USE_BSD_EVDEV
|
||||
#include <dev/evdev/input.h>
|
||||
#else
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
extern uint16_t tft_width;
|
||||
extern uint16_t tft_height;
|
||||
|
||||
namespace dev {
|
||||
|
||||
/**
|
||||
* A task to measure the elapsed time for LittlevGL
|
||||
* @param data unused
|
||||
* @return never return
|
||||
*/
|
||||
static void* tick_thread(void* data)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
while(1) {
|
||||
usleep(5000); /*Sleep for 5 millisecond*/
|
||||
lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t TftFbdevDrv::width()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
int32_t TftFbdevDrv::height()
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
static void* gui_entrypoint(void* arg)
|
||||
{
|
||||
#if HASP_USE_LVGL_TASK
|
||||
// create an LVGL GUI task thread
|
||||
pthread_t gui_pthread;
|
||||
pthread_create(&gui_pthread, 0, (void* (*)(void*))gui_task, NULL);
|
||||
#endif
|
||||
// create an LVGL tick thread
|
||||
pthread_t tick_pthread;
|
||||
pthread_create(&tick_pthread, 0, tick_thread, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TftFbdevDrv::init(int32_t w, int h)
|
||||
{
|
||||
// try to switch the active tty to tty7
|
||||
int tty_fd = open("/dev/tty0", O_WRONLY);
|
||||
if(tty_fd == -1) {
|
||||
perror("Couldn't open /dev/tty0 (try running as root)");
|
||||
} else {
|
||||
if(ioctl(tty_fd, VT_ACTIVATE, 7) == -1) perror("Couldn't change active tty");
|
||||
}
|
||||
close(tty_fd);
|
||||
|
||||
// check active tty
|
||||
std::ifstream f;
|
||||
f.open("/sys/class/tty/tty0/active");
|
||||
std::string tty;
|
||||
f >> tty;
|
||||
tty = "/dev/" + tty;
|
||||
f.close();
|
||||
|
||||
// try to hide the cursor
|
||||
tty_fd = open(tty.c_str(), O_WRONLY);
|
||||
if(tty_fd == -1) {
|
||||
perror("Couldn't open active tty (try running as root)");
|
||||
} else {
|
||||
write(tty_fd, "\033[?25l", 6);
|
||||
}
|
||||
close(tty_fd);
|
||||
|
||||
/* Add a display
|
||||
* Use the 'fbdev' driver which uses POSIX framebuffer device as a display
|
||||
* The following input devices are handled: mouse, keyboard, mousewheel */
|
||||
fbdev_init(fbdev_path.empty() ? NULL : fbdev_path.c_str());
|
||||
fbdev_get_sizes((uint32_t*)&_width, (uint32_t*)&_height);
|
||||
|
||||
// show the splashscreen early
|
||||
splashscreen();
|
||||
|
||||
tft_width = _width;
|
||||
tft_height = _height;
|
||||
|
||||
#if USE_EVDEV || USE_BSD_EVDEV
|
||||
DIR* dir = opendir("/dev/input");
|
||||
if(dir == NULL) {
|
||||
perror("/dev/input opendir failed");
|
||||
} else {
|
||||
// iterate through /dev/input devices
|
||||
struct dirent* dirent;
|
||||
unsigned char ev_type[EV_MAX / 8 + 1];
|
||||
while((dirent = readdir(dir)) != NULL) {
|
||||
// make sure it's a block device matching /dev/input/event*
|
||||
if(strncmp(dirent->d_name, "event", 5) != 0 || strlen(dirent->d_name) <= 5) continue;
|
||||
if(dirent->d_type != DT_CHR) continue;
|
||||
// skip device if not specified on command line
|
||||
if(!evdev_names.empty() &&
|
||||
std::find(evdev_names.begin(), evdev_names.end(), std::string(dirent->d_name)) == evdev_names.end())
|
||||
continue;
|
||||
// get full path
|
||||
char dev_path[64];
|
||||
strcpy(dev_path, "/dev/input/");
|
||||
strcat(dev_path, dirent->d_name);
|
||||
#if USE_BSD_EVDEV
|
||||
// open the device
|
||||
int fd = open(dev_path, O_RDONLY | O_NOCTTY);
|
||||
#else
|
||||
int fd = open(dev_path, O_RDONLY | O_NOCTTY | O_NDELAY);
|
||||
#endif
|
||||
if(fd == -1) {
|
||||
perror("input open failed");
|
||||
continue;
|
||||
}
|
||||
// read supported event types
|
||||
memset(ev_type, 0, sizeof(ev_type));
|
||||
if(ioctl(fd, EVIOCGBIT(0, sizeof(ev_type)), ev_type) < 0) {
|
||||
perror("ioctl failed");
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
// read device name
|
||||
char dev_name[256];
|
||||
if(ioctl(fd, EVIOCGNAME(sizeof(dev_name)), dev_name) < 0) {
|
||||
perror("ioctl failed");
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
// check which types are supported; judge LVGL device type
|
||||
lv_indev_type_t dev_type;
|
||||
const char* dev_type_name;
|
||||
if(ev_type[EV_REL / 8] & (1 << (EV_REL % 8))) {
|
||||
dev_type = LV_INDEV_TYPE_POINTER;
|
||||
dev_type_name = "EV_REL";
|
||||
} else if(ev_type[EV_ABS / 8] & (1 << (EV_ABS % 8))) {
|
||||
dev_type = LV_INDEV_TYPE_POINTER;
|
||||
dev_type_name = "EV_ABS";
|
||||
} else if(ev_type[EV_KEY / 8] & (1 << (EV_KEY % 8))) {
|
||||
dev_type = LV_INDEV_TYPE_KEYPAD;
|
||||
dev_type_name = "EV_KEY";
|
||||
} else {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
// register the device
|
||||
switch(dev_type) {
|
||||
case LV_INDEV_TYPE_POINTER:
|
||||
LOG_VERBOSE(TAG_TFT, F("Pointer : %s %s (%s)"), dev_path, dev_type_name, dev_name);
|
||||
break;
|
||||
case LV_INDEV_TYPE_KEYPAD:
|
||||
LOG_VERBOSE(TAG_TFT, F("Keypad : %s %s (%s)"), dev_path, dev_type_name, dev_name);
|
||||
break;
|
||||
default:
|
||||
LOG_VERBOSE(TAG_TFT, F("Input : %s %s (%s)"), dev_path, dev_type_name, dev_name);
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
// print verbose resolution info
|
||||
lv_indev_t* indev;
|
||||
if(!evdev_register(dev_path, dev_type, &indev) || indev == NULL) {
|
||||
printf("Failed to register evdev\n");
|
||||
continue;
|
||||
}
|
||||
evdev_data_t* user_data = (evdev_data_t*)indev->driver.user_data;
|
||||
LOG_VERBOSE(TAG_TFT, F("Resolution : X=%d (%d..%d), Y=%d (%d..%d)"), user_data->x_max,
|
||||
user_data->x_absinfo.minimum, user_data->x_absinfo.maximum, user_data->y_max,
|
||||
user_data->y_absinfo.minimum, user_data->y_absinfo.maximum);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
gui_entrypoint(NULL);
|
||||
}
|
||||
void TftFbdevDrv::show_info()
|
||||
{
|
||||
splashscreen();
|
||||
|
||||
LOG_VERBOSE(TAG_TFT, F("Driver : %s"), get_tft_model());
|
||||
}
|
||||
|
||||
void TftFbdevDrv::splashscreen()
|
||||
{
|
||||
uint8_t fg[] = logoFgColor;
|
||||
uint8_t bg[] = logoBgColor;
|
||||
lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]);
|
||||
lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]);
|
||||
fbdev_splashscreen(logoImage, logoWidth, logoHeight, fgColor, bgColor);
|
||||
}
|
||||
void TftFbdevDrv::set_rotation(uint8_t rotation)
|
||||
{}
|
||||
void TftFbdevDrv::set_invert(bool invert)
|
||||
{}
|
||||
void TftFbdevDrv::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
|
||||
{
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
bool TftFbdevDrv::is_driver_pin(uint8_t pin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const char* TftFbdevDrv::get_tft_model()
|
||||
{
|
||||
return "POSIX fbdev";
|
||||
}
|
||||
|
||||
} // namespace dev
|
||||
|
||||
dev::TftFbdevDrv haspTft;
|
||||
|
||||
#endif // WINDOWS || POSIX
|
50
src/drv/tft/tft_driver_posix_fbdev.h
Normal file
50
src/drv/tft/tft_driver_posix_fbdev.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#ifndef HASP_FBDEV_DRIVER_H
|
||||
#define HASP_FBDEV_DRIVER_H
|
||||
|
||||
#include "tft_driver.h"
|
||||
|
||||
#if USE_FBDEV && HASP_TARGET_PC
|
||||
// #warning Building H driver FBDEV
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dev {
|
||||
|
||||
class TftFbdevDrv : BaseTft {
|
||||
public:
|
||||
void init(int w, int h);
|
||||
void show_info();
|
||||
void splashscreen();
|
||||
|
||||
void set_rotation(uint8_t rotation);
|
||||
void set_invert(bool invert);
|
||||
|
||||
void flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
|
||||
bool is_driver_pin(uint8_t pin);
|
||||
|
||||
const char* get_tft_model();
|
||||
|
||||
int32_t width();
|
||||
int32_t height();
|
||||
|
||||
public:
|
||||
std::string fbdev_path;
|
||||
std::vector<std::string> evdev_names;
|
||||
|
||||
private:
|
||||
int32_t _width, _height;
|
||||
};
|
||||
|
||||
} // namespace dev
|
||||
|
||||
using dev::TftFbdevDrv;
|
||||
extern dev::TftFbdevDrv haspTft;
|
||||
|
||||
#endif // HASP_TARGET_PC
|
||||
|
||||
#endif // HASP_FBDEV_DRIVER_H
|
@ -1,7 +1,7 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if USE_MONITOR && HASP_TARGET_PC
|
||||
|
||||
#include "hasplib.h"
|
||||
#include "lvgl.h"
|
||||
@ -75,6 +75,10 @@ void TftSdl::init(int32_t w, int h)
|
||||
* You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
|
||||
* Create an SDL thread to do this*/
|
||||
SDL_CreateThread(tick_thread, "tick", NULL);
|
||||
|
||||
#if HASP_USE_LVGL_TASK
|
||||
#error "SDL2 LVGL task is not implemented"
|
||||
#endif
|
||||
}
|
||||
void TftSdl::show_info()
|
||||
{
|
||||
@ -115,4 +119,4 @@ const char* TftSdl::get_tft_model()
|
||||
|
||||
dev::TftSdl haspTft;
|
||||
|
||||
#endif // WINDOWS || POSIX
|
||||
#endif // WINDOWS || POSIX
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "tft_driver.h"
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if USE_MONITOR && HASP_TARGET_PC
|
||||
// #warning Building H driver TFT SDL2
|
||||
|
||||
#include "lvgl.h"
|
||||
@ -40,6 +40,6 @@ class TftSdl : BaseTft {
|
||||
using dev::TftSdl;
|
||||
extern dev::TftSdl haspTft;
|
||||
|
||||
#endif // defined(WINDOWS) || defined(POSIX)
|
||||
#endif // HASP_TARGET_PC
|
||||
|
||||
#endif // HASP_SDL2_DRIVER_H
|
||||
|
149
src/drv/tft/tft_driver_win32drv.cpp
Normal file
149
src/drv/tft/tft_driver_win32drv.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#if USE_WIN32DRV && HASP_TARGET_PC
|
||||
|
||||
#include "hasplib.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "win32drv/win32drv.h"
|
||||
|
||||
#include "drv/tft/tft_driver.h"
|
||||
#include "tft_driver_win32drv.h"
|
||||
|
||||
#include "dev/device.h"
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_gui.h"
|
||||
|
||||
#ifdef HASP_CUSTOMIZE_BOOTLOGO
|
||||
#include "custom/bootlogo.h" // Sketch tab header for xbm images
|
||||
#else
|
||||
#include "custom/bootlogo_template.h" // Sketch tab header for xbm images
|
||||
#endif
|
||||
|
||||
namespace dev {
|
||||
|
||||
/**
|
||||
* A task to measure the elapsed time for LittlevGL
|
||||
* @param data unused
|
||||
* @return never return
|
||||
*/
|
||||
static DWORD tick_thread(void* data)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
while(1) {
|
||||
Sleep(5); /*Sleep for 5 millisecond*/
|
||||
lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t TftWin32Drv::width()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
int32_t TftWin32Drv::height()
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
static void win32_message_loop(lv_task_t* param)
|
||||
{
|
||||
MSG Message;
|
||||
#if HASP_USE_LVGL_TASK
|
||||
while(haspDevice.pc_is_running && GetMessageW(&Message, NULL, 0, 0)) {
|
||||
TranslateMessage(&Message);
|
||||
DispatchMessageW(&Message);
|
||||
}
|
||||
// apparently GetMessageW doesn't deliver WM_QUIT
|
||||
haspDevice.pc_is_running = false;
|
||||
#else
|
||||
BOOL Result = PeekMessageW(&Message, NULL, 0, 0, TRUE);
|
||||
if(Result != 0 && Result != -1) {
|
||||
TranslateMessage(&Message);
|
||||
DispatchMessageW(&Message);
|
||||
if(Message.message == WM_QUIT) haspDevice.pc_is_running = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static DWORD gui_entrypoint(HANDLE semaphore)
|
||||
{
|
||||
/* Add a display
|
||||
* Use the 'win32drv' driver which creates window on PC's monitor to simulate a display
|
||||
* The following input devices are handled: mouse, keyboard, mousewheel */
|
||||
lv_win32_init(0, SW_SHOWNORMAL, haspTft.width(), haspTft.height(), 0);
|
||||
lv_win32_set_title(haspDevice.get_hostname());
|
||||
|
||||
#if HASP_USE_LVGL_TASK
|
||||
// let the init() function continue
|
||||
ReleaseSemaphore(semaphore, 1, NULL);
|
||||
// run the LVGL task as a thread
|
||||
HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)gui_task, NULL, 0, NULL);
|
||||
// run a blocking message loop on this thread
|
||||
win32_message_loop(NULL);
|
||||
// wait for the LVGL task now
|
||||
WaitForSingleObject(thread, 4000);
|
||||
#else
|
||||
// create a LVGL tick thread
|
||||
CreateThread(NULL, 0, tick_thread, NULL, 0, NULL);
|
||||
// create a LVGL task for the message loop
|
||||
lv_task_create(win32_message_loop, 5, LV_TASK_PRIO_HIGHEST, NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TftWin32Drv::init(int32_t w, int h)
|
||||
{
|
||||
_width = w;
|
||||
_height = h;
|
||||
|
||||
#if HASP_USE_LVGL_TASK
|
||||
// run a thread for creating the window and running the message loop
|
||||
HANDLE semaphore = CreateSemaphore(NULL, 0, 1, NULL);
|
||||
HANDLE thread = CreateThread(NULL, 0, gui_entrypoint, semaphore, 0, NULL);
|
||||
WaitForSingleObject(semaphore, INFINITE);
|
||||
#else
|
||||
// do not use the gui_task(), just init the GUI and return
|
||||
gui_entrypoint(NULL);
|
||||
#endif
|
||||
}
|
||||
void TftWin32Drv::show_info()
|
||||
{
|
||||
splashscreen();
|
||||
|
||||
LOG_VERBOSE(TAG_TFT, F("Driver : %s"), get_tft_model());
|
||||
}
|
||||
|
||||
void TftWin32Drv::splashscreen()
|
||||
{
|
||||
uint8_t fg[] = logoFgColor;
|
||||
uint8_t bg[] = logoBgColor;
|
||||
lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]);
|
||||
lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]);
|
||||
lv_win32_splashscreen(logoImage, logoWidth, logoHeight, lv_color_to32(fgColor), lv_color_to32(bgColor));
|
||||
}
|
||||
void TftWin32Drv::set_rotation(uint8_t rotation)
|
||||
{}
|
||||
void TftWin32Drv::set_invert(bool invert)
|
||||
{}
|
||||
void TftWin32Drv::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
|
||||
{
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
bool TftWin32Drv::is_driver_pin(uint8_t pin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const char* TftWin32Drv::get_tft_model()
|
||||
{
|
||||
return "Win32Drv";
|
||||
}
|
||||
|
||||
} // namespace dev
|
||||
|
||||
dev::TftWin32Drv haspTft;
|
||||
|
||||
#endif // WINDOWS || POSIX
|
44
src/drv/tft/tft_driver_win32drv.h
Normal file
44
src/drv/tft/tft_driver_win32drv.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#ifndef HASP_WIN32DRV_DRIVER_H
|
||||
#define HASP_WIN32DRV_DRIVER_H
|
||||
|
||||
#include "tft_driver.h"
|
||||
|
||||
#if USE_WIN32DRV && HASP_TARGET_PC
|
||||
// #warning Building H driver WIN32DRV
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
namespace dev {
|
||||
|
||||
class TftWin32Drv : BaseTft {
|
||||
public:
|
||||
void init(int w, int h);
|
||||
void show_info();
|
||||
void splashscreen();
|
||||
|
||||
void set_rotation(uint8_t rotation);
|
||||
void set_invert(bool invert);
|
||||
|
||||
void flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
|
||||
bool is_driver_pin(uint8_t pin);
|
||||
|
||||
const char* get_tft_model();
|
||||
|
||||
int32_t width();
|
||||
int32_t height();
|
||||
|
||||
private:
|
||||
int32_t _width, _height;
|
||||
};
|
||||
|
||||
} // namespace dev
|
||||
|
||||
using dev::TftWin32Drv;
|
||||
extern dev::TftWin32Drv haspTft;
|
||||
|
||||
#endif // HASP_TARGET_PC
|
||||
|
||||
#endif // HASP_WIN32DRV_DRIVER_H
|
@ -11,7 +11,7 @@
|
||||
#include "ArduinoLog.h"
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "../hasp_debug.h"
|
||||
#include "hasp_gui.h" // for screenshot
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@ -496,10 +496,12 @@ void dispatch_config(const char* topic, const char* payload, uint8_t source)
|
||||
}
|
||||
|
||||
if(strcasecmp_P(topic, PSTR("debug")) == 0) {
|
||||
#if HASP_TARGET_ARDUINO
|
||||
if(update)
|
||||
debugSetConfig(settings);
|
||||
else
|
||||
debugGetConfig(settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(strcasecmp_P(topic, PSTR("gui")) == 0) {
|
||||
@ -770,7 +772,7 @@ void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id)
|
||||
void dispatch_parse_jsonl(const char*, const char* payload, uint8_t source)
|
||||
{
|
||||
if(source != TAG_MQTT) saved_jsonl_page = haspPages.get();
|
||||
#if HASP_USE_CONFIG > 0
|
||||
#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO
|
||||
CharStream stream((char*)payload);
|
||||
// stream.setTimeout(10);
|
||||
dispatch_parse_jsonl(stream, saved_jsonl_page);
|
||||
@ -840,7 +842,11 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
|
||||
path[0] = '.';
|
||||
path[1] = '\0';
|
||||
strcat(path, filename);
|
||||
#if defined(WINDOWS)
|
||||
path[1] = '\\';
|
||||
#elif defined(POSIX)
|
||||
path[1] = '/';
|
||||
#endif
|
||||
|
||||
LOG_TRACE(TAG_HASP, F("Loading %s from disk..."), path);
|
||||
std::ifstream f(path); // taking file as inputstream
|
||||
@ -858,6 +864,48 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HASP_TARGET_PC
|
||||
static void shell_command_thread(char* cmdline)
|
||||
{
|
||||
// run the command
|
||||
FILE* pipe = popen(cmdline, "r");
|
||||
// free the string duplicated previously
|
||||
free(cmdline);
|
||||
if(!pipe) {
|
||||
LOG_ERROR(TAG_MSGR, F("Couldn't execute system command"));
|
||||
return;
|
||||
}
|
||||
// read each line, up to 1023 chars long
|
||||
char command[1024];
|
||||
while(fgets(command, sizeof(command), pipe) != NULL) {
|
||||
// strip newline character
|
||||
char* temp = command;
|
||||
while(*temp) {
|
||||
if(*temp == '\r' || *temp == '\n') {
|
||||
*temp = '\0';
|
||||
break;
|
||||
}
|
||||
temp++;
|
||||
}
|
||||
// run the command
|
||||
LOG_INFO(TAG_MSGR, F("Running '%s'"), command);
|
||||
dispatch_text_line(command, TAG_MSGR);
|
||||
}
|
||||
// close the pipe, check return code
|
||||
int status_code = pclose(pipe);
|
||||
if(status_code) {
|
||||
LOG_ERROR(TAG_MSGR, F("Process exited with non-zero return code %d"), status_code);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatch_shell_execute(const char*, const char* payload, uint8_t source)
|
||||
{
|
||||
// must duplicate the string for thread's own usage
|
||||
char* command = strdup(payload);
|
||||
haspDevice.run_thread((void (*)(void*))shell_command_thread, (void*)command);
|
||||
}
|
||||
#endif
|
||||
|
||||
void dispatch_current_page()
|
||||
{
|
||||
char topic[8];
|
||||
@ -941,7 +989,14 @@ void dispatch_page(const char*, const char* payload, uint8_t source)
|
||||
void dispatch_clear_page(const char*, const char* page, uint8_t source)
|
||||
{
|
||||
if(!strcasecmp(page, "all")) {
|
||||
#if !HASP_TARGET_PC
|
||||
hasp_init();
|
||||
#else
|
||||
// workaround for "clearpage all" deadlocking or crashing on PC build (when called from non-LVGL thread)
|
||||
for(uint8_t pageid = 0; pageid <= HASP_NUM_PAGES; pageid++) {
|
||||
haspPages.clear(pageid);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1155,7 +1210,7 @@ void dispatch_reboot(bool saveConfig)
|
||||
LOG_VERBOSE(TAG_MSGR, F("-------------------------------------"));
|
||||
LOG_TRACE(TAG_MSGR, F(D_DISPATCH_REBOOT));
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
fflush(stdout);
|
||||
#else
|
||||
Serial.flush();
|
||||
@ -1259,7 +1314,7 @@ void dispatch_send_discovery(const char*, const char*, uint8_t source)
|
||||
#if HASP_USE_HTTP > 0
|
||||
network_get_ipaddress(buffer, sizeof(buffer));
|
||||
doc[F("uri")] = String(F("http://")) + String(buffer);
|
||||
#elif defined(WINDOWS) || defined(POSIX)
|
||||
#elif HASP_TARGET_PC
|
||||
doc[F("uri")] = "http://google.pt";
|
||||
#endif
|
||||
|
||||
@ -1396,7 +1451,7 @@ void dispatch_idle_state(uint8_t state)
|
||||
{
|
||||
char topic[8];
|
||||
char buffer[8];
|
||||
memcpy_P(topic, PSTR("idle"), 8);
|
||||
memcpy_P(topic, PSTR("idle"), 5);
|
||||
hasp_get_sleep_payload(state, buffer);
|
||||
dispatch_state_subtopic(topic, buffer);
|
||||
}
|
||||
@ -1531,6 +1586,9 @@ void dispatchSetup()
|
||||
dispatch_add_command(PSTR("sensors"), dispatch_send_sensordata);
|
||||
dispatch_add_command(PSTR("theme"), dispatch_theme);
|
||||
dispatch_add_command(PSTR("run"), dispatch_run_script);
|
||||
#if HASP_TARGET_PC
|
||||
dispatch_add_command(PSTR("shell"), dispatch_shell_execute);
|
||||
#endif
|
||||
dispatch_add_command(PSTR("service"), dispatch_service);
|
||||
dispatch_add_command(PSTR("antiburn"), dispatch_antiburn);
|
||||
dispatch_add_command(PSTR("calibrate"), dispatch_calibrate);
|
||||
@ -1552,7 +1610,7 @@ void dispatchSetup()
|
||||
dispatch_add_command(PSTR("unzip"), filesystemUnzip);
|
||||
#endif
|
||||
#endif
|
||||
#if HASP_USE_CONFIG > 0
|
||||
#if HASP_USE_CONFIG > 0 && HASP_TARGET_ARDUINO
|
||||
dispatch_add_command(PSTR("setupap"), oobeFakeSetup);
|
||||
#endif
|
||||
/* WARNING: remember to expand the commands array when adding new commands */
|
||||
|
@ -176,9 +176,9 @@ void event_timer_clock(lv_task_t* task)
|
||||
timeval curTime;
|
||||
int rslt = gettimeofday(&curTime, NULL);
|
||||
(void)rslt; // unused
|
||||
time_t seconds = curTime.tv_sec;
|
||||
useconds_t tv_msec = curTime.tv_usec / 1000;
|
||||
tm* timeinfo = localtime(&seconds);
|
||||
time_t seconds = curTime.tv_sec;
|
||||
auto tv_msec = curTime.tv_usec / 1000;
|
||||
tm* timeinfo = localtime(&seconds);
|
||||
lv_task_set_period(task, data->interval - tv_msec);
|
||||
|
||||
char buffer[128] = {0};
|
||||
@ -835,7 +835,7 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
if(!translate_event(obj, event, hasp_event_id) || event == LV_EVENT_VALUE_CHANGED) return;
|
||||
|
||||
/* Get the new value */
|
||||
lv_color_t color = lv_cpicker_get_color(obj);
|
||||
lv_color_t color = lv_cpicker_get_color(obj);
|
||||
lv_cpicker_color_mode_t mode = lv_cpicker_get_color_mode(obj);
|
||||
|
||||
if(hasp_event_id == HASP_EVENT_CHANGED && last_color_sent.full == color.full) return; // same value as before
|
||||
@ -853,12 +853,16 @@ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
|
||||
if(const char* tag = my_obj_get_tag(obj))
|
||||
snprintf_P(data, sizeof(data),
|
||||
PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%d,\"v\":%d,\"tag\":%s}"),
|
||||
eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h, hsv.s, hsv.v, tag);
|
||||
PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
|
||||
"d,\"v\":%d,\"tag\":%s}"),
|
||||
eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
|
||||
hsv.s, hsv.v, tag);
|
||||
else
|
||||
snprintf_P(data, sizeof(data),
|
||||
PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%d,\"v\":%d}"), eventname,
|
||||
c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h, hsv.s, hsv.v);
|
||||
PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d,\"h\":%d,\"s\":%"
|
||||
"d,\"v\":%d}"),
|
||||
eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue, hsv.h,
|
||||
hsv.s, hsv.v);
|
||||
}
|
||||
event_send_object_data(obj, data);
|
||||
|
||||
@ -907,4 +911,4 @@ void calendar_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
|
||||
// event_update_group(obj->user_data.groupid, obj, val, min, max);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -68,7 +68,7 @@ void font_setup()
|
||||
} else {
|
||||
LOG_ERROR(TAG_FONT, F("FreeType " D_SERVICE_START_FAILED));
|
||||
}
|
||||
#elif defined(WINDOWS) || defined(POSIX)
|
||||
#elif HASP_TARGET_PC
|
||||
#else
|
||||
#endif
|
||||
|
||||
|
@ -179,7 +179,7 @@ int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX) || defined(ESP32)
|
||||
#if HASP_TARGET_PC || defined(ESP32)
|
||||
std::string v;
|
||||
v.reserve(64);
|
||||
|
||||
|
@ -244,7 +244,11 @@ void Page::load_jsonl(const char* pagesfile)
|
||||
path[0] = '.';
|
||||
path[1] = '\0';
|
||||
strcat(path, pagesfile);
|
||||
#if defined(WINDOWS)
|
||||
path[1] = '\\';
|
||||
#elif defined(POSIX)
|
||||
path[1] = '/';
|
||||
#endif
|
||||
|
||||
LOG_TRACE(TAG_HASP, F("Loading %s from disk..."), path);
|
||||
std::ifstream f(path); // taking file as inputstream
|
||||
|
@ -136,34 +136,34 @@ void Parser::get_event_name(uint8_t eventid, char* buffer, size_t size)
|
||||
{
|
||||
switch(eventid) {
|
||||
case HASP_EVENT_ON:
|
||||
memcpy_P(buffer, PSTR("on"), size);
|
||||
memcpy_P(buffer, PSTR("on"), 3);
|
||||
break;
|
||||
case HASP_EVENT_OFF:
|
||||
memcpy_P(buffer, PSTR("off"), size);
|
||||
memcpy_P(buffer, PSTR("off"), 4);
|
||||
break;
|
||||
case HASP_EVENT_UP:
|
||||
memcpy_P(buffer, PSTR("up"), size);
|
||||
memcpy_P(buffer, PSTR("up"), 3);
|
||||
break;
|
||||
case HASP_EVENT_DOWN:
|
||||
memcpy_P(buffer, PSTR("down"), size);
|
||||
memcpy_P(buffer, PSTR("down"), 5);
|
||||
break;
|
||||
case HASP_EVENT_RELEASE:
|
||||
memcpy_P(buffer, PSTR("release"), size);
|
||||
memcpy_P(buffer, PSTR("release"), 8);
|
||||
break;
|
||||
case HASP_EVENT_LONG:
|
||||
memcpy_P(buffer, PSTR("long"), size);
|
||||
memcpy_P(buffer, PSTR("long"), 5);
|
||||
break;
|
||||
case HASP_EVENT_HOLD:
|
||||
memcpy_P(buffer, PSTR("hold"), size);
|
||||
memcpy_P(buffer, PSTR("hold"), 5);
|
||||
break;
|
||||
case HASP_EVENT_LOST:
|
||||
memcpy_P(buffer, PSTR("lost"), size);
|
||||
memcpy_P(buffer, PSTR("lost"), 5);
|
||||
break;
|
||||
case HASP_EVENT_CHANGED:
|
||||
memcpy_P(buffer, PSTR("changed"), size);
|
||||
memcpy_P(buffer, PSTR("changed"), 8);
|
||||
break;
|
||||
default:
|
||||
memcpy_P(buffer, PSTR("unknown"), size);
|
||||
memcpy_P(buffer, PSTR("unknown"), 8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,4 +238,4 @@ long map(long x, long in_min, long in_max, long out_min, long out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -8,7 +8,9 @@
|
||||
#include "hasp_config.h"
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_gui.h"
|
||||
#if HASP_TARGET_ARDUINO
|
||||
#include "hal/hasp_hal.h"
|
||||
#endif
|
||||
|
||||
// #include "hasp_ota.h" included in conf
|
||||
// #include "hasp_filesystem.h" included in conf
|
||||
@ -21,7 +23,9 @@
|
||||
#include "EEPROM.h"
|
||||
#endif
|
||||
|
||||
#if HASP_USE_EEPROM > 0
|
||||
#include "StreamUtils.h" // For EEPromStream
|
||||
#endif
|
||||
|
||||
extern uint16_t dispatchTelePeriod;
|
||||
extern uint32_t dispatchLastMillis;
|
||||
@ -29,6 +33,7 @@ extern uint32_t dispatchLastMillis;
|
||||
extern gui_conf_t gui_settings;
|
||||
extern dispatch_conf_t dispatch_settings;
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
void confDebugSet(const __FlashStringHelper* fstr_name)
|
||||
{
|
||||
/*char buffer[128];
|
||||
@ -36,6 +41,7 @@ void confDebugSet(const __FlashStringHelper* fstr_name)
|
||||
debugPrintln(buffer);*/
|
||||
LOG_VERBOSE(TAG_CONF, F(D_BULLET "%S set"), fstr_name);
|
||||
}
|
||||
#endif
|
||||
void confDebugSet(const char* fstr_name)
|
||||
{
|
||||
/*char buffer[128];
|
||||
@ -44,6 +50,7 @@ void confDebugSet(const char* fstr_name)
|
||||
LOG_VERBOSE(TAG_CONF, F(D_BULLET "%s set"), fstr_name);
|
||||
}
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name)
|
||||
{
|
||||
if(!setting.isNull()) {
|
||||
@ -130,6 +137,7 @@ bool configSet(char *value, size_t size, const JsonVariant& setting, const __Fla
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name)
|
||||
{
|
||||
@ -207,7 +215,9 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n
|
||||
|
||||
void configSetupDebug(JsonDocument& settings)
|
||||
{
|
||||
#if HASP_TARGET_ARDUINO
|
||||
debugSetup(settings[FPSTR(FP_DEBUG)]);
|
||||
#endif
|
||||
debugStart(); // Debug started, now we can use it; HASP header sent
|
||||
}
|
||||
|
||||
@ -239,9 +249,9 @@ void configMaskPasswords(JsonDocument& settings)
|
||||
|
||||
DeserializationError configParseFile(String& configFile, JsonDocument& settings)
|
||||
{
|
||||
DeserializationError result = DeserializationError::InvalidInput;
|
||||
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
|
||||
File file = HASP_FS.open(configFile, "r");
|
||||
DeserializationError result;
|
||||
|
||||
if(file) {
|
||||
// size_t size = file.size();
|
||||
@ -254,30 +264,50 @@ DeserializationError configParseFile(String& configFile, JsonDocument& settings)
|
||||
return result;
|
||||
}
|
||||
return DeserializationError::InvalidInput;
|
||||
#elif HASP_TARGET_PC
|
||||
lv_fs_file_t f;
|
||||
lv_fs_res_t res;
|
||||
lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
|
||||
if(res == LV_FS_RES_OK) {
|
||||
uint32_t size = 0, read = 0;
|
||||
if(lv_fs_size(&f, &size) == LV_FS_RES_OK && size != 0) {
|
||||
char* buf = (char*)malloc(size + 1);
|
||||
if(lv_fs_read(&f, buf, size, &read) == LV_FS_RES_OK && read == size) {
|
||||
result = deserializeJson(settings, buf);
|
||||
}
|
||||
}
|
||||
lv_fs_close(&f);
|
||||
return result;
|
||||
}
|
||||
LOG_ERROR(TAG_HASP, F("Opening config.json from FS failed %d"), res);
|
||||
return result;
|
||||
#else
|
||||
return DeserializationError::InvalidInput;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
DeserializationError configRead(JsonDocument& settings, bool setupdebug)
|
||||
{
|
||||
String configFile((char*)0);
|
||||
String configFile;
|
||||
configFile.reserve(32);
|
||||
configFile = String(FPSTR(FP_HASP_CONFIG_FILE));
|
||||
DeserializationError error;
|
||||
|
||||
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
|
||||
if(setupdebug) configSetupDebug(settings); // Now we can use log
|
||||
|
||||
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 || HASP_TARGET_PC
|
||||
error = configParseFile(configFile, settings);
|
||||
if(!error) {
|
||||
String output, wifiPass, mqttPass, httpPass, wgPrivKey;
|
||||
|
||||
/* Load Debug params */
|
||||
if(setupdebug) {
|
||||
configSetupDebug(settings); // Now we can use log
|
||||
LOG_INFO(TAG_CONF, F("SPI flash FS mounted"));
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
filesystemInfo();
|
||||
filesystemList();
|
||||
#endif
|
||||
}
|
||||
|
||||
LOG_TRACE(TAG_CONF, F(D_FILE_LOADING), configFile.c_str());
|
||||
@ -304,9 +334,6 @@ DeserializationError configRead(JsonDocument& settings, bool setupdebug)
|
||||
|
||||
#endif
|
||||
|
||||
// File does not exist or error reading file
|
||||
if(setupdebug) configSetupDebug(settings); // Now we can use log
|
||||
|
||||
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
|
||||
LOG_ERROR(TAG_CONF, F(D_FILE_LOAD_FAILED), configFile.c_str());
|
||||
#endif
|
||||
@ -360,11 +387,11 @@ void configBackupToEeprom()
|
||||
*/
|
||||
void configWrite()
|
||||
{
|
||||
String configFile((char*)0);
|
||||
String configFile;
|
||||
configFile.reserve(32);
|
||||
configFile = String(FPSTR(FP_HASP_CONFIG_FILE));
|
||||
|
||||
String settingsChanged((char*)0);
|
||||
String settingsChanged;
|
||||
settingsChanged.reserve(128);
|
||||
settingsChanged = F(D_CONFIG_CHANGED);
|
||||
|
||||
@ -462,6 +489,7 @@ void configWrite()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
module = FPSTR(FP_DEBUG);
|
||||
if(settings[module].as<JsonObject>().isNull()) settings.createNestedObject(module);
|
||||
changed = debugGetConfig(settings[module]);
|
||||
@ -470,6 +498,7 @@ void configWrite()
|
||||
configOutput(settings[module], TAG_DEBG);
|
||||
writefile = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(settings[FPSTR(FP_GUI)].as<JsonObject>().isNull()) settings.createNestedObject(FPSTR(FP_GUI));
|
||||
changed = guiGetConfig(settings[FPSTR(FP_GUI)]);
|
||||
@ -561,9 +590,10 @@ void configSetup()
|
||||
configRead(settings, true);
|
||||
}
|
||||
|
||||
// #if HASP_USE_SPIFFS > 0
|
||||
#if HASP_TARGET_ARDUINO
|
||||
LOG_INFO(TAG_DEBG, F("Loading debug settings"));
|
||||
debugSetConfig(settings[FPSTR(FP_DEBUG)]);
|
||||
#endif
|
||||
LOG_INFO(TAG_GPIO, F("Loading GUI settings"));
|
||||
guiSetConfig(settings[FPSTR(FP_GUI)]);
|
||||
LOG_INFO(TAG_HASP, F("Loading HASP settings"));
|
||||
@ -605,6 +635,12 @@ void configSetup()
|
||||
gpioSetConfig(settings[FPSTR(FP_GPIO)]);
|
||||
#endif
|
||||
|
||||
// target-specific config
|
||||
#if defined(POSIX)
|
||||
LOG_INFO(TAG_CONF, F("Loading POSIX-specific settings"));
|
||||
haspDevice.set_config(settings[F("posix")]);
|
||||
#endif
|
||||
|
||||
LOG_INFO(TAG_CONF, F(D_CONFIG_LOADED));
|
||||
}
|
||||
// #endif
|
||||
@ -615,15 +651,15 @@ void configLoop(void)
|
||||
|
||||
void configOutput(const JsonObject& settings, uint8_t tag)
|
||||
{
|
||||
String output((char*)0);
|
||||
String output;
|
||||
output.reserve(128);
|
||||
serializeJson(settings, output);
|
||||
|
||||
String passmask((char*)0);
|
||||
String passmask;
|
||||
passmask.reserve(128);
|
||||
passmask = F("\"pass\":\"" D_PASSWORD_MASK "\"");
|
||||
|
||||
String password((char*)0);
|
||||
String password;
|
||||
password.reserve(128);
|
||||
|
||||
String pass = F("pass");
|
||||
@ -631,28 +667,48 @@ void configOutput(const JsonObject& settings, uint8_t tag)
|
||||
password = F("\"pass\":\"");
|
||||
password += settings[pass].as<String>();
|
||||
password += F("\"");
|
||||
#if HASP_TARGET_ARDUINO
|
||||
output.replace(password, passmask);
|
||||
#elif HASP_TARGET_PC
|
||||
size_t pos = 0;
|
||||
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_WIFI)][pass].isNull()) {
|
||||
password = F("\"pass\":\"");
|
||||
password += settings[FPSTR(FP_WIFI)][pass].as<String>();
|
||||
password += F("\"");
|
||||
#if HASP_TARGET_ARDUINO
|
||||
output.replace(password, passmask);
|
||||
#elif HASP_TARGET_PC
|
||||
size_t pos = 0;
|
||||
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_MQTT)][pass].isNull()) {
|
||||
password = F("\"pass\":\"");
|
||||
password += settings[FPSTR(FP_MQTT)][pass].as<String>();
|
||||
password += F("\"");
|
||||
#if HASP_TARGET_ARDUINO
|
||||
output.replace(password, passmask);
|
||||
#elif HASP_TARGET_PC
|
||||
size_t pos = 0;
|
||||
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_HTTP)][pass].isNull()) {
|
||||
password = F("\"pass\":\"");
|
||||
password += settings[FPSTR(FP_HTTP)][pass].as<String>();
|
||||
password += F("\"");
|
||||
#if HASP_TARGET_ARDUINO
|
||||
output.replace(password, passmask);
|
||||
#elif HASP_TARGET_PC
|
||||
size_t pos = 0;
|
||||
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].isNull()) {
|
||||
@ -660,7 +716,12 @@ void configOutput(const JsonObject& settings, uint8_t tag)
|
||||
password += settings[FPSTR(FP_WG)][FPSTR(FP_CONFIG_PRIVATE_KEY)].as<String>();
|
||||
password += F("\"");
|
||||
passmask = F("\"privkey\":\"" D_PASSWORD_MASK "\"");
|
||||
#if HASP_TARGET_ARDUINO
|
||||
output.replace(password, passmask);
|
||||
#elif HASP_TARGET_PC
|
||||
size_t pos = 0;
|
||||
if((pos = output.find(password)) != std::string::npos) output.replace(pos, password.size(), passmask);
|
||||
#endif
|
||||
}
|
||||
|
||||
LOG_VERBOSE(tag, output.c_str());
|
||||
@ -688,4 +749,4 @@ bool configClearEeprom()
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_USE_CONFIG
|
||||
#endif // HAS_USE_CONFIG
|
||||
|
@ -25,13 +25,15 @@ void configOutput(const JsonObject& settings, uint8_t tag);
|
||||
bool configClearEeprom(void);
|
||||
|
||||
/* ===== Getter and Setter Functions ===== */
|
||||
#if HASP_TARGET_ARDUINO
|
||||
bool configSet(bool& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(int8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(uint8_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(uint16_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(int32_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(lv_color_t& value, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(char *value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
bool configSet(char* value, size_t size, const JsonVariant& setting, const __FlashStringHelper* fstr_name);
|
||||
#endif
|
||||
bool configSet(bool& value, const JsonVariant& setting, const char* fstr_name);
|
||||
bool configSet(int8_t& value, const JsonVariant& setting, const char* fstr_name);
|
||||
bool configSet(uint8_t& value, const JsonVariant& setting, const char* fstr_name);
|
||||
@ -41,8 +43,10 @@ bool configSet(lv_color_t& value, const JsonVariant& setting, const char* fstr_n
|
||||
void configMaskPasswords(JsonDocument& settings);
|
||||
|
||||
/* ===== Read/Write Configuration ===== */
|
||||
#if HASP_TARGET_ARDUINO
|
||||
void configSetConfig(JsonObject& settings);
|
||||
void configGetConfig(JsonDocument& settings);
|
||||
#endif
|
||||
|
||||
/* json keys used in the configfile */
|
||||
const char FP_CONFIG_STARTPAGE[] PROGMEM = "startpage";
|
||||
@ -107,4 +111,4 @@ const char FP_OTA[] PROGMEM = "ota";
|
||||
|
||||
#endif
|
||||
|
||||
#endif // HASP_USE_CONFIG
|
||||
#endif // HASP_USE_CONFIG
|
||||
|
@ -8,12 +8,12 @@
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_macro.h"
|
||||
|
||||
#if(!defined(WINDOWS)) && (!defined(POSIX))
|
||||
#if HASP_TARGET_ARDUINO
|
||||
|
||||
#define debug_print(io, ...) io->printf(__VA_ARGS__)
|
||||
#define debug_newline(io) io->println()
|
||||
|
||||
#else
|
||||
#elif HASP_TARGET_PC
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
@ -21,6 +21,18 @@
|
||||
#define debug_print(io, ...) fprintf(stdout, __VA_ARGS__)
|
||||
#define debug_newline(io) fprintf(stdout, "\n")
|
||||
|
||||
#if defined(WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#define cwd _getcwd
|
||||
#endif
|
||||
|
||||
#if defined(POSIX)
|
||||
#include <unistd.h>
|
||||
#include <linux/limits.h>
|
||||
#define cwd getcwd
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
bool debugAnsiCodes = false;
|
||||
@ -99,7 +111,7 @@ static inline void debug_flush()
|
||||
HASP_SERIAL.flush();
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
@ -116,22 +128,22 @@ void debugEverySecond()
|
||||
void debugStart(void)
|
||||
{
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
debug_newline();
|
||||
debugPrintHaspHeader(NULL);
|
||||
debug_newline();
|
||||
|
||||
char curdir[PATH_MAX];
|
||||
LOG_INFO(TAG_DEBG, F("Configuration directory: %s"), cwd(curdir, sizeof(curdir)));
|
||||
LOG_INFO(TAG_DEBG, F("Environment: " PIOENV));
|
||||
LOG_INFO(TAG_DEBG, F("Console started"));
|
||||
|
||||
debug_flush();
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if HASP_USE_CONSOLE > 0
|
||||
consoleSetup();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void debugStop()
|
||||
@ -445,4 +457,4 @@ void debugPrintPrefix(uint8_t tag, int level, Print* _logOutput)
|
||||
#else
|
||||
debug_print(_logOutput, PSTR(" %s: "), buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "lang/lang.h"
|
||||
|
||||
#if(!defined(WINDOWS)) && (!defined(POSIX))
|
||||
#if HASP_TARGET_ARDUINO
|
||||
/* ===== Default Event Processors ===== */
|
||||
void debugSetup(JsonObject settings);
|
||||
|
||||
|
@ -207,21 +207,8 @@ static inline void gui_init_images()
|
||||
static inline void gui_init_filesystems()
|
||||
{
|
||||
#if LV_USE_FS_IF != 0
|
||||
//_lv_fs_init(); // lvgl File System -- not needed, it done in lv_init() when LV_USE_FILESYSTEM is set
|
||||
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_ENABLED));
|
||||
lv_fs_if_init(); // auxiliary file system drivers
|
||||
// filesystem_list_path("L:/");
|
||||
|
||||
lv_fs_file_t f;
|
||||
lv_fs_res_t res;
|
||||
res = lv_fs_open(&f, "L:/config.json", LV_FS_MODE_RD);
|
||||
if(res == LV_FS_RES_OK) {
|
||||
LOG_VERBOSE(TAG_HASP, F("TEST Opening config.json OK"));
|
||||
lv_fs_close(&f);
|
||||
} else {
|
||||
LOG_ERROR(TAG_HASP, F("TEST Opening config.json from FS failed %d"), res);
|
||||
}
|
||||
|
||||
#else
|
||||
LOG_VERBOSE(TAG_LVGL, F("Filesystem : " D_SETTING_DISABLED));
|
||||
#endif
|
||||
@ -305,17 +292,27 @@ void guiSetup()
|
||||
#endif
|
||||
disp_drv.monitor_cb = gui_monitor_cb;
|
||||
|
||||
// register a touchscreen/mouse driver - only on real hardware and SDL2
|
||||
// Win32 and POSIX handles input drivers in tft_driver
|
||||
#if TOUCH_DRIVER != -1 || USE_MONITOR
|
||||
/* Initialize the touch pad */
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if USE_MONITOR && HASP_TARGET_PC
|
||||
indev_drv.read_cb = mouse_read;
|
||||
#else
|
||||
indev_drv.read_cb = gui_touch_read;
|
||||
#endif
|
||||
lv_indev_t* mouse_indev = lv_indev_drv_register(&indev_drv);
|
||||
mouse_indev->driver.type = LV_INDEV_TYPE_POINTER;
|
||||
#else
|
||||
// find the first registered input device to add a cursor to
|
||||
lv_indev_t* mouse_indev = NULL;
|
||||
while((mouse_indev = lv_indev_get_next(mouse_indev))) {
|
||||
if(mouse_indev->driver.type == LV_INDEV_TYPE_POINTER) break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Set a cursor for the mouse*/
|
||||
LOG_TRACE(TAG_GUI, F("Initialize Cursor"));
|
||||
@ -336,16 +333,18 @@ void guiSetup()
|
||||
cursor = lv_img_create(mouse_layer, NULL); /*Create an image object for the cursor */
|
||||
lv_img_set_src(cursor, &mouse_cursor_icon); /*Set the image source*/
|
||||
#else
|
||||
cursor = lv_obj_create(mouse_layer, NULL); // show cursor object on every page
|
||||
cursor = lv_obj_create(mouse_layer, NULL); // show cursor object on every page
|
||||
lv_obj_set_size(cursor, 9, 9);
|
||||
lv_obj_set_style_local_radius(cursor, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_obj_set_style_local_bg_color(cursor, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
lv_obj_set_style_local_bg_opa(cursor, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
#endif
|
||||
gui_hide_pointer(false);
|
||||
lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
|
||||
if(mouse_indev != NULL) {
|
||||
lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
|
||||
}
|
||||
|
||||
#if !(defined(WINDOWS) || defined(POSIX))
|
||||
#if HASP_TARGET_ARDUINO
|
||||
// drv_touch_init(gui_settings.rotation); // Touch driver
|
||||
haspTouch.init(tft_width, tft_height);
|
||||
haspTouch.set_calibration(gui_settings.cal_data);
|
||||
@ -386,7 +385,7 @@ IRAM_ATTR void guiLoop(void)
|
||||
// tick.update();
|
||||
#endif
|
||||
|
||||
#if !(defined(WINDOWS) || defined(POSIX))
|
||||
#if HASP_TARGET_ARDUINO
|
||||
// haspTouch.loop();
|
||||
#endif
|
||||
}
|
||||
@ -396,23 +395,34 @@ void guiEverySecond(void)
|
||||
// nothing
|
||||
}
|
||||
|
||||
#if defined(ESP32) && defined(HASP_USE_ESP_MQTT)
|
||||
|
||||
#if HASP_USE_LVGL_TASK == 1
|
||||
static void gui_task(void* args)
|
||||
void gui_task(void* args)
|
||||
{
|
||||
LOG_TRACE(TAG_GUI, "Start to run LVGL");
|
||||
while(1) {
|
||||
while(haspDevice.pc_is_running) {
|
||||
// no idea what MQTT has to do with LVGL - the #if is copied from the code below
|
||||
#if defined(ESP32) && defined(HASP_USE_ESP_MQTT)
|
||||
/* Try to take the semaphore, call lvgl related function on success */
|
||||
// if(pdTRUE == xSemaphoreTake(xGuiSemaphore, pdMS_TO_TICKS(10))) {
|
||||
if(pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
|
||||
lv_task_handler();
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
}
|
||||
#else
|
||||
// optimize lv_task_handler() by actually using the returned delay value
|
||||
auto time_start = millis();
|
||||
uint32_t sleep_time = lv_task_handler();
|
||||
delay(sleep_time);
|
||||
auto time_end = millis();
|
||||
lv_tick_inc(time_end - time_start);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // HASP_USE_LVGL_TASK
|
||||
|
||||
#if defined(ESP32) && defined(HASP_USE_ESP_MQTT)
|
||||
|
||||
#if HASP_USE_LVGL_TASK == 1
|
||||
esp_err_t gui_setup_lvgl_task()
|
||||
{
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
|
@ -60,6 +60,11 @@ uint32_t guiScreenshotEtag();
|
||||
void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
|
||||
void gui_antiburn_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p);
|
||||
|
||||
/* ===== Main LVGL Task ===== */
|
||||
#if HASP_USE_LVGL_TASK == 1
|
||||
void gui_task(void* args);
|
||||
#endif
|
||||
|
||||
/* ===== Locks ===== */
|
||||
#ifdef ESP32
|
||||
IRAM_ATTR bool gui_acquire(TickType_t timeout);
|
||||
@ -73,4 +78,4 @@ bool guiGetConfig(const JsonObject& settings);
|
||||
bool guiSetConfig(const JsonObject& settings);
|
||||
#endif // HASP_USE_CONFIG
|
||||
|
||||
#endif // HASP_GUI_H
|
||||
#endif // HASP_GUI_H
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* MIT License - Copyright (c) 2019-2024 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#if !(defined(WINDOWS) || defined(POSIX))
|
||||
|
||||
/*
|
||||
#ifdef CORE_DEBUG_LEVEL
|
||||
#undef CORE_DEBUG_LEVEL
|
||||
@ -28,9 +26,9 @@
|
||||
#include "hasp_gui.h"
|
||||
#endif
|
||||
|
||||
bool isConnected;
|
||||
uint8_t mainLoopCounter = 0;
|
||||
unsigned long mainLastLoopTime = 0;
|
||||
static bool isConnected;
|
||||
static uint8_t mainLoopCounter = 0;
|
||||
static unsigned long mainLastLoopTime = 0;
|
||||
|
||||
#ifdef HASP_USE_STAT_COUNTER
|
||||
uint16_t statLoopCounter = 0; // measures the average looptime
|
||||
@ -40,11 +38,23 @@ void setup()
|
||||
{
|
||||
// hal_setup();
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
esp_log_level_set("*", ESP_LOG_NONE); // set all components to ERROR level
|
||||
// esp_log_level_set("wifi", ESP_LOG_NONE); // enable WARN logs from WiFi stack
|
||||
// esp_log_level_set("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
|
||||
// esp_log_level_set("esp_crt_bundle", ESP_LOG_VERBOSE); // enable WARN logs from WiFi stack
|
||||
// esp_log_level_set("esp_tls", ESP_LOG_VERBOSE); // enable WARN logs from WiFi stack
|
||||
#elif HASP_TARGET_PC
|
||||
// Initialize lvgl environment
|
||||
lv_init();
|
||||
lv_log_register_print_cb(debugLvglLogEvent);
|
||||
#if HASP_USE_CONFIG
|
||||
// initialize FS before running configSetup()
|
||||
// normally, it's initialized in guiSetup(), but Arduino doesn't need FS in configSetup()
|
||||
lv_fs_if_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
haspDevice.init();
|
||||
|
||||
/****************************
|
||||
@ -149,7 +159,7 @@ void setup()
|
||||
gui_setup_lvgl_task();
|
||||
#endif // HASP_USE_LVGL_TASK
|
||||
|
||||
mainLastLoopTime = -1000; // reset loop counter
|
||||
mainLastLoopTime = 0; // reset loop counter
|
||||
}
|
||||
|
||||
IRAM_ATTR void loop()
|
||||
@ -195,7 +205,7 @@ IRAM_ATTR void loop()
|
||||
|
||||
/* Timer Loop */
|
||||
if(millis() - mainLastLoopTime >= 1000) {
|
||||
mainLastLoopTime += 1000;
|
||||
mainLastLoopTime = millis();
|
||||
|
||||
/* Runs Every Second */
|
||||
haspEverySecond(); // sleep timer & statusupdate
|
||||
@ -237,10 +247,9 @@ IRAM_ATTR void loop()
|
||||
case 4:
|
||||
#if HASP_USE_WIFI > 0 || HASP_USE_ETHERNET > 0
|
||||
isConnected = networkEvery5Seconds(); // Check connection
|
||||
|
||||
#endif
|
||||
#if HASP_USE_MQTT > 0
|
||||
mqttEvery5Seconds(isConnected);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -270,5 +279,3 @@ IRAM_ATTR void loop()
|
||||
delay(2); // ms
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
226
src/main_pc.cpp
Normal file
226
src/main_pc.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#if HASP_TARGET_PC
|
||||
|
||||
#if defined(WINDOWS)
|
||||
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
// MSDN recommends against using getcwd & chdir names
|
||||
#define cwd _getcwd
|
||||
#define cd _chdir
|
||||
#endif
|
||||
|
||||
#if defined(POSIX)
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#define cwd getcwd
|
||||
#define cd chdir
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "hasplib.h"
|
||||
|
||||
#if USE_MONITOR
|
||||
#include "display/monitor.h"
|
||||
#endif
|
||||
|
||||
#include "hasp_debug.h"
|
||||
|
||||
// hasp_gui.cpp
|
||||
extern uint16_t tft_width;
|
||||
extern uint16_t tft_height;
|
||||
|
||||
// main.cpp
|
||||
extern void setup();
|
||||
extern void loop();
|
||||
|
||||
#if defined(WINDOWS)
|
||||
// https://gist.github.com/kingseva/a918ec66079a9475f19642ec31276a21
|
||||
void BindStdHandlesToConsole()
|
||||
{
|
||||
// TODO: Add Error checking.
|
||||
|
||||
// Redirect the CRT standard input, output, and error handles to the console
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
|
||||
// Note that there is no CONERR$ file
|
||||
HANDLE hStdout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE hStdin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
|
||||
SetStdHandle(STD_ERROR_HANDLE, hStdout);
|
||||
SetStdHandle(STD_INPUT_HANDLE, hStdin);
|
||||
|
||||
// Clear the error state for each of the C++ standard stream objects.
|
||||
std::wclog.clear();
|
||||
std::clog.clear();
|
||||
std::wcout.clear();
|
||||
std::cout.clear();
|
||||
std::wcerr.clear();
|
||||
std::cerr.clear();
|
||||
std::wcin.clear();
|
||||
std::cin.clear();
|
||||
}
|
||||
|
||||
void InitializeConsoleOutput()
|
||||
{
|
||||
bool isConsoleApp;
|
||||
|
||||
// How to check if the program is run from a console?
|
||||
// https://stackoverflow.com/questions/9009333/how-to-check-if-the-program-is-run-from-a-console
|
||||
HWND consoleWnd = GetConsoleWindow();
|
||||
DWORD dwProcessId;
|
||||
GetWindowThreadProcessId(consoleWnd, &dwProcessId);
|
||||
|
||||
if(GetCurrentProcessId() == dwProcessId) {
|
||||
isConsoleApp = true; // Opened in Console
|
||||
} else {
|
||||
isConsoleApp = false; // Opened in Windows
|
||||
}
|
||||
|
||||
// Use normal console that launched the program
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
// Test if the application was started from a Console Window
|
||||
if(!isConsoleApp) {
|
||||
// If started from Windows, use detached Log Console Window
|
||||
AllocConsole();
|
||||
}
|
||||
|
||||
// Redirect all standard output streams to the console
|
||||
BindStdHandlesToConsole();
|
||||
}
|
||||
#endif
|
||||
|
||||
void usage(const char* progName, const char* version)
|
||||
{
|
||||
std::cout << "\n"
|
||||
<< progName << " " << version << " [options]" << std::endl
|
||||
<< std::endl
|
||||
<< "Options:" << std::endl
|
||||
<< " -h | --help Print this help" << std::endl
|
||||
<< " -q | --quiet Suppress console output (can improve performance)" << std::endl
|
||||
#if !USE_FBDEV
|
||||
<< " -W | --width Width of the window" << std::endl
|
||||
<< " -H | --height Height of the window" << std::endl
|
||||
#endif
|
||||
<< " -c | --config Configuration/storage directory" << std::endl
|
||||
#if defined(WINDOWS)
|
||||
<< " (default: 'AppData\\hasp\\hasp')" << std::endl
|
||||
#elif defined(POSIX)
|
||||
<< " (default: '~/.local/share/hasp/hasp')" << std::endl
|
||||
#endif
|
||||
<< std::endl;
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
bool showhelp = false;
|
||||
bool console = true;
|
||||
char config[PATH_MAX] = {'\0'};
|
||||
|
||||
#if defined(WINDOWS)
|
||||
InitializeConsoleOutput();
|
||||
SetConsoleCP(65001); // 65001 = UTF-8
|
||||
#endif
|
||||
|
||||
for(int arg = 1; arg < argc; arg++) {
|
||||
if(strncmp(argv[arg], "--help", 6) == 0 || strncmp(argv[arg], "-h", 2) == 0) {
|
||||
showhelp = true;
|
||||
} else if(strncmp(argv[arg], "--quiet", 7) == 0 || strncmp(argv[arg], "-q", 2) == 0) {
|
||||
#if defined(WINDOWS)
|
||||
FreeConsole();
|
||||
#endif
|
||||
#if defined(POSIX)
|
||||
int nullfd = open("/dev/null", O_WRONLY);
|
||||
dup2(nullfd, 1);
|
||||
close(nullfd);
|
||||
#endif
|
||||
#if !USE_FBDEV
|
||||
} else if(strncmp(argv[arg], "--width", 7) == 0 || strncmp(argv[arg], "-W", 2) == 0) {
|
||||
if(arg + 1 < argc) {
|
||||
int w = atoi(argv[arg + 1]);
|
||||
if(w > 0) tft_width = w;
|
||||
arg++;
|
||||
} else {
|
||||
std::cout << "Missing width value" << std::endl;
|
||||
showhelp = true;
|
||||
}
|
||||
} else if(strncmp(argv[arg], "--height", 8) == 0 || strncmp(argv[arg], "-H", 2) == 0) {
|
||||
if(arg + 1 < argc) {
|
||||
int h = atoi(argv[arg + 1]);
|
||||
if(h > 0) tft_height = h;
|
||||
arg++;
|
||||
} else {
|
||||
std::cout << "Missing height value" << std::endl;
|
||||
showhelp = true;
|
||||
}
|
||||
#endif
|
||||
} else if(strncmp(argv[arg], "--config", 8) == 0 || strncmp(argv[arg], "-c", 2) == 0) {
|
||||
if(arg + 1 < argc) {
|
||||
strcpy(config, argv[arg + 1]);
|
||||
arg++;
|
||||
} else {
|
||||
std::cout << "Missing config directory" << std::endl;
|
||||
showhelp = true;
|
||||
}
|
||||
} else {
|
||||
std::cout << "Unrecognized command line parameter: " << argv[arg] << std::endl;
|
||||
showhelp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(showhelp) {
|
||||
usage("openHASP", haspDevice.get_version());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(config[0] == '\0') {
|
||||
#if USE_MONITOR
|
||||
SDL_Init(0); // Needs to be initialized for GetPerfPath
|
||||
strcpy(config, SDL_GetPrefPath("hasp", "hasp"));
|
||||
SDL_Quit(); // We'll properly init later
|
||||
#elif defined(WINDOWS)
|
||||
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, config))) {
|
||||
PathAppendA(config, "hasp");
|
||||
PathAppendA(config, "hasp");
|
||||
}
|
||||
#elif defined(POSIX)
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
strcpy(config, pw->pw_dir);
|
||||
strcat(config, "/.local/share/hasp/hasp");
|
||||
#endif
|
||||
}
|
||||
cd(config);
|
||||
|
||||
setup();
|
||||
while(haspDevice.pc_is_running) {
|
||||
loop();
|
||||
}
|
||||
|
||||
end:
|
||||
#if defined(WINDOWS)
|
||||
std::cout << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
FreeConsole();
|
||||
exit(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,389 +0,0 @@
|
||||
/* MIT License - Copyright (c) 2019-2022 Francis Van Roie
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
|
||||
#if defined(WINDOWS)
|
||||
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
// MSDN recommends against using getcwd & chdir names
|
||||
#define cwd _getcwd
|
||||
#define cd _chdir
|
||||
#endif
|
||||
|
||||
#if defined(POSIX)
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#define cwd getcwd
|
||||
#define cd chdir
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "hasplib.h"
|
||||
|
||||
// #include "app_hal.h"
|
||||
#include "display/monitor.h"
|
||||
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_gui.h"
|
||||
|
||||
#include "dev/device.h"
|
||||
|
||||
bool isConnected;
|
||||
bool isRunning = 1;
|
||||
|
||||
uint8_t mainLoopCounter = 0;
|
||||
unsigned long mainLastLoopTime = 0;
|
||||
|
||||
#ifdef HASP_USE_STAT_COUNTER
|
||||
uint16_t statLoopCounter = 0; // measures the average looptime
|
||||
#endif
|
||||
|
||||
extern uint16_t tft_width;
|
||||
extern uint16_t tft_height;
|
||||
|
||||
#if defined(WINDOWS)
|
||||
// https://gist.github.com/kingseva/a918ec66079a9475f19642ec31276a21
|
||||
void BindStdHandlesToConsole()
|
||||
{
|
||||
// TODO: Add Error checking.
|
||||
|
||||
// Redirect the CRT standard input, output, and error handles to the console
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
|
||||
// Note that there is no CONERR$ file
|
||||
HANDLE hStdout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE hStdin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
|
||||
SetStdHandle(STD_ERROR_HANDLE, hStdout);
|
||||
SetStdHandle(STD_INPUT_HANDLE, hStdin);
|
||||
|
||||
// Clear the error state for each of the C++ standard stream objects.
|
||||
std::wclog.clear();
|
||||
std::clog.clear();
|
||||
std::wcout.clear();
|
||||
std::cout.clear();
|
||||
std::wcerr.clear();
|
||||
std::cerr.clear();
|
||||
std::wcin.clear();
|
||||
std::cin.clear();
|
||||
}
|
||||
|
||||
void InitializeConsoleOutput()
|
||||
{
|
||||
bool isConsoleApp;
|
||||
|
||||
// How to check if the program is run from a console?
|
||||
// https://stackoverflow.com/questions/9009333/how-to-check-if-the-program-is-run-from-a-console
|
||||
HWND consoleWnd = GetConsoleWindow();
|
||||
DWORD dwProcessId;
|
||||
GetWindowThreadProcessId(consoleWnd, &dwProcessId);
|
||||
|
||||
if(GetCurrentProcessId() == dwProcessId) {
|
||||
isConsoleApp = true; // Opened in Console
|
||||
} else {
|
||||
isConsoleApp = false; // Opened in Windows
|
||||
}
|
||||
|
||||
// Use normal console that launched the program
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
// Test if the application was started from a Console Window
|
||||
if(!isConsoleApp) {
|
||||
// If started from Windows, use detached Log Console Window
|
||||
AllocConsole();
|
||||
}
|
||||
|
||||
// Redirect all standard output streams to the console
|
||||
BindStdHandlesToConsole();
|
||||
}
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Load Settings
|
||||
|
||||
// Init debug log
|
||||
// debug_init();
|
||||
|
||||
// Initialize lvgl environment
|
||||
lv_init();
|
||||
lv_log_register_print_cb(debugLvglLogEvent);
|
||||
|
||||
haspDevice.init(); // hardware setup
|
||||
haspDevice.show_info(); // debug info
|
||||
// hal_setup();
|
||||
guiSetup();
|
||||
|
||||
LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
|
||||
dispatchSetup(); // for hasp and oobe
|
||||
haspSetup();
|
||||
|
||||
#if HASP_USE_MQTT > 0
|
||||
LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
|
||||
mqttSetup(); // Hasp must be running
|
||||
mqttStart();
|
||||
#endif
|
||||
|
||||
#if HASP_USE_GPIO > 0
|
||||
LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
|
||||
gpioSetup();
|
||||
#endif
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
custom_setup();
|
||||
#endif
|
||||
|
||||
mainLastLoopTime = millis(); // - 1000; // reset loop counter
|
||||
LOG_DEBUG(TAG_MAIN, "%s %d", __FILE__, __LINE__);
|
||||
// delay(250);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
haspLoop();
|
||||
mqttLoop();
|
||||
|
||||
// debugLoop(); // Console
|
||||
haspDevice.loop();
|
||||
guiLoop();
|
||||
|
||||
#if HASP_USE_GPIO > 0
|
||||
gpioLoop();
|
||||
#endif
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
custom_loop();
|
||||
#endif
|
||||
|
||||
#ifdef HASP_USE_STAT_COUNTER
|
||||
statLoopCounter++; // measures the average looptime
|
||||
#endif
|
||||
|
||||
/* Timer Loop */
|
||||
if(millis() - mainLastLoopTime >= 1000) {
|
||||
/* Runs Every Second */
|
||||
haspEverySecond(); // sleep timer
|
||||
dispatchEverySecond(); // sleep timer
|
||||
|
||||
#if HASP_USE_ARDUINOOTA > 0
|
||||
otaEverySecond(); // progressbar
|
||||
#endif
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
custom_every_second();
|
||||
#endif
|
||||
|
||||
/* Runs Every 5 Seconds */
|
||||
if(mainLoopCounter == 0 || mainLoopCounter == 5) {
|
||||
|
||||
haspDevice.loop_5s();
|
||||
gpioEvery5Seconds();
|
||||
|
||||
#if defined(HASP_USE_MQTT)
|
||||
mqttEvery5Seconds(true);
|
||||
#endif
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
custom_every_5seconds();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Reset loop counter every 10 seconds */
|
||||
if(mainLoopCounter >= 9) {
|
||||
mainLoopCounter = 0;
|
||||
} else {
|
||||
mainLoopCounter++;
|
||||
}
|
||||
mainLastLoopTime += 1000;
|
||||
}
|
||||
// delay(6);
|
||||
}
|
||||
|
||||
void usage(const char* progName, const char* version)
|
||||
{
|
||||
std::cout << "\n\n"
|
||||
<< progName << " " << version << " [options]" << std::endl
|
||||
<< std::endl
|
||||
<< "Options:" << std::endl
|
||||
<< " -? | --help Print this help" << std::endl
|
||||
<< " -w | --width Width of the window" << std::endl
|
||||
<< " -h | --height Height of the window" << std::endl
|
||||
<< " --mqttname MQTT device name topic (default: computer hostname)" << std::endl
|
||||
<< " --mqtthost MQTT broker hostname or IP address" << std::endl
|
||||
<< " --mqttport MQTT broker port (default: 1883)" << std::endl
|
||||
<< " --mqttuser MQTT username" << std::endl
|
||||
<< " --mqttpass MQTT password" << std::endl
|
||||
<< " --mqttgroup MQTT groupname (default: plates)" << std::endl
|
||||
<< std::endl
|
||||
// << " -t | --topic Base topic of the mqtt messages (default: hasp)" << std::endl
|
||||
// << std::endl
|
||||
// << " -f | --fullscreen Open the application fullscreen" << std::endl
|
||||
// << " -v | --verbose Verbosity level" << std::endl
|
||||
<< std::endl;
|
||||
fflush(stdout);
|
||||
#if defined(WINDOWS)
|
||||
static const char s[] = "\n";
|
||||
DWORD slen = lstrlen(s);
|
||||
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), s, slen, &slen, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
bool showhelp = false;
|
||||
int count;
|
||||
|
||||
#if defined(WINDOWS)
|
||||
InitializeConsoleOutput();
|
||||
SetConsoleCP(65001); // 65001 = UTF-8
|
||||
static const char s[] = "tränenüberströmt™\n";
|
||||
DWORD slen = lstrlen(s);
|
||||
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), s, slen, &slen, NULL);
|
||||
|
||||
HANDLE std_out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if(std_out == INVALID_HANDLE_VALUE) {
|
||||
return 66;
|
||||
}
|
||||
if(!WriteConsole(std_out, "Hello World!\n", 13, NULL, NULL)) {
|
||||
return 67;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Init(0); // Needs to be initialized for GetPerfPath
|
||||
char buf[4096]; // never know how much is needed
|
||||
std::cout << "CWD: " << cwd(buf, sizeof buf) << std::endl;
|
||||
cd(SDL_GetPrefPath("hasp", "hasp"));
|
||||
std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
|
||||
SDL_Quit(); // We'll properly init later
|
||||
|
||||
// Change to preferences dir
|
||||
std::cout << "\nCommand-line arguments:\n";
|
||||
for(count = 0; count < argc; count++)
|
||||
std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
|
||||
|
||||
StaticJsonDocument<1024> settings;
|
||||
|
||||
for(count = 0; count < argc; count++) {
|
||||
if(argv[count][0] == '-') {
|
||||
|
||||
if(strncmp(argv[count], "--help", 6) == 0 || strncmp(argv[count], "-?", 2) == 0) {
|
||||
showhelp = true;
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--width", 7) == 0 || strncmp(argv[count], "-w", 2) == 0) {
|
||||
int w = atoi(argv[count + 1]);
|
||||
if(w > 0) tft_width = w;
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--height", 8) == 0 || strncmp(argv[count], "-h", 2) == 0) {
|
||||
int h = atoi(argv[count + 1]);
|
||||
if(h > 0) tft_height = h;
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--mqttname", 10) == 0 || strncmp(argv[count], "-n", 2) == 0) {
|
||||
std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
if(count + 1 < argc) {
|
||||
haspDevice.set_hostname(argv[count + 1]);
|
||||
settings["mqtt"]["name"] = argv[count + 1];
|
||||
} else {
|
||||
showhelp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--mqtthost", 10) == 0) {
|
||||
std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
if(count + 1 < argc) {
|
||||
settings["mqtt"]["host"] = argv[count + 1];
|
||||
} else {
|
||||
showhelp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--mqttport", 10) == 0) {
|
||||
std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
if(count + 1 < argc) {
|
||||
settings["mqtt"]["port"] = atoi(argv[count + 1]);
|
||||
} else {
|
||||
showhelp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--mqttuser", 10) == 0) {
|
||||
std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
if(count + 1 < argc) {
|
||||
settings["mqtt"]["user"] = argv[count + 1];
|
||||
} else {
|
||||
showhelp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(strncmp(argv[count], "--mqttpass", 10) == 0) {
|
||||
std::cout << " argv[" << count << "] " << argv[count] << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
if(count + 1 < argc) {
|
||||
settings["mqtt"]["pass"] = argv[count + 1];
|
||||
} else {
|
||||
showhelp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(showhelp) {
|
||||
usage("openHASP", haspDevice.get_version());
|
||||
|
||||
#if defined(WINDOWS)
|
||||
WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
|
||||
std::cout << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
FreeConsole();
|
||||
exit(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
serializeJson(settings, buffer, sizeof(buffer));
|
||||
std::cout << buffer << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
mqttSetConfig(settings["mqtt"]);
|
||||
// printf("%s %d\n", __FILE__, __LINE__);
|
||||
// fflush(stdout);
|
||||
|
||||
debugPrintHaspHeader(stdout);
|
||||
LOG_INFO(TAG_MAIN, "resolution %d x %d", tft_width, tft_height);
|
||||
LOG_INFO(TAG_MAIN, "pre setup");
|
||||
|
||||
setup();
|
||||
|
||||
LOG_TRACE(TAG_MAIN, "loop started");
|
||||
while(isRunning) {
|
||||
loop();
|
||||
}
|
||||
LOG_TRACE(TAG_MAIN, "main loop completed");
|
||||
|
||||
#if defined(WINDOWS)
|
||||
WriteConsole(std_out, "bye\n\n", 3, NULL, NULL);
|
||||
std::cout << std::endl << std::flush;
|
||||
fflush(stdout);
|
||||
FreeConsole();
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -16,7 +16,7 @@
|
||||
|
||||
#define RETAINED true
|
||||
|
||||
#if defined(WINDOWS) || defined(POSIX)
|
||||
#if HASP_TARGET_PC
|
||||
extern std::string mqttNodeTopic;
|
||||
extern std::string mqttGroupTopic;
|
||||
#else
|
||||
@ -35,7 +35,7 @@ const char FP_MQTT_HA_NAME[] PROGMEM = "name";
|
||||
const char FP_MQTT_HA_MODEL[] PROGMEM = "mdl";
|
||||
const char FP_MQTT_HA_MANUFACTURER[] PROGMEM = "mf";
|
||||
|
||||
#if !(defined(WINDOWS) || defined(POSIX))
|
||||
#if HASP_TARGET_ARDUINO
|
||||
|
||||
#include "hal/hasp_hal.h"
|
||||
|
||||
|
@ -10,6 +10,15 @@
|
||||
#if HASP_USE_MQTT_ASYNC > 0
|
||||
#ifdef HASP_USE_PAHO
|
||||
|
||||
#if !HASP_USE_CONFIG
|
||||
const char FP_CONFIG_HOST[] PROGMEM = "host";
|
||||
const char FP_CONFIG_PORT[] PROGMEM = "port";
|
||||
const char FP_CONFIG_NAME[] PROGMEM = "name";
|
||||
const char FP_CONFIG_USER[] PROGMEM = "user";
|
||||
const char FP_CONFIG_PASS[] PROGMEM = "pass";
|
||||
const char FP_CONFIG_GROUP[] PROGMEM = "group";
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012, 2020 IBM Corp.
|
||||
*
|
||||
@ -38,7 +47,7 @@
|
||||
#include "hasp_mqtt.h" // functions to implement here
|
||||
|
||||
#include "hasp/hasp_dispatch.h" // for dispatch_topic_payload
|
||||
#include "hasp_debug.h" // for logging
|
||||
#include "hasp_debug.h" // for logging
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
@ -50,78 +59,131 @@
|
||||
#include <OsWrapper.h>
|
||||
#endif
|
||||
|
||||
#define ADDRESS "10.4.0.5:1883"
|
||||
#define CLIENTID "ExampleClientSub"
|
||||
#define TOPIC "hasp/plate35/"
|
||||
// #define ADDRESS "10.4.0.5:1883"
|
||||
// #define CLIENTID "ExampleClientSub"
|
||||
// #define TOPIC "hasp/plate35/"
|
||||
#define QOS 1
|
||||
#define TIMEOUT 10000L
|
||||
|
||||
const char* mqttNodeTopic = TOPIC;
|
||||
const char* mqttGroupTopic = TOPIC;
|
||||
// char mqttNodeTopic[24];
|
||||
// char mqttGroupTopic[24];
|
||||
std::string mqttNodeTopic;
|
||||
std::string mqttGroupTopic;
|
||||
std::string mqttLwtTopic;
|
||||
bool mqttEnabled = false;
|
||||
bool mqttHAautodiscover = true;
|
||||
uint32_t mqttPublishCount;
|
||||
uint32_t mqttReceiveCount;
|
||||
uint32_t mqttFailedCount;
|
||||
|
||||
std::recursive_mutex dispatch_mtx;
|
||||
std::recursive_mutex publish_mtx;
|
||||
|
||||
char mqttServer[MAX_HOSTNAME_LENGTH] = MQTT_HOSTNAME;
|
||||
char mqttUser[MAX_USERNAME_LENGTH] = MQTT_USERNAME;
|
||||
char mqttPassword[MAX_PASSWORD_LENGTH] = MQTT_PASSWORD;
|
||||
// char mqttNodeName[16] = MQTT_NODENAME;
|
||||
char mqttGroupName[16] = MQTT_GROUPNAME;
|
||||
uint16_t mqttPort = MQTT_PORT;
|
||||
std::string mqttServer = MQTT_HOSTNAME;
|
||||
std::string mqttUsername = MQTT_USERNAME;
|
||||
std::string mqttPassword = MQTT_PASSWORD;
|
||||
std::string mqttGroupName = MQTT_GROUPNAME;
|
||||
uint16_t mqttPort = MQTT_PORT;
|
||||
|
||||
MQTTAsync mqtt_client;
|
||||
|
||||
int disc_finished = 0;
|
||||
int subscribed = 0;
|
||||
int connected = 0;
|
||||
static bool mqttConnecting = false;
|
||||
static bool mqttConnected = false;
|
||||
|
||||
static bool mqttPublish(const char* topic, const char* payload, size_t len, bool retain = false);
|
||||
int mqttPublish(const char* topic, const char* payload, size_t len, bool retain = false);
|
||||
|
||||
/* ===== Paho event callbacks ===== */
|
||||
|
||||
void connlost(void* context, char* cause)
|
||||
static void onConnectFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
printf("\nConnection lost\n");
|
||||
if(cause) printf(" cause: %s\n", cause);
|
||||
#if HASP_TARGET_PC
|
||||
dispatch_run_script(NULL, "L:/offline.cmd", TAG_HASP);
|
||||
#endif
|
||||
mqttConnecting = false;
|
||||
mqttConnected = false;
|
||||
LOG_ERROR(TAG_MQTT, "Connection failed, return code %d (%s)", response->code, response->message);
|
||||
}
|
||||
|
||||
printf("Reconnecting\n");
|
||||
mqttStart();
|
||||
static void onDisconnect(void* context, MQTTAsync_successData* response)
|
||||
{
|
||||
#if HASP_TARGET_PC
|
||||
dispatch_run_script(NULL, "L:/offline.cmd", TAG_HASP);
|
||||
#endif
|
||||
mqttConnecting = false;
|
||||
mqttConnected = false;
|
||||
}
|
||||
|
||||
static void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
mqttConnecting = false;
|
||||
mqttConnected = false;
|
||||
LOG_ERROR(TAG_MQTT, "Disconnection failed, return code %d (%s)", response->code, response->message);
|
||||
}
|
||||
|
||||
static void onSendFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
LOG_ERROR(TAG_MQTT, "Send failed, return code %d (%s)", response->code, response->message);
|
||||
}
|
||||
|
||||
static void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
LOG_ERROR(TAG_MQTT, "Subscribe failed, return code %d (%s)", response->code, response->message);
|
||||
}
|
||||
|
||||
static void connlost(void* context, char* cause)
|
||||
{
|
||||
#if HASP_TARGET_PC
|
||||
dispatch_run_script(NULL, "L:/offline.cmd", TAG_HASP);
|
||||
#endif
|
||||
LOG_WARNING(TAG_MQTT, F(D_MQTT_DISCONNECTED ": %s"), cause);
|
||||
mqttConnecting = false;
|
||||
mqttConnected = false;
|
||||
}
|
||||
|
||||
// Receive incoming messages
|
||||
static void mqtt_message_cb(char* topic, char* payload, size_t length)
|
||||
{ // Handle incoming commands from MQTT
|
||||
if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
|
||||
mqttFailedCount++;
|
||||
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), (uint32_t)length);
|
||||
return;
|
||||
} else {
|
||||
mqttReceiveCount++;
|
||||
payload[length] = '\0';
|
||||
}
|
||||
|
||||
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_mtx.lock();
|
||||
dispatch_topic_payload(topic, (const char*)payload);
|
||||
dispatch_topic_payload(topic, (const char*)payload, length > 0, TAG_MQTT);
|
||||
dispatch_mtx.unlock();
|
||||
return;
|
||||
|
||||
#ifdef HASP_USE_BROADCAST
|
||||
} else if(topic == strstr_P(topic, PSTR(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST
|
||||
"/"))) { // /" MQTT_TOPIC_BROADCAST "/ discovery topic
|
||||
|
||||
// /" MQTT_TOPIC_BROADCAST "/ topic
|
||||
topic += strlen(MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/"); // shorten topic
|
||||
dispatch_mtx.lock();
|
||||
dispatch_topic_payload(topic, (const char*)payload, length > 0, TAG_MQTT);
|
||||
dispatch_mtx.unlock();
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef HASP_USE_HA
|
||||
} else if(topic == strstr_P(topic, PSTR("homeassistant/status"))) { // HA discovery topic
|
||||
if(mqttHAautodiscover && !strcasecmp_P((char*)payload, PSTR("online"))) {
|
||||
dispatch_current_state();
|
||||
dispatch_mtx.lock();
|
||||
dispatch_current_state(TAG_MQTT);
|
||||
dispatch_mtx.unlock();
|
||||
mqtt_ha_register_auto_discovery();
|
||||
}
|
||||
return;
|
||||
@ -138,11 +200,8 @@ static void mqtt_message_cb(char* topic, char* payload, size_t 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" MQTT_TOPIC_LWT), mqttNodeTopic);
|
||||
snprintf_P(msg, sizeof(msg), PSTR("online"));
|
||||
|
||||
mqttPublish(tmp_topic, msg, true);
|
||||
mqttPublish(mqttLwtTopic.c_str(), msg, strlen(msg), true);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -150,175 +209,151 @@ static void mqtt_message_cb(char* topic, char* payload, size_t length)
|
||||
}
|
||||
} else {
|
||||
dispatch_mtx.lock();
|
||||
dispatch_topic_payload(topic, (const char*)payload);
|
||||
dispatch_topic_payload(topic, (const char*)payload, length > 0, TAG_MQTT);
|
||||
dispatch_mtx.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
int msgarrvd(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
|
||||
static int mqtt_message_arrived(void* context, char* topicName, int topicLen, MQTTAsync_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';
|
||||
|
||||
mqtt_message_cb(topicName, (char*)message->payload, message->payloadlen);
|
||||
mqtt_message_cb(topicName, msg, message->payloadlen);
|
||||
|
||||
MQTTAsync_freeMessage(&message);
|
||||
MQTTAsync_free(topicName);
|
||||
return 1;
|
||||
return 1; // the message was received properly
|
||||
}
|
||||
|
||||
void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
printf("Disconnect failed, rc %d\n", response->code);
|
||||
disc_finished = 1;
|
||||
}
|
||||
|
||||
void onDisconnect(void* context, MQTTAsync_successData* response)
|
||||
{
|
||||
printf("Successful disconnection\n");
|
||||
disc_finished = 1;
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
void onSubscribe(void* context, MQTTAsync_successData* response)
|
||||
{
|
||||
printf("Subscribe succeeded %d\n", response->token);
|
||||
subscribed = 1;
|
||||
}
|
||||
|
||||
void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
printf("Subscribe failed, rc %d\n", response->code);
|
||||
}
|
||||
|
||||
void onConnectFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
connected = 0;
|
||||
printf("Connect failed, rc %d\n", response->code);
|
||||
}
|
||||
|
||||
void mqtt_subscribe(void* context, const char* topic)
|
||||
static void mqtt_subscribe(void* context, const char* topic)
|
||||
{
|
||||
MQTTAsync client = (MQTTAsync)context;
|
||||
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
|
||||
int rc;
|
||||
|
||||
printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n", topic, CLIENTID, QOS);
|
||||
opts.onSuccess = onSubscribe;
|
||||
opts.onFailure = onSubscribeFailure;
|
||||
opts.context = client;
|
||||
if((rc = MQTTAsync_subscribe(client, topic, QOS, &opts)) != MQTTASYNC_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);
|
||||
}
|
||||
}
|
||||
|
||||
void onConnect(void* context, MQTTAsync_successData* response)
|
||||
{
|
||||
MQTTAsync client = (MQTTAsync)context;
|
||||
connected = 1;
|
||||
|
||||
printf("Successful connection\n");
|
||||
|
||||
mqtt_subscribe(context, TOPIC MQTT_TOPIC_COMMAND "/#");
|
||||
mqtt_subscribe(context, TOPIC MQTT_TOPIC_COMMAND);
|
||||
mqtt_subscribe(context, TOPIC "light");
|
||||
mqtt_subscribe(context, TOPIC "dim");
|
||||
|
||||
mqttPublish(TOPIC MQTT_TOPIC_LWT, "online", false);
|
||||
|
||||
mqtt_send_object_state(0, 0, "connected");
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void onSendFailure(void* context, MQTTAsync_failureData* response)
|
||||
{
|
||||
MQTTAsync client = (MQTTAsync)context;
|
||||
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
|
||||
int rc;
|
||||
|
||||
printf("Message send failed token %d error code %d\n", response->token, response->code);
|
||||
opts.onSuccess = onDisconnect;
|
||||
opts.onFailure = onDisconnectFailure;
|
||||
opts.context = client;
|
||||
if((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) {
|
||||
printf("Failed to start disconnect, return code %d\n", rc);
|
||||
// exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void onSend(void* context, MQTTAsync_successData* response)
|
||||
{
|
||||
MQTTAsync client = (MQTTAsync)context;
|
||||
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
|
||||
int rc;
|
||||
|
||||
// printf("Message with token value %d delivery confirmed\n", response->token);
|
||||
|
||||
// opts.onSuccess = onDisconnect;
|
||||
// opts.onFailure = onDisconnectFailure;
|
||||
// opts.context = client;
|
||||
// if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
|
||||
// {
|
||||
// printf("Failed to start disconnect, return code %d\n", rc);
|
||||
// exit(EXIT_FAILURE);
|
||||
// }
|
||||
}
|
||||
|
||||
/* ===== Local HASP MQTT functions ===== */
|
||||
|
||||
static bool 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)
|
||||
{
|
||||
if(mqttIsConnected()) {
|
||||
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
|
||||
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
|
||||
int rc;
|
||||
if(!mqttEnabled) return MQTT_ERR_DISABLED;
|
||||
|
||||
opts.onSuccess = onSend;
|
||||
opts.onFailure = onSendFailure;
|
||||
opts.context = mqtt_client;
|
||||
pubmsg.payload = (char*)payload;
|
||||
pubmsg.payloadlen = (int)strlen(payload);
|
||||
pubmsg.qos = QOS;
|
||||
pubmsg.retained = 0;
|
||||
dispatch_mtx.lock();
|
||||
if((rc = MQTTAsync_sendMessage(mqtt_client, topic, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) {
|
||||
dispatch_mtx.unlock();
|
||||
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " %s => %s"), topic, payload);
|
||||
} else {
|
||||
dispatch_mtx.unlock();
|
||||
LOG_TRACE(TAG_MQTT_PUB, F("%s => %s"), topic, payload);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(TAG_MQTT, F(D_MQTT_NOT_CONNECTED));
|
||||
if(!mqttIsConnected()) {
|
||||
mqttFailedCount++;
|
||||
return MQTT_ERR_NO_CONN;
|
||||
}
|
||||
|
||||
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
|
||||
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
|
||||
|
||||
opts.onFailure = onSendFailure;
|
||||
opts.context = mqtt_client;
|
||||
pubmsg.payload = (char*)payload;
|
||||
pubmsg.payloadlen = (int)strlen(payload);
|
||||
pubmsg.qos = QOS;
|
||||
pubmsg.retained = 0;
|
||||
|
||||
dispatch_mtx.lock();
|
||||
int rc = MQTTAsync_sendMessage(mqtt_client, topic, &pubmsg, &opts);
|
||||
|
||||
if(rc != MQTTASYNC_SUCCESS) {
|
||||
dispatch_mtx.unlock();
|
||||
mqttFailedCount++;
|
||||
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload);
|
||||
return MQTT_ERR_PUB_FAIL;
|
||||
} else {
|
||||
dispatch_mtx.unlock();
|
||||
mqttPublishCount++;
|
||||
// LOG_TRACE(TAG_MQTT_PUB, F("'%s' => %s OK"), topic, payload);
|
||||
return MQTT_ERR_OK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ===== Public HASP MQTT functions ===== */
|
||||
|
||||
bool mqttIsConnected()
|
||||
{
|
||||
return connected == 1;
|
||||
return mqttConnected; // MQTTAsync_isConnected(mqtt_client); // <- deadlocking on Linux
|
||||
}
|
||||
|
||||
void 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];
|
||||
printf(("%s" MQTT_TOPIC_STATE "/%s\n"), mqttNodeTopic, subtopic);
|
||||
snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic, subtopic);
|
||||
mqttPublish(tmp_topic, payload, false);
|
||||
char tmp_topic[mqttNodeTopic.length() + 20];
|
||||
snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic.c_str(), subtopic);
|
||||
return mqttPublish(tmp_topic, payload, strlen(payload), false);
|
||||
}
|
||||
|
||||
void mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
|
||||
int mqtt_send_discovery(const char* payload, size_t len)
|
||||
{
|
||||
char tmp_topic[strlen(mqttNodeTopic) + 20];
|
||||
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/p%ub%u"), mqttNodeTopic, pageid, btnid);
|
||||
mqttPublish(tmp_topic, payload, false);
|
||||
char tmp_topic[128];
|
||||
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR(MQTT_PREFIX "/" MQTT_TOPIC_DISCOVERY "/%s"),
|
||||
haspDevice.get_hardware_id());
|
||||
return mqttPublish(tmp_topic, payload, len, false);
|
||||
}
|
||||
|
||||
// int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload)
|
||||
// {
|
||||
// char tmp_topic[mqttNodeTopic.length() + 20];
|
||||
// snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/p%ub%u"), mqttNodeTopic.c_str(), pageid,
|
||||
// btnid);
|
||||
// return mqttPublish(tmp_topic, payload, strlen(payload), false);
|
||||
// }
|
||||
|
||||
static void onConnect(void* context, MQTTAsync_successData* response)
|
||||
{
|
||||
mqttConnecting = false;
|
||||
mqttConnected = true;
|
||||
MQTTAsync client = (MQTTAsync)context;
|
||||
std::string topic;
|
||||
|
||||
LOG_VERBOSE(TAG_MQTT, D_MQTT_CONNECTED, mqttServer.c_str(), haspDevice.get_hostname());
|
||||
|
||||
topic = mqttGroupTopic + MQTT_TOPIC_COMMAND "/#";
|
||||
mqtt_subscribe(mqtt_client, topic.c_str());
|
||||
|
||||
topic = mqttNodeTopic + MQTT_TOPIC_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());
|
||||
|
||||
#if defined(HASP_USE_CUSTOM)
|
||||
topic = mqttGroupTopic + MQTT_TOPIC_CUSTOM "/#";
|
||||
mqtt_subscribe(mqtt_client, topic.c_str());
|
||||
|
||||
topic = mqttNodeTopic + MQTT_TOPIC_CUSTOM "/#";
|
||||
mqtt_subscribe(mqtt_client, topic.c_str());
|
||||
#endif
|
||||
|
||||
#ifdef HASP_USE_BROADCAST
|
||||
topic = MQTT_PREFIX "/" MQTT_TOPIC_BROADCAST "/" MQTT_TOPIC_COMMAND "/#";
|
||||
mqtt_subscribe(mqtt_client, topic.c_str());
|
||||
#endif
|
||||
|
||||
/* Home Assistant auto-configuration */
|
||||
#ifdef HASP_USE_HA
|
||||
topic = "homeassistant/status";
|
||||
mqtt_subscribe(mqtt_client, topic.c_str());
|
||||
#endif
|
||||
|
||||
mqttPublish(mqttLwtTopic.c_str(), "online", 6, true);
|
||||
|
||||
#if HASP_TARGET_PC
|
||||
dispatch_run_script(NULL, "L:/online.cmd", TAG_HASP);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mqttStart()
|
||||
@ -328,47 +363,51 @@ void mqttStart()
|
||||
int rc;
|
||||
int ch;
|
||||
|
||||
if((rc = MQTTAsync_create(&mqtt_client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) !=
|
||||
if((rc = MQTTAsync_create(&mqtt_client, mqttServer.c_str(), haspDevice.get_hostname(), MQTTCLIENT_PERSISTENCE_NONE,
|
||||
NULL)) != MQTTASYNC_SUCCESS) {
|
||||
LOG_ERROR(TAG_MQTT, "Failed to create client, return code %d", rc);
|
||||
rc = EXIT_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, mqtt_message_arrived, NULL)) !=
|
||||
MQTTASYNC_SUCCESS) {
|
||||
printf("Failed to create client, return code %d\n", rc);
|
||||
LOG_ERROR(TAG_MQTT, "Failed to set callbacks, return code %d", rc);
|
||||
rc = EXIT_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
if((rc = MQTTAsync_setCallbacks(mqtt_client, mqtt_client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS) {
|
||||
printf("Failed to set callbacks, return code %d\n", rc);
|
||||
rc = EXIT_FAILURE;
|
||||
return;
|
||||
}
|
||||
mqttEnabled = mqttServer.length() > 0 && mqttPort > 0;
|
||||
|
||||
conn_opts.will = &will_opts;
|
||||
conn_opts.will->message = "offline";
|
||||
conn_opts.will->qos = 1;
|
||||
conn_opts.will->retained = 0;
|
||||
conn_opts.will->topicName = "hasp/plate35/LWT";
|
||||
if(mqttEnabled) {
|
||||
conn_opts.will = &will_opts;
|
||||
conn_opts.will->message = "offline";
|
||||
conn_opts.will->qos = 1;
|
||||
conn_opts.will->retained = 1;
|
||||
conn_opts.will->topicName = mqttLwtTopic.c_str();
|
||||
|
||||
conn_opts.keepAliveInterval = 20;
|
||||
conn_opts.cleansession = 1;
|
||||
conn_opts.onSuccess = onConnect;
|
||||
conn_opts.onFailure = onConnectFailure;
|
||||
conn_opts.context = mqtt_client;
|
||||
conn_opts.keepAliveInterval = 20;
|
||||
conn_opts.cleansession = 1;
|
||||
conn_opts.connectTimeout = 2; // seconds
|
||||
conn_opts.retryInterval = 15; // 0 = no retry
|
||||
conn_opts.onSuccess = onConnect;
|
||||
conn_opts.onFailure = onConnectFailure;
|
||||
conn_opts.context = mqtt_client;
|
||||
|
||||
if((rc = MQTTAsync_connect(mqtt_client, &conn_opts)) != MQTTASYNC_SUCCESS) {
|
||||
printf("Failed to start connect, return code %d\n", rc);
|
||||
rc = EXIT_FAILURE;
|
||||
// goto destroy_exit;
|
||||
conn_opts.username = mqttUsername.c_str();
|
||||
conn_opts.password = mqttPassword.c_str();
|
||||
|
||||
mqttConnecting = true;
|
||||
if((rc = MQTTAsync_connect(mqtt_client, &conn_opts)) != MQTTASYNC_SUCCESS) {
|
||||
mqttConnecting = false;
|
||||
LOG_ERROR(TAG_MQTT, "Failed to connect, return code %d", rc);
|
||||
rc = EXIT_FAILURE;
|
||||
// goto destroy_exit;
|
||||
}
|
||||
} else {
|
||||
rc = EXIT_FAILURE;
|
||||
LOG_WARNING(TAG_MQTT, "Mqtt server not configured");
|
||||
}
|
||||
|
||||
// while (!subscribed && !finished)
|
||||
// #if defined(_WIN32)
|
||||
// Sleep(100);
|
||||
// #else
|
||||
// usleep(10000L);
|
||||
// #endif
|
||||
|
||||
// if (finished)
|
||||
// goto exit;
|
||||
}
|
||||
|
||||
void mqttStop()
|
||||
@ -378,30 +417,146 @@ void mqttStop()
|
||||
disc_opts.onSuccess = onDisconnect;
|
||||
disc_opts.onFailure = onDisconnectFailure;
|
||||
if((rc = MQTTAsync_disconnect(mqtt_client, &disc_opts)) != MQTTASYNC_SUCCESS) {
|
||||
printf("Failed to start disconnect, return code %d\n", rc);
|
||||
LOG_ERROR(TAG_MQTT, "Failed to disconnect, return code %d", rc);
|
||||
rc = EXIT_FAILURE;
|
||||
// goto destroy_exit;
|
||||
}
|
||||
// while (!disc_finished)
|
||||
// {
|
||||
// #if defined(_WIN32)
|
||||
// Sleep(100);
|
||||
// #else
|
||||
// usleep(10000L);
|
||||
// #endif
|
||||
// }
|
||||
|
||||
// destroy_exit:
|
||||
// MQTTAsync_destroy(&client);
|
||||
// exit:
|
||||
// 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 += MQTT_TOPIC_LWT;
|
||||
}
|
||||
|
||||
IRAM_ATTR void mqttLoop(){};
|
||||
|
||||
void mqttEvery5Seconds(bool wifiIsConnected){};
|
||||
void mqttEvery5Seconds(bool wifiIsConnected)
|
||||
{
|
||||
if(!mqttIsConnected() && !mqttConnecting && mqttServer.length() > 0 && mqttPort > 0) {
|
||||
LOG_WARNING(TAG_MQTT, F(D_MQTT_RECONNECTING));
|
||||
mqttStart();
|
||||
}
|
||||
};
|
||||
|
||||
void mqtt_get_info(JsonDocument& doc)
|
||||
{
|
||||
char mqttClientId[64];
|
||||
|
||||
JsonObject info = doc.createNestedObject(F("MQTT"));
|
||||
info[F(D_INFO_SERVER)] = mqttServer;
|
||||
info[F(D_INFO_USERNAME)] = mqttUsername;
|
||||
info[F(D_INFO_CLIENTID)] = haspDevice.get_hostname();
|
||||
info[F(D_INFO_STATUS)] = mqttIsConnected() ? F(D_SERVICE_CONNECTED) : F(D_SERVICE_DISCONNECTED);
|
||||
info[F(D_INFO_RECEIVED)] = mqttReceiveCount;
|
||||
info[F(D_INFO_PUBLISHED)] = mqttPublishCount;
|
||||
info[F(D_INFO_FAILED)] = mqttFailedCount;
|
||||
}
|
||||
|
||||
bool mqttGetConfig(const JsonObject& settings)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname();
|
||||
|
||||
if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
|
||||
|
||||
if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
|
||||
|
||||
if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as<uint16_t>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
|
||||
|
||||
if(mqttUsername != settings[FPSTR(FP_CONFIG_USER)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_USER)] = mqttUsername;
|
||||
|
||||
if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
|
||||
|
||||
if(changed) configOutput(settings, TAG_MQTT);
|
||||
return changed;
|
||||
}
|
||||
|
||||
/** Set MQTT Configuration.
|
||||
*
|
||||
* Read the settings from json and sets the application variables.
|
||||
*
|
||||
* @note: data pixel should be formatted to uint32_t RGBA. Imagemagick requirements.
|
||||
*
|
||||
* @param[in] settings JsonObject with the config settings.
|
||||
**/
|
||||
bool mqttSetConfig(const JsonObject& settings)
|
||||
{
|
||||
// configOutput(settings, TAG_MQTT);
|
||||
bool changed = false;
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_PORT)].isNull()) {
|
||||
// changed |= configSet(mqttPort, settings[FPSTR(FP_CONFIG_PORT)], F("mqttPort"));
|
||||
changed |= mqttPort != settings[FPSTR(FP_CONFIG_PORT)];
|
||||
mqttPort = settings[FPSTR(FP_CONFIG_PORT)];
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_NAME)].isNull()) {
|
||||
LOG_VERBOSE(TAG_MQTT, "%s => %s", FP_CONFIG_NAME, settings[FPSTR(FP_CONFIG_NAME)].as<const char*>());
|
||||
changed |= strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)]) != 0;
|
||||
// strncpy(mqttNodeName, settings[FPSTR(FP_CONFIG_NAME)], sizeof(mqttNodeName));
|
||||
haspDevice.set_hostname(settings[FPSTR(FP_CONFIG_NAME)].as<const char*>());
|
||||
}
|
||||
// Prefill node name
|
||||
// if(strlen(haspDevice.get_hostname()) == 0) {
|
||||
// char mqttNodeName[64];
|
||||
// std::string mac = halGetMacAddress(3, "");
|
||||
// mac.toLowerCase();
|
||||
// snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR(D_MQTT_DEFAULT_NAME), mac.c_str());
|
||||
// haspDevice.set_hostname(mqttNodeName);
|
||||
// changed = true;
|
||||
// }
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_GROUP)].isNull()) {
|
||||
changed |= mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)];
|
||||
mqttGroupName = settings[FPSTR(FP_CONFIG_GROUP)].as<std::string>();
|
||||
}
|
||||
|
||||
if(mqttGroupName.length() == 0) {
|
||||
mqttGroupName = "plates";
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_HOST)].isNull()) {
|
||||
LOG_VERBOSE(TAG_MQTT, "%s => %s", FP_CONFIG_HOST, settings[FPSTR(FP_CONFIG_HOST)].as<const char*>());
|
||||
changed |= mqttServer != settings[FPSTR(FP_CONFIG_HOST)];
|
||||
mqttServer = settings[FPSTR(FP_CONFIG_HOST)].as<const char*>();
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_USER)].isNull()) {
|
||||
changed |= mqttUsername != settings[FPSTR(FP_CONFIG_USER)];
|
||||
mqttUsername = settings[FPSTR(FP_CONFIG_USER)].as<const char*>();
|
||||
}
|
||||
|
||||
if(!settings[FPSTR(FP_CONFIG_PASS)].isNull() &&
|
||||
settings[FPSTR(FP_CONFIG_PASS)].as<std::string>() != D_PASSWORD_MASK) {
|
||||
changed |= mqttPassword != settings[FPSTR(FP_CONFIG_PASS)];
|
||||
mqttPassword = settings[FPSTR(FP_CONFIG_PASS)].as<const char*>();
|
||||
}
|
||||
|
||||
mqttNodeTopic = MQTT_PREFIX;
|
||||
mqttNodeTopic += haspDevice.get_hostname();
|
||||
mqttGroupTopic = MQTT_PREFIX;
|
||||
mqttGroupTopic += mqttGroupName;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
#endif // HASP_USE_PAHO
|
||||
#endif // USE_MQTT
|
||||
|
@ -5,15 +5,17 @@
|
||||
|
||||
#include "hasplib.h"
|
||||
|
||||
#if HASP_USE_MQTT > 0
|
||||
#if HASP_USE_MQTT > 0 && !HASP_USE_MQTT_ASYNC
|
||||
#ifdef HASP_USE_PAHO
|
||||
|
||||
#if !HASP_USE_CONFIG
|
||||
const char FP_CONFIG_HOST[] PROGMEM = "host";
|
||||
const char FP_CONFIG_PORT[] PROGMEM = "port";
|
||||
const char FP_CONFIG_NAME[] PROGMEM = "name";
|
||||
const char FP_CONFIG_USER[] PROGMEM = "user";
|
||||
const char FP_CONFIG_PASS[] PROGMEM = "pass";
|
||||
const char FP_CONFIG_GROUP[] PROGMEM = "group";
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012, 2020 IBM Corp.
|
||||
@ -411,6 +413,32 @@ void mqtt_get_info(JsonDocument& doc)
|
||||
info[F(D_INFO_FAILED)] = mqttFailedCount;
|
||||
}
|
||||
|
||||
bool mqttGetConfig(const JsonObject& settings)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if(strcmp(haspDevice.get_hostname(), settings[FPSTR(FP_CONFIG_NAME)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_NAME)] = haspDevice.get_hostname();
|
||||
|
||||
if(mqttGroupName != settings[FPSTR(FP_CONFIG_GROUP)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_GROUP)] = mqttGroupName;
|
||||
|
||||
if(mqttServer != settings[FPSTR(FP_CONFIG_HOST)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_HOST)] = mqttServer;
|
||||
|
||||
if(mqttPort != settings[FPSTR(FP_CONFIG_PORT)].as<uint16_t>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_PORT)] = mqttPort;
|
||||
|
||||
if(mqttUsername != settings[FPSTR(FP_CONFIG_USER)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_USER)] = mqttUsername;
|
||||
|
||||
if(mqttPassword != settings[FPSTR(FP_CONFIG_PASS)].as<String>()) changed = true;
|
||||
settings[FPSTR(FP_CONFIG_PASS)] = mqttPassword;
|
||||
|
||||
if(changed) configOutput(settings, TAG_MQTT);
|
||||
return changed;
|
||||
}
|
||||
|
||||
/** Set MQTT Configuration.
|
||||
*
|
||||
* Read the settings from json and sets the application variables.
|
||||
|
@ -5,8 +5,10 @@
|
||||
|
||||
#if HASP_USE_CONSOLE > 0
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
#include "ConsoleInput.h"
|
||||
#include <StreamUtils.h>
|
||||
#endif
|
||||
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_console.h"
|
||||
@ -17,15 +19,18 @@
|
||||
extern hasp_http_config_t http_config;
|
||||
#endif
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
// Create a new Stream that buffers all writes to serialClient
|
||||
HardwareSerial* bufferedSerialClient = (HardwareSerial*)&HASP_SERIAL;
|
||||
ConsoleInput* console;
|
||||
#endif
|
||||
|
||||
uint8_t consoleLoginState = CONSOLE_UNAUTHENTICATED;
|
||||
uint16_t serialPort = 0;
|
||||
uint8_t consoleEnabled = true; // Enable serial debug output
|
||||
uint8_t consoleLoginAttempt = 0; // Initial attempt
|
||||
ConsoleInput* console;
|
||||
|
||||
#if HASP_TARGET_ARDUINO
|
||||
void console_update_prompt()
|
||||
{
|
||||
if(console) console->update(__LINE__);
|
||||
@ -101,9 +106,21 @@ static void console_process_line(const char* input)
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif HASP_TARGET_PC
|
||||
static bool console_running = true;
|
||||
static void console_thread(void* arg)
|
||||
{
|
||||
while(console_running) {
|
||||
std::string input;
|
||||
std::getline(std::cin, input);
|
||||
dispatch_text_line(input.c_str(), TAG_CONS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void consoleStart()
|
||||
{
|
||||
#if HASP_TARGET_ARDUINO
|
||||
LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING));
|
||||
console = new ConsoleInput(bufferedSerialClient, HASP_CONSOLE_BUFFER);
|
||||
if(console) {
|
||||
@ -126,16 +143,27 @@ void consoleStart()
|
||||
console_logoff();
|
||||
LOG_ERROR(TAG_CONS, F(D_SERVICE_START_FAILED));
|
||||
}
|
||||
#elif HASP_TARGET_PC
|
||||
LOG_TRACE(TAG_MSGR, F(D_SERVICE_STARTING));
|
||||
haspDevice.run_thread(console_thread, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void consoleStop()
|
||||
{
|
||||
#if HASP_TARGET_ARDUINO
|
||||
console_logoff();
|
||||
Log.unregisterOutput(0); // serialClient
|
||||
HASP_SERIAL.end();
|
||||
|
||||
delete console;
|
||||
console = NULL;
|
||||
#elif HASP_TARGET_PC
|
||||
#if defined(WINDOWS)
|
||||
|
||||
#elif defined(POSIX)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void consoleSetup()
|
||||
@ -147,6 +175,7 @@ void consoleSetup()
|
||||
|
||||
IRAM_ATTR void consoleLoop()
|
||||
{
|
||||
#if HASP_TARGET_ARDUINO
|
||||
if(!console) return;
|
||||
|
||||
bool update = false;
|
||||
@ -168,13 +197,14 @@ IRAM_ATTR void consoleLoop()
|
||||
case 0:
|
||||
case -1:
|
||||
break;
|
||||
|
||||
|
||||
default: {
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(update) console_update_prompt();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HASP_USE_CONFIG > 0
|
||||
@ -201,4 +231,4 @@ bool consoleSetConfig(const JsonObject& settings)
|
||||
}
|
||||
#endif // HASP_USE_CONFIG
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -4,10 +4,10 @@
|
||||
#ifndef HASP_CONSOLE_H
|
||||
#define HASP_CONSOLE_H
|
||||
|
||||
#if HASP_USE_CONSOLE > 0
|
||||
|
||||
#include "hasplib.h"
|
||||
|
||||
#if HASP_USE_CONSOLE > 0
|
||||
|
||||
/* ===== Default Event Processors ===== */
|
||||
void consoleSetup();
|
||||
IRAM_ATTR void consoleLoop(void);
|
||||
|
@ -2,6 +2,9 @@
|
||||
For full license information read the LICENSE file in the project folder */
|
||||
|
||||
#include "hasplib.h"
|
||||
|
||||
#if HASP_USE_HTTP > 0
|
||||
|
||||
#include "ArduinoLog.h"
|
||||
|
||||
#define HTTP_LEGACY
|
||||
@ -21,7 +24,6 @@
|
||||
#include "hasp_gui.h"
|
||||
#include "hasp_debug.h"
|
||||
|
||||
#if HASP_USE_HTTP > 0
|
||||
#include "sys/net/hasp_network.h"
|
||||
#include "sys/net/hasp_time.h"
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
//#include "webServer.h"
|
||||
#include "hasplib.h"
|
||||
|
||||
#if HASP_USE_HTTP_ASYNC > 0
|
||||
|
||||
#include "ArduinoLog.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
@ -16,7 +19,6 @@
|
||||
#include "hasp_gui.h"
|
||||
#include "hasp_debug.h"
|
||||
|
||||
#if HASP_USE_HTTP_ASYNC > 0
|
||||
#include "sys/net/hasp_network.h"
|
||||
|
||||
/* clang-format off */
|
||||
|
@ -1,4 +1,4 @@
|
||||
[env:darwin_sdl_64bits]
|
||||
[env:darwin_sdl]
|
||||
lib_archive = false
|
||||
platform = native@^1.1.4
|
||||
extra_scripts =
|
||||
@ -6,7 +6,8 @@ extra_scripts =
|
||||
tools/linux_build_extra.py
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D HASP_MODEL="MacOS X App"
|
||||
-D HASP_MODEL="MacOS X App"
|
||||
-D HASP_TARGET_PC=1
|
||||
|
||||
; ----- Monitor
|
||||
-D TFT_WIDTH=240
|
||||
@ -25,8 +26,8 @@ build_flags =
|
||||
-D HASP_USE_SPIFFS=0
|
||||
-D HASP_USE_LITTLEFS=0
|
||||
-D HASP_USE_EEPROM=0
|
||||
-D HASP_USE_GPIO=1
|
||||
-D HASP_USE_CONFIG=0 ; Standalone application, as library
|
||||
-D HASP_USE_GPIO=0
|
||||
-D HASP_USE_CONFIG=1
|
||||
-D HASP_USE_DEBUG=1
|
||||
-D HASP_USE_PNGDECODE=1
|
||||
-D HASP_USE_BMPDECODE=1
|
||||
@ -48,8 +49,8 @@ build_flags =
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_VERBOSE_MAKEFILE=TRUE
|
||||
;-D NO_PERSISTENCE
|
||||
-I.pio/libdeps/darwin_sdl_64bits/paho/src
|
||||
-I.pio/libdeps/darwin_sdl_64bits/ArduinoJson/src
|
||||
-I.pio/libdeps/darwin_sdl/paho/src
|
||||
-I.pio/libdeps/darwin_sdl/ArduinoJson/src
|
||||
-I lib/ArduinoJson/src
|
||||
-I lib/lv_fs_if
|
||||
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
|
||||
@ -84,21 +85,20 @@ lib_ignore =
|
||||
build_src_filter =
|
||||
+<*>
|
||||
-<*.h>
|
||||
+<../hal/sdl2>
|
||||
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/*.c>
|
||||
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.c>
|
||||
+<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTClient.h>
|
||||
-<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsync.c>
|
||||
-<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/darwin_sdl_64bits/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/darwin_sdl_64bits/paho/src/SSLSocket.c>
|
||||
+<MQTTClient.c>
|
||||
-<MQTTAsync.c>
|
||||
-<MQTTAsyncUtils.c>
|
||||
+<../.pio/libdeps/darwin_sdl/paho/src/*.c>
|
||||
-<../.pio/libdeps/darwin_sdl/paho/src/MQTTClient.c>
|
||||
+<../.pio/libdeps/darwin_sdl/paho/src/MQTTAsync.c>
|
||||
+<../.pio/libdeps/darwin_sdl/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/darwin_sdl/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/darwin_sdl/paho/src/SSLSocket.c>
|
||||
-<MQTTClient.c>
|
||||
+<MQTTAsync.c>
|
||||
+<MQTTAsyncUtils.c>
|
||||
-<MQTTVersion.c>
|
||||
-<SSLSocket.c>
|
||||
-<sys/>
|
||||
+<sys/gpio/>
|
||||
+<sys/svc/>
|
||||
-<hal/>
|
||||
+<drv/>
|
||||
-<drv/touch>
|
||||
@ -112,4 +112,4 @@ build_src_filter =
|
||||
+<lang/>
|
||||
-<log/>
|
||||
+<mqtt/>
|
||||
+<../.pio/libdeps/darwin_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
|
||||
+<../.pio/libdeps/darwin_sdl/ArduinoJson/src/ArduinoJson.h>
|
@ -35,6 +35,7 @@ files =
|
||||
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D HASP_TARGET_ARDUINO=1
|
||||
-D HTTP_UPLOAD_BUFLEN=1024 ; lower http upload buffer
|
||||
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
|
||||
-D HASP_CONSOLE_BUFFER=256 ; maximum length of a console/telnet command
|
||||
|
@ -12,6 +12,7 @@ board_build.f_cpu = 160000000L ; set frequency to 160MHz
|
||||
monitor_filters = esp8266_exception_decoder
|
||||
|
||||
build_flags=
|
||||
-D HASP_TARGET_ARDUINO=1
|
||||
-D HTTP_UPLOAD_BUFLEN=512 ; lower http upload buffer
|
||||
-D MQTT_MAX_PACKET_SIZE=1024 ; longer PubSubClient messages
|
||||
-D HASP_CONSOLE_BUFFER=160 ; maximum length of a console/telnet command
|
||||
|
101
user_setups/linux/linux_fbdev.ini
Normal file
101
user_setups/linux/linux_fbdev.ini
Normal file
@ -0,0 +1,101 @@
|
||||
[env:linux_fbdev]
|
||||
platform = native@^1.1.4
|
||||
extra_scripts =
|
||||
tools/linux_build_extra.py
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D HASP_MODEL="Linux App"
|
||||
-D HASP_TARGET_PC=1
|
||||
|
||||
; ----- Monitor
|
||||
-D TFT_WIDTH=240
|
||||
-D TFT_HEIGHT=320
|
||||
; SDL drivers options
|
||||
;-D LV_LVGL_H_INCLUDE_SIMPLE
|
||||
;-D LV_DRV_NO_CONF
|
||||
-D USE_FBDEV
|
||||
-D USE_EVDEV
|
||||
; ----- ArduinoJson
|
||||
-D ARDUINOJSON_DECODE_UNICODE=1
|
||||
-D HASP_NUM_PAGES=12
|
||||
-D HASP_USE_SPIFFS=0
|
||||
-D HASP_USE_LITTLEFS=0
|
||||
-D LV_USE_FS_IF=1
|
||||
-D HASP_USE_EEPROM=0
|
||||
-D HASP_USE_GPIO=0
|
||||
-D HASP_USE_CONFIG=1
|
||||
-D HASP_USE_DEBUG=1
|
||||
-D HASP_USE_PNGDECODE=1
|
||||
-D HASP_USE_BMPDECODE=1
|
||||
-D HASP_USE_GIFDECODE=0
|
||||
-D HASP_USE_JPGDECODE=0
|
||||
-D HASP_USE_MQTT=1
|
||||
-D HASP_USE_LVGL_TASK=1
|
||||
-D MQTT_MAX_PACKET_SIZE=2048
|
||||
-D HASP_ATTRIBUTE_FAST_MEM=
|
||||
-D IRAM_ATTR= ; No IRAM_ATTR available
|
||||
-D PROGMEM= ; No PROGMEM available
|
||||
;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
|
||||
;-D LV_LOG_PRINTF=1
|
||||
; Add recursive dirs for hal headers search
|
||||
-D POSIX
|
||||
-D PAHO_MQTT_STATIC
|
||||
-DPAHO_WITH_SSL=TRUE
|
||||
-DPAHO_BUILD_DOCUMENTATION=FALSE
|
||||
-DPAHO_BUILD_SAMPLES=FALSE
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_VERBOSE_MAKEFILE=TRUE
|
||||
;-D NO_PERSISTENCE
|
||||
-I.pio/libdeps/linux_fbdev/paho/src
|
||||
-I.pio/libdeps/linux_fbdev/ArduinoJson/src
|
||||
|
||||
; ----- Statically linked libraries --------------------
|
||||
-lm
|
||||
-lpthread
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
;lv_drivers@~7.9.0
|
||||
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
|
||||
https://github.com/eclipse/paho.mqtt.c.git
|
||||
bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
|
||||
https://github.com/fvanroie/lv_drivers
|
||||
|
||||
lib_ignore =
|
||||
paho
|
||||
AXP192
|
||||
ArduinoLog
|
||||
lv_lib_qrcode
|
||||
ETHSPI
|
||||
|
||||
build_src_filter =
|
||||
+<*>
|
||||
-<*.h>
|
||||
+<../.pio/libdeps/linux_fbdev/paho/src/*.c>
|
||||
-<../.pio/libdeps/linux_fbdev/paho/src/MQTTClient.c>
|
||||
+<../.pio/libdeps/linux_fbdev/paho/src/MQTTAsync.c>
|
||||
+<../.pio/libdeps/linux_fbdev/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/linux_fbdev/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/linux_fbdev/paho/src/SSLSocket.c>
|
||||
-<MQTTClient.c>
|
||||
+<MQTTAsync.c>
|
||||
+<MQTTAsyncUtils.c>
|
||||
-<MQTTVersion.c>
|
||||
-<SSLSocket.c>
|
||||
-<sys/>
|
||||
+<sys/gpio/>
|
||||
+<sys/svc/>
|
||||
-<hal/>
|
||||
+<drv/>
|
||||
-<drv/touch>
|
||||
+<drv/tft>
|
||||
+<dev/>
|
||||
-<hal/>
|
||||
-<svc/>
|
||||
-<hasp_filesystem.cpp>
|
||||
+<font/>
|
||||
+<hasp/>
|
||||
+<lang/>
|
||||
-<log/>
|
||||
+<mqtt/>
|
||||
+<../.pio/libdeps/linux_fbdev/ArduinoJson/src/ArduinoJson.h>
|
@ -1,4 +1,4 @@
|
||||
[env:linux_sdl_64bits]
|
||||
[env:linux_sdl]
|
||||
platform = native@^1.1.4
|
||||
extra_scripts =
|
||||
tools/sdl2_build_extra.py
|
||||
@ -6,6 +6,7 @@ extra_scripts =
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D HASP_MODEL="Linux App"
|
||||
-D HASP_TARGET_PC=1
|
||||
|
||||
; ----- Monitor
|
||||
-D TFT_WIDTH=240
|
||||
@ -25,8 +26,8 @@ build_flags =
|
||||
-D HASP_USE_LITTLEFS=0
|
||||
-D LV_USE_FS_IF=1
|
||||
-D HASP_USE_EEPROM=0
|
||||
-D HASP_USE_GPIO=1
|
||||
-D HASP_USE_CONFIG=0 ; Standalone application, as library
|
||||
-D HASP_USE_GPIO=0
|
||||
-D HASP_USE_CONFIG=1
|
||||
-D HASP_USE_DEBUG=1
|
||||
-D HASP_USE_PNGDECODE=1
|
||||
-D HASP_USE_BMPDECODE=1
|
||||
@ -48,8 +49,8 @@ build_flags =
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_VERBOSE_MAKEFILE=TRUE
|
||||
;-D NO_PERSISTENCE
|
||||
-I.pio/libdeps/linux_sdl_64bits/paho/src
|
||||
-I.pio/libdeps/linux_sdl_64bits/ArduinoJson/src
|
||||
-I.pio/libdeps/linux_sdl/paho/src
|
||||
-I.pio/libdeps/linux_sdl/ArduinoJson/src
|
||||
|
||||
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
|
||||
; ----- Statically linked libraries --------------------
|
||||
@ -75,20 +76,20 @@ lib_ignore =
|
||||
build_src_filter =
|
||||
+<*>
|
||||
-<*.h>
|
||||
+<../hal/sdl2>
|
||||
+<../.pio/libdeps/linux_sdl_64bits/paho/src/*.c>
|
||||
+<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTClient.c>
|
||||
-<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsync.c>
|
||||
-<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/linux_sdl_64bits/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/linux_sdl_64bits/paho/src/SSLSocket.c>
|
||||
+<MQTTClient.c>
|
||||
-<MQTTAsync.c>
|
||||
-<MQTTAsyncUtils.c>
|
||||
+<../.pio/libdeps/linux_sdl/paho/src/*.c>
|
||||
-<../.pio/libdeps/linux_sdl/paho/src/MQTTClient.c>
|
||||
+<../.pio/libdeps/linux_sdl/paho/src/MQTTAsync.c>
|
||||
+<../.pio/libdeps/linux_sdl/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/linux_sdl/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/linux_sdl/paho/src/SSLSocket.c>
|
||||
-<MQTTClient.c>
|
||||
+<MQTTAsync.c>
|
||||
+<MQTTAsyncUtils.c>
|
||||
-<MQTTVersion.c>
|
||||
-<SSLSocket.c>
|
||||
-<sys/>
|
||||
+<sys/gpio/>
|
||||
+<sys/svc/>
|
||||
-<hal/>
|
||||
+<drv/>
|
||||
-<drv/touch>
|
||||
@ -102,4 +103,4 @@ build_src_filter =
|
||||
+<lang/>
|
||||
-<log/>
|
||||
+<mqtt/>
|
||||
+<../.pio/libdeps/linux_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
|
||||
+<../.pio/libdeps/linux_sdl/ArduinoJson/src/ArduinoJson.h>
|
@ -3,6 +3,7 @@
|
||||
framework = arduino
|
||||
platform = ststm32
|
||||
build_flags=
|
||||
-D HASP_TARGET_ARDUINO=1
|
||||
-I include/stm32f4
|
||||
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
|
||||
-D HASP_CONSOLE_BUFFER=220 ; maximum length of a console/telnet command
|
||||
@ -21,4 +22,4 @@ build_flags=
|
||||
|
||||
lib_deps =
|
||||
stm32duino/STM32duino LwIP @ ^2.1.2
|
||||
;https://github.com/stm32duino/LwIP.git
|
||||
;https://github.com/stm32duino/LwIP.git
|
||||
|
@ -3,6 +3,7 @@
|
||||
framework = arduino
|
||||
platform = ststm32
|
||||
build_flags=
|
||||
-D HASP_TARGET_ARDUINO=1
|
||||
; -I include/stm32f4
|
||||
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
|
||||
-D HASP_CONSOLE_BUFFER=220 ; maximum length of a console/telnet command
|
||||
|
131
user_setups/win32/windows_gdi.ini
Normal file
131
user_setups/win32/windows_gdi.ini
Normal file
@ -0,0 +1,131 @@
|
||||
[env:windows_gdi]
|
||||
platform = native@^1.1.4
|
||||
extra_scripts =
|
||||
tools/windows_build_extra.py
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D HASP_MODEL="Windows App"
|
||||
-D HASP_TARGET_PC=1
|
||||
|
||||
; ----- Monitor
|
||||
-D TFT_WIDTH=240
|
||||
-D TFT_HEIGHT=320
|
||||
; SDL drivers options
|
||||
;-D LV_LVGL_H_INCLUDE_SIMPLE
|
||||
;-D LV_DRV_NO_CONF
|
||||
-D USE_WIN32DRV
|
||||
; ----- ArduinoJson
|
||||
-D ARDUINOJSON_DECODE_UNICODE=1
|
||||
-D HASP_NUM_PAGES=12
|
||||
-D HASP_USE_SPIFFS=0
|
||||
-D HASP_USE_LITTLEFS=0
|
||||
-D HASP_USE_EEPROM=0
|
||||
-D HASP_USE_GPIO=0
|
||||
-D HASP_USE_CONFIG=1
|
||||
-D HASP_USE_DEBUG=1
|
||||
-D HASP_USE_PNGDECODE=1
|
||||
-D HASP_USE_BMPDECODE=1
|
||||
-D HASP_USE_GIFDECODE=0
|
||||
-D HASP_USE_JPGDECODE=0
|
||||
-D HASP_USE_MQTT=1
|
||||
-D HASP_USE_SYSLOG=0
|
||||
-D HASP_USE_LVGL_TASK=1
|
||||
-D MQTT_MAX_PACKET_SIZE=2048
|
||||
-D HASP_ATTRIBUTE_FAST_MEM=
|
||||
-D IRAM_ATTR= ; No IRAM_ATTR available
|
||||
-D PROGMEM= ; No PROGMEM available
|
||||
|
||||
; -- FreeType build options ------------------------
|
||||
-D LV_USE_FT_CACHE_MANAGER=1 ; crashes without cache
|
||||
-D LVGL_FREETYPE_MAX_FACES=64 ; max number of FreeType faces in cache
|
||||
-D LVGL_FREETYPE_MAX_SIZES=4 ; max number of sizes in cache
|
||||
-D LVGL_FREETYPE_MAX_BYTES=16384 ; max bytes in cache
|
||||
-D LVGL_FREETYPE_MAX_BYTES_PSRAM=65536 ; max bytes in cache when using PSRAM
|
||||
|
||||
;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
|
||||
;-D LV_LOG_PRINTF=1
|
||||
; Add recursive dirs for hal headers search
|
||||
-D _WIN64
|
||||
-D WINDOWS ; We add this ourselves for code branching in hasp
|
||||
-D WIN32_LEAN_AND_MEAN ; exclude a bunch of Windows header files from windows.h
|
||||
-D PAHO_MQTT_STATIC
|
||||
-DPAHO_WITH_SSL=TRUE
|
||||
-DPAHO_BUILD_DOCUMENTATION=FALSE
|
||||
-DPAHO_BUILD_SAMPLES=FALSE
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_VERBOSE_MAKEFILE=TRUE
|
||||
;-D NO_PERSISTENCE
|
||||
-I.pio/libdeps/windows_gdi/paho/src
|
||||
-I.pio/libdeps/windows_gdi/ArduinoJson/src
|
||||
-I lib/lv_fs_if
|
||||
-I lib/lv_datetime
|
||||
-mconsole
|
||||
; ----- Statically linked libraries --------------------
|
||||
-l"ws2_32" ;windsock2
|
||||
-lrpcrt4
|
||||
-lcrypt32
|
||||
-lmingw32
|
||||
-lm
|
||||
-ldinput8
|
||||
;-ldxguid
|
||||
;-ldxerr8
|
||||
;-luser32
|
||||
-lgdi32
|
||||
-lwinmm
|
||||
-limm32
|
||||
-lole32
|
||||
-loleaut32
|
||||
;-lshell32
|
||||
-lversion
|
||||
;-luuid
|
||||
-lsetupapi
|
||||
-lshlwapi
|
||||
;-lhid
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
;lv_drivers@~7.9.0
|
||||
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
|
||||
https://github.com/eclipse/paho.mqtt.c.git
|
||||
bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser
|
||||
https://github.com/fvanroie/lv_drivers
|
||||
|
||||
lib_ignore =
|
||||
paho
|
||||
AXP192
|
||||
ArduinoLog
|
||||
lv_lib_qrcode
|
||||
ETHSPI
|
||||
|
||||
build_src_filter =
|
||||
+<*>
|
||||
-<*.h>
|
||||
+<../.pio/libdeps/windows_gdi/paho/src/*.c>
|
||||
-<../.pio/libdeps/windows_gdi/paho/src/MQTTClient.c>
|
||||
+<../.pio/libdeps/windows_gdi/paho/src/MQTTAsync.c>
|
||||
+<../.pio/libdeps/windows_gdi/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/windows_gdi/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/windows_gdi/paho/src/SSLSocket.c>
|
||||
-<MQTTClient.c>
|
||||
+<MQTTAsync.c>
|
||||
+<MQTTAsyncUtils.c>
|
||||
-<MQTTVersion.c>
|
||||
-<SSLSocket.c>
|
||||
-<sys/>
|
||||
+<sys/gpio/>
|
||||
+<sys/svc/>
|
||||
-<hal/>
|
||||
+<drv/>
|
||||
-<drv/touch>
|
||||
+<drv/tft>
|
||||
+<dev/>
|
||||
-<hal/>
|
||||
-<svc/>
|
||||
-<hasp_filesystem.cpp>
|
||||
+<font/>
|
||||
+<hasp/>
|
||||
+<lang/>
|
||||
-<log/>
|
||||
+<mqtt/>
|
||||
+<../.pio/libdeps/windows_gdi/ArduinoJson/src/ArduinoJson.h>
|
||||
+<lib/lv_datetime>
|
@ -1,4 +1,4 @@
|
||||
[env:windows_sdl_64bits]
|
||||
[env:windows_sdl]
|
||||
platform = native@^1.1.4
|
||||
extra_scripts =
|
||||
tools/sdl2_build_extra.py
|
||||
@ -6,6 +6,7 @@ extra_scripts =
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D HASP_MODEL="Windows App"
|
||||
-D HASP_TARGET_PC=1
|
||||
|
||||
; ----- Monitor
|
||||
-D TFT_WIDTH=240
|
||||
@ -24,8 +25,8 @@ build_flags =
|
||||
-D HASP_USE_SPIFFS=0
|
||||
-D HASP_USE_LITTLEFS=0
|
||||
-D HASP_USE_EEPROM=0
|
||||
-D HASP_USE_GPIO=1
|
||||
-D HASP_USE_CONFIG=0 ; Standalone application, as library
|
||||
-D HASP_USE_GPIO=0
|
||||
-D HASP_USE_CONFIG=1
|
||||
-D HASP_USE_DEBUG=1
|
||||
-D HASP_USE_PNGDECODE=1
|
||||
-D HASP_USE_BMPDECODE=1
|
||||
@ -58,8 +59,8 @@ build_flags =
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_VERBOSE_MAKEFILE=TRUE
|
||||
;-D NO_PERSISTENCE
|
||||
-I.pio/libdeps/windows_sdl_64bits/paho/src
|
||||
-I.pio/libdeps/windows_sdl_64bits/ArduinoJson/src
|
||||
-I.pio/libdeps/windows_sdl/paho/src
|
||||
-I.pio/libdeps/windows_sdl/ArduinoJson/src
|
||||
-I lib/lv_fs_if
|
||||
-I lib/lv_datetime
|
||||
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
|
||||
@ -71,13 +72,12 @@ build_flags =
|
||||
-lmingw32
|
||||
-lSDL2main
|
||||
-lSDL2
|
||||
-mwindows
|
||||
-lm
|
||||
-ldinput8
|
||||
;-ldxguid
|
||||
;-ldxerr8
|
||||
;-luser32
|
||||
;-lgdi32
|
||||
-lgdi32
|
||||
-lwinmm
|
||||
-limm32
|
||||
-lole32
|
||||
@ -106,20 +106,20 @@ lib_ignore =
|
||||
build_src_filter =
|
||||
+<*>
|
||||
-<*.h>
|
||||
+<../hal/sdl2>
|
||||
+<../.pio/libdeps/windows_sdl_64bits/paho/src/*.c>
|
||||
+<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTClient.c>
|
||||
-<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsync.c>
|
||||
-<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/windows_sdl_64bits/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/windows_sdl_64bits/paho/src/SSLSocket.c>
|
||||
+<MQTTClient.c>
|
||||
-<MQTTAsync.c>
|
||||
-<MQTTAsyncUtils.c>
|
||||
+<../.pio/libdeps/windows_sdl/paho/src/*.c>
|
||||
-<../.pio/libdeps/windows_sdl/paho/src/MQTTClient.c>
|
||||
+<../.pio/libdeps/windows_sdl/paho/src/MQTTAsync.c>
|
||||
+<../.pio/libdeps/windows_sdl/paho/src/MQTTAsyncUtils.c>
|
||||
-<../.pio/libdeps/windows_sdl/paho/src/MQTTVersion.c>
|
||||
-<../.pio/libdeps/windows_sdl/paho/src/SSLSocket.c>
|
||||
-<MQTTClient.c>
|
||||
+<MQTTAsync.c>
|
||||
+<MQTTAsyncUtils.c>
|
||||
-<MQTTVersion.c>
|
||||
-<SSLSocket.c>
|
||||
-<sys/>
|
||||
+<sys/gpio/>
|
||||
+<sys/svc/>
|
||||
-<hal/>
|
||||
+<drv/>
|
||||
-<drv/touch>
|
||||
@ -133,5 +133,5 @@ build_src_filter =
|
||||
+<lang/>
|
||||
-<log/>
|
||||
+<mqtt/>
|
||||
+<../.pio/libdeps/windows_sdl_64bits/ArduinoJson/src/ArduinoJson.h>
|
||||
+<../.pio/libdeps/windows_sdl/ArduinoJson/src/ArduinoJson.h>
|
||||
+<lib/lv_datetime>
|
Loading…
x
Reference in New Issue
Block a user