diff --git a/CMakeLists.txt b/CMakeLists.txt
index dab131b..ea5acde 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,8 +118,15 @@ if (LWS_OPENSSL_INCLUDE_DIRS)
set(CMAKE_C_FLAGS "-I\"${LWS_OPENSSL_INCLUDE_DIRS}\" ${CMAKE_C_FLAGS}")
endif()
-
-set(CMAKE_C_FLAGS "-DBUILD_INFO=\\\"${LWS_BUILD_HASH}\\\" ${CMAKE_C_FLAGS}")
+include_directories(${CMAKE_BINARY_DIR})
+add_custom_target(sai_git_hash ALL
+ COMMAND ${CMAKE_COMMAND}
+ -DCMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
+ -DCPACK_PACKAGE_VERSION=${CPACK_PACKAGE_VERSION}
+ -DOUTPUT_FILE=${CMAKE_BINARY_DIR}/sai-git-hash.h
+ -P ${CMAKE_SOURCE_DIR}/cmake/GetGitHash.cmake
+ BYPRODUCTS ${CMAKE_BINARY_DIR}/sai-git-hash.h
+)
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\nint
main(void) {\n#if defined(LWS_HAVE_LIBCAP)\n return
diff --git a/src/builder/CMakeLists.txt b/src/builder/CMakeLists.txt
index ee680f4..f27d026 100644
--- a/src/builder/CMakeLists.txt
+++ b/src/builder/CMakeLists.txt
@@ -29,6 +29,7 @@ require_lws_config(LWS_WITH_DIR 1 requirements)
if (requirements)
add_executable(${SUB} ${SRCS})
+add_dependencies(${SUB} sai_git_hash)
if (APPLE)
set_property(TARGET ${SUB} PROPERTY MACOSX_RPATH YES)
set(CMAKE_MACOSX_RPATH 1)
diff --git a/src/builder/b-conf.c b/src/builder/b-conf.c
index ce0d34a..1839dc9 100644
--- a/src/builder/b-conf.c
+++ b/src/builder/b-conf.c
@@ -25,6 +25,7 @@
#include <time.h>
#include <fcntl.h>
+#include "sai-git-hash.h"
#include "b-private.h"
/* global part */
@@ -43,6 +44,7 @@ static const char * const paths_global[] = {
"power-on.mac",
"power-off.type",
"power-off.url",
+ "power-monitor.url",
"rebuild_script_user",
"rebuild_script_root"
};
@@ -61,6 +63,7 @@ enum enum_paths_global {
LEJPM_POWER_ON_MAC,
LEJPM_POWER_OFF_TYPE,
LEJPM_POWER_OFF_URL,
+ LEJPM_POWER_MONITOR_URL,
LEJPM_REBUILD_SCRIPT_USER,
LEJPM_REBUILD_SCRIPT_ROOT
};
@@ -115,7 +118,7 @@ saib_conf_cb(struct lejp_ctx *ctx, char reason)
if (!a->sai_plat)
return -1;
- lws_strncpy(a->sai_plat->sai_hash, BUILD_INFO,
+ lws_strncpy(a->sai_plat->sai_hash, SAI_BUILD_INFO,
sizeof(a->sai_plat->sai_hash));
lws_strncpy(a->sai_plat->lws_hash, LWS_BUILD_HASH,
sizeof(a->sai_plat->lws_hash));
@@ -311,6 +314,9 @@ saib_conf_global_cb(struct lejp_ctx *ctx, char reason)
case LEJPM_POWER_OFF_URL:
pp = &a->builder->power_off_url;
break;
+ case LEJPM_POWER_MONITOR_URL:
+ pp = &a->builder->power_monitor_url;
+ break;
case LEJPM_REBUILD_SCRIPT_USER:
pp = &a->builder->rebuild_script_user;
diff --git a/src/builder/b-power.c b/src/builder/b-power.c
index 37f14d1..1422fec 100644
--- a/src/builder/b-power.c
+++ b/src/builder/b-power.c
@@ -75,6 +75,14 @@ saib_power_client_state(void *userobj, void *sh, lws_ss_constate_t state,
(unsigned int)ack);
switch (state) {
+ case LWSSSCS_CREATING:
+ lwsl_notice("%s: CREATING sai-power client connection to %s\n", __func__, builder.url_sai_power);
+ if (lws_ss_set_metadata((struct lws_ss_handle *)sh, "url",
+ builder.url_sai_power,
+ strlen(builder.url_sai_power)))
+ lwsl_err("%s: failed to set metadata\n", __func__);
+ break;
+
case LWSSSCS_CONNECTED:
lwsl_notice("%s: Connected to sai-power, sending registration: '%s' '%s'\n", __func__, builder.host, builder.power_controller_name);
@@ -87,6 +95,19 @@ saib_power_client_state(void *userobj, void *sh, lws_ss_constate_t state,
else
lws_strncpy(r.power_controller_name, "unknown", sizeof(r.power_controller_name));
+ if (builder.power_on_type)
+ lws_strncpy(r.power_on_type, builder.power_on_type, sizeof(r.power_on_type));
+ if (builder.power_on_url)
+ lws_strncpy(r.power_on_url, builder.power_on_url, sizeof(r.power_on_url));
+ if (builder.power_on_mac)
+ lws_strncpy(r.power_on_mac, builder.power_on_mac, sizeof(r.power_on_mac));
+ if (builder.power_off_type)
+ lws_strncpy(r.power_off_type, builder.power_off_type, sizeof(r.power_off_type));
+ if (builder.power_off_url)
+ lws_strncpy(r.power_off_url, builder.power_off_url, sizeof(r.power_off_url));
+ if (builder.power_monitor_url)
+ lws_strncpy(r.power_monitor_url, builder.power_monitor_url, sizeof(r.power_monitor_url));
+
/* Add platforms */
lws_start_foreach_dll(struct lws_dll2 *, d, builder.sai_plat_owner.head) {
sai_plat_t *sp = lws_container_of(d, sai_plat_t, sai_plat_list);
@@ -112,6 +133,10 @@ saib_power_client_state(void *userobj, void *sh, lws_ss_constate_t state,
lws_buflist_destroy_all_segments(&g->bl_tx);
break;
+ case LWSSSCS_ALL_RETRIES_FAILED:
+ lwsl_err("%s: Failed to connect to sai-power\n", __func__);
+ break;
+
default:
break;
}
diff --git a/src/builder/b-private.h b/src/builder/b-private.h
index f61c09b..5b1ac65 100644
--- a/src/builder/b-private.h
+++ b/src/builder/b-private.h
@@ -136,6 +136,7 @@ struct sai_builder {
const char *power_on_type;
const char *power_on_url;
const char *power_on_mac;
+ const char *power_monitor_url;
const char *home; /* home dir, usually /sai/home */
const char *perms; /* user:group */
diff --git a/src/builder/b-task.c b/src/builder/b-task.c
index cde9996..43f0e5f 100644
--- a/src/builder/b-task.c
+++ b/src/builder/b-task.c
@@ -25,6 +25,7 @@
#include <fcntl.h>
#include <errno.h>
+#include "sai-git-hash.h"
#include "b-private.h"
const char *git_helper_sh =
@@ -910,7 +911,7 @@ saib_consider_allocating_task(struct sai_plat_server *spm, lws_struct_args_t *a,
ml = lws_snprintf(mb, sizeof(mb),
">saib> Sai Builder Version: %s, lws: %s\n",
- BUILD_INFO, LWS_BUILD_HASH);
+ SAI_BUILD_INFO, LWS_BUILD_HASH);
saib_log_chunk_create(ns, mb, (unsigned int)ml, 3);
}
diff --git a/src/common/c-sqlite3.c b/src/common/c-sqlite3.c
index bf91b12..e007d33 100644
--- a/src/common/c-sqlite3.c
+++ b/src/common/c-sqlite3.c
@@ -20,6 +20,7 @@
*/
#include <libwebsockets.h>
+#include <sqlite3.h>
#include <assert.h>
diff --git a/src/common/include/private.h b/src/common/include/private.h
index eb4f709..abe9970 100644
--- a/src/common/include/private.h
+++ b/src/common/include/private.h
@@ -622,6 +622,12 @@ typedef struct sai_power_controller {
char name[64];
char type[32];
char depends_on[64];
+ char power_on_type[16];
+ char power_on_url[128];
+ char power_on_mac[24];
+ char power_off_type[16];
+ char power_off_url[128];
+ char power_monitor_url[128];
unsigned int on;
unsigned int manual_on;
} sai_power_controller_t;
@@ -658,6 +664,12 @@ typedef struct sai_builder_registration {
lws_dll2_owner_t platforms_owner; /* sai_builder_platform_t */
char builder_name[64];
char power_controller_name[64];
+ char power_on_type[16];
+ char power_on_url[128];
+ char power_on_mac[24];
+ char power_off_type[16];
+ char power_off_url[128];
+ char power_monitor_url[128];
} sai_builder_registration_t;
typedef struct tasmota_data {
@@ -703,7 +715,7 @@ extern const lws_struct_map_t
lsm_power_managed_builder[2],
lsm_power_managed_builders_list[2],
lsm_schema_power_managed_builders[1],
- lsm_power_controller[6],
+ lsm_power_controller[12],
lsm_schema_json_map_task[],
lsm_schema_sq3_map_task[],
lsm_schema_sq3_map_event[],
@@ -739,10 +751,11 @@ extern const lws_struct_map_t
lsm_build_metric[14],
lsm_plat[14], /* +1 for pcon */
lsm_builder_platform[1],
- lsm_builder_registration[3],
+ lsm_builder_registration[9],
lsm_schema_sq3_map_power_controller[1],
lsm_schema_sq3_map_controlled_builder[1],
lsm_schema_builder_registration[1],
+ lsm_schema_sq3_map_builder_registration[1],
lsm_pcon_energy_report[1],
lsm_schema_pcon_energy[1],
lsm_pcon_control[2],
diff --git a/src/common/struct-metadata.c b/src/common/struct-metadata.c
index a310e10..ddb98af 100644
--- a/src/common/struct-metadata.c
+++ b/src/common/struct-metadata.c
@@ -326,6 +326,12 @@ const lws_struct_map_t lsm_power_controller[] = {
LSM_CARRAY(sai_power_controller_t, name, "name"),
LSM_CARRAY(sai_power_controller_t, type, "type"),
LSM_CARRAY(sai_power_controller_t, depends_on, "depends_on"),
+ LSM_CARRAY(sai_power_controller_t, power_on_type, "power_on_type"),
+ LSM_CARRAY(sai_power_controller_t, power_on_url, "power_on_url"),
+ LSM_CARRAY(sai_power_controller_t, power_on_mac, "power_on_mac"),
+ LSM_CARRAY(sai_power_controller_t, power_off_type, "power_off_type"),
+ LSM_CARRAY(sai_power_controller_t, power_off_url, "power_off_url"),
+ LSM_CARRAY(sai_power_controller_t, power_monitor_url, "power_monitor_url"),
LSM_UNSIGNED(sai_power_controller_t, on, "on"),
LSM_UNSIGNED(sai_power_controller_t, manual_on, "manual_on"),
LSM_LIST(sai_power_controller_t, controlled_builders_owner,
@@ -338,6 +344,12 @@ const lws_struct_map_t lsm_sq3_power_controller[] = {
LSM_CARRAY(sai_power_controller_t, name, "name"),
LSM_CARRAY(sai_power_controller_t, type, "type"),
LSM_CARRAY(sai_power_controller_t, depends_on, "depends_on"),
+ LSM_CARRAY(sai_power_controller_t, power_on_type, "power_on_type"),
+ LSM_CARRAY(sai_power_controller_t, power_on_url, "power_on_url"),
+ LSM_CARRAY(sai_power_controller_t, power_on_mac, "power_on_mac"),
+ LSM_CARRAY(sai_power_controller_t, power_off_type, "power_off_type"),
+ LSM_CARRAY(sai_power_controller_t, power_off_url, "power_off_url"),
+ LSM_CARRAY(sai_power_controller_t, power_monitor_url, "power_monitor_url"),
LSM_UNSIGNED(sai_power_controller_t, on, "state"),
};
@@ -391,6 +403,12 @@ const lws_struct_map_t lsm_builder_registration[] = {
lsm_builder_platform, "platforms"),
LSM_CARRAY(sai_builder_registration_t, builder_name, "builder_name"),
LSM_CARRAY(sai_builder_registration_t, power_controller_name, "power_controller_name"),
+ LSM_CARRAY(sai_builder_registration_t, power_on_type, "power_on_type"),
+ LSM_CARRAY(sai_builder_registration_t, power_on_url, "power_on_url"),
+ LSM_CARRAY(sai_builder_registration_t, power_on_mac, "power_on_mac"),
+ LSM_CARRAY(sai_builder_registration_t, power_off_type, "power_off_type"),
+ LSM_CARRAY(sai_builder_registration_t, power_off_url, "power_off_url"),
+ LSM_CARRAY(sai_builder_registration_t, power_monitor_url, "power_monitor_url"),
};
const lws_struct_map_t lsm_schema_builder_registration[] = {
@@ -399,6 +417,22 @@ const lws_struct_map_t lsm_schema_builder_registration[] = {
"com.warmcat.sai.builder_registration"),
};
+const lws_struct_map_t lsm_sq3_builder_registration[] = {
+ LSM_CARRAY(sai_builder_registration_t, builder_name, "builder_name"),
+ LSM_CARRAY(sai_builder_registration_t, power_controller_name, "power_controller_name"),
+ LSM_CARRAY(sai_builder_registration_t, power_on_type, "power_on_type"),
+ LSM_CARRAY(sai_builder_registration_t, power_on_url, "power_on_url"),
+ LSM_CARRAY(sai_builder_registration_t, power_on_mac, "power_on_mac"),
+ LSM_CARRAY(sai_builder_registration_t, power_off_type, "power_off_type"),
+ LSM_CARRAY(sai_builder_registration_t, power_off_url, "power_off_url"),
+ LSM_CARRAY(sai_builder_registration_t, power_monitor_url, "power_monitor_url"),
+};
+
+const lws_struct_map_t lsm_schema_sq3_map_builder_registration[] = {
+ LSM_SCHEMA_DLL2(sai_builder_registration_t, list, NULL,
+ lsm_sq3_builder_registration, "builder_registrations"),
+};
+
static const lws_struct_map_t lsm_pcon_energy_item[] = {
LSM_CARRAY (sai_pcon_energy_report_item_t, name, "name"),
LSM_UNSIGNED (sai_pcon_energy_report_item_t, data.voltage_v, "voltage_v"),
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
index a69acb2..9142373 100644
--- a/src/device/CMakeLists.txt
+++ b/src/device/CMakeLists.txt
@@ -17,6 +17,7 @@ require_lws_config(LWS_WITH_DIR 1 requirements)
if (requirements)
add_executable("sai-device" ${SRCS})
+add_dependencies("sai-device" sai_git_hash)
if (APPLE)
set_property(TARGET sai-device PROPERTY MACOSX_RPATH YES)
endif()
diff --git a/src/expect/CMakeLists.txt b/src/expect/CMakeLists.txt
index 84dc913..0386ac9 100644
--- a/src/expect/CMakeLists.txt
+++ b/src/expect/CMakeLists.txt
@@ -24,6 +24,7 @@ if (requirements AND NOT MSVC)
endif()
add_executable("sai-expect" ${SRCS})
+add_dependencies("sai-expect" sai_git_hash)
if (APPLE)
set_property(TARGET sai-expect PROPERTY MACOSX_RPATH YES)
endif()
diff --git a/src/jig/CMakeLists.txt b/src/jig/CMakeLists.txt
index c007c9b..0305956 100644
--- a/src/jig/CMakeLists.txt
+++ b/src/jig/CMakeLists.txt
@@ -24,6 +24,7 @@ if (requirements)
include_directories(BEFORE "${GPIOD_INC_PATH}")
add_executable("sai-jig" ${SRCS})
+add_dependencies("sai-jig" sai_git_hash)
target_link_libraries("sai-jig" ${GPIOD_LIB_PATH})
if (APPLE)
diff --git a/src/power/CMakeLists.txt b/src/power/CMakeLists.txt
index ac91e4a..6c312e0 100644
--- a/src/power/CMakeLists.txt
+++ b/src/power/CMakeLists.txt
@@ -11,6 +11,7 @@ set(SRCS
p-tasmota-monitor.c
../common/c-utils.c
../common/struct-metadata.c
+ ../common/c-sqlite3.c
)
set(requirements 1)
@@ -20,10 +21,12 @@ require_lws_config(LWS_WITH_STRUCT_JSON 1 requirements)
require_lws_config(LWS_WITH_SECURE_STREAMS 1 requirements)
require_lws_config(LWS_WITH_DIR 1 requirements)
require_lws_config(LWS_WITH_WOL 1 requirements)
+require_lws_config(LWS_WITH_STRUCT_SQLITE3 1 requirements)
if (requirements)
add_executable(${SUB} ${SRCS})
+add_dependencies(${SUB} sai_git_hash)
if (APPLE)
set_property(TARGET ${SUB} PROPERTY MACOSX_RPATH YES)
endif()
@@ -36,7 +39,7 @@ if (requirements)
find_library(CAP_LIB_PATH NAMES "cap")
endif()
- target_link_libraries(${SUB} websockets ${SAI_LWS_LIB_PATH})
+ target_link_libraries(${SUB} websockets sqlite3 ${SAI_LWS_LIB_PATH})
message("LWS_OPENSSL_LIBRARIES ${SUB} '${LWS_OPENSSL_LIBRARIES}'")
if (LWS_OPENSSL_LIBRARIES)
diff --git a/src/power/p-conf.c b/src/power/p-conf.c
index 0e8da54..a5dddc4 100644
--- a/src/power/p-conf.c
+++ b/src/power/p-conf.c
@@ -32,38 +32,16 @@
static const char * const paths_global[] = {
"perms",
"wol-if",
+ "database",
"servers[].url",
- "servers[].power_controllers[].name",
- "servers[].power_controllers[].type",
- "servers[].power_controllers[].url",
- "servers[].power_controllers[].mac",
- "servers[].power_controllers[].depends_on",
- "servers[].power_controllers[]",
- "power_controllers[].name",
- "power_controllers[].type",
- "power_controllers[].url",
- "power_controllers[].mac",
- "power_controllers[].depends_on",
- "power_controllers[]",
"servers[]"
};
enum enum_paths_global {
LEJPM_PERMS,
LEJPM_WOL_IF,
+ LEJPM_DATABASE,
LEJPM_SERVERS_URL,
- LEJPM_SRV_PCON_NAME,
- LEJPM_SRV_PCON_TYPE,
- LEJPM_SRV_PCON_URL,
- LEJPM_SRV_PCON_MAC,
- LEJPM_SRV_PCON_DEPENDS_ON,
- LEJPM_SRV_PCON,
- LEJPM_PCON_NAME,
- LEJPM_PCON_TYPE,
- LEJPM_PCON_URL,
- LEJPM_PCON_MAC,
- LEJPM_PCON_DEPENDS_ON,
- LEJPM_PCON,
LEJPM_SERVERS
};
@@ -93,21 +71,6 @@ saip_conf_global_cb(struct lejp_ctx *ctx, char reason)
&a->power->sai_server_owner);
break;
- case LEJPM_PCON:
- case LEJPM_SRV_PCON:
- /*
- * Create the saip_pcon_t object
- */
- a->sai_pcon = lwsac_use_zero(&a->power->ac_conf_head,
- sizeof(*a->sai_pcon), 4096);
- if (!a->sai_pcon)
- return -1;
-
- /* We will link dependencies later */
- lws_dll2_add_tail(&a->sai_pcon->list,
- &a->power->sai_pcon_owner);
- break;
-
default:
return 0;
}
@@ -132,29 +95,8 @@ saip_conf_global_cb(struct lejp_ctx *ctx, char reason)
pp = &a->power->wol_if;
break;
- case LEJPM_PCON_NAME:
- case LEJPM_SRV_PCON_NAME:
- pp = &a->sai_pcon->name;
- break;
-
- case LEJPM_PCON_TYPE:
- case LEJPM_SRV_PCON_TYPE:
- pp = &a->sai_pcon->type;
- break;
-
- case LEJPM_PCON_URL:
- case LEJPM_SRV_PCON_URL:
- pp = &a->sai_pcon->url;
- break;
-
- case LEJPM_PCON_MAC:
- case LEJPM_SRV_PCON_MAC:
- pp = &a->sai_pcon->mac;
- break;
-
- case LEJPM_PCON_DEPENDS_ON:
- case LEJPM_SRV_PCON_DEPENDS_ON:
- pp = &a->sai_pcon->depends_on;
+ case LEJPM_DATABASE:
+ pp = &a->power->database;
break;
case LEJPM_SERVERS_URL:
diff --git a/src/power/p-http-api.c b/src/power/p-http-api.c
index 45d70ee..30d27d3 100644
--- a/src/power/p-http-api.c
+++ b/src/power/p-http-api.c
@@ -97,8 +97,8 @@ saip_builder_bringup(saip_server_t *sps, saip_pcon_t *pc)
{
saip_notify_server_power_state(pc->name, 1, 0);
- if (pc->type && !strcmp(pc->type, "wol")) {
- if (pc->mac) {
+ if (pc->type[0] && !strcmp(pc->type, "wol")) {
+ if (pc->mac[0]) {
lwsl_notice("%s: triggering WOL for %s\n", __func__, pc->name);
#if defined(LWS_WITH_SPAWN)
write(lws_spawn_get_fd_stdxxx(lsp_wol, 0),
@@ -301,6 +301,42 @@ local_srv_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
}
if (pc) {
+ /* update dynamic info */
+ if (r->power_on_type[0])
+ lws_strncpy(pc->type, r->power_on_type, sizeof(pc->type));
+ if (r->power_on_url[0])
+ lws_strncpy(pc->url_on, r->power_on_url, sizeof(pc->url_on));
+ if (r->power_on_mac[0])
+ lws_strncpy(pc->mac, r->power_on_mac, sizeof(pc->mac));
+ if (r->power_off_url[0])
+ lws_strncpy(pc->url_off, r->power_off_url, sizeof(pc->url_off));
+ if (r->power_monitor_url[0])
+ lws_strncpy(pc->url_monitor, r->power_monitor_url, sizeof(pc->url_monitor));
+
+ saip_ss_create_pcon_streams(pc);
+
+#if defined(LWS_WITH_STRUCT_SQLITE3)
+ if (power.pdb) {
+ char q[256], esc[128];
+ struct lws_dll2_owner o;
+
+ lws_dll2_owner_clear(&o);
+ lws_dll2_add_tail(&r->list, &o);
+
+ lws_sql_purify(esc, r->builder_name, sizeof(esc));
+ lws_snprintf(q, sizeof(q), "DELETE FROM builder_registrations WHERE builder_name='%s'", esc);
+ sai_sqlite3_statement(power.pdb, q, "delete sticky reg");
+
+ if (lws_struct_sq3_serialize(power.pdb, lsm_schema_sq3_map_builder_registration, &o, 0))
+ lwsl_err("%s: Failed to serialize sticky reg\n", __func__);
+ else
+ lwsl_notice("%s: Successfully serialized sticky reg for %s\n", __func__, r->builder_name);
+
+ lws_dll2_remove(&r->list);
+ }
+#endif
+
+
/* Check if builder already exists */
int found = 0;
lws_start_foreach_dll(struct lws_dll2 *, b_node, pc->registered_builders_owner.head) {
@@ -456,7 +492,7 @@ local_srv_state(void *userobj, void *sh, lws_ss_constate_t state,
saip_notify_server_power_state(pc->name, 1, 0);
- if (pc->mac) {
+ if (pc->mac[0]) {
#if defined(LWS_WITH_SPAWN)
if (write(lws_spawn_get_fd_stdxxx(lsp_wol, 0),
pc->mac, strlen(pc->mac)) !=
diff --git a/src/power/p-private.h b/src/power/p-private.h
index 0c56d0d..fe50aeb 100644
--- a/src/power/p-private.h
+++ b/src/power/p-private.h
@@ -64,9 +64,9 @@ typedef struct saip_pcon {
const char *depends_on; /* name from config */
const char *name;
- const char *type;
- const char *url;
- const char *mac; /* For WOL */
+ char type[32];
+ char url[128];
+ char mac[24]; /* For WOL */
char url_on[128];
char url_off[128];
@@ -142,6 +142,9 @@ struct sai_power {
const char *power_off;
const char *wol_if;
+ const char *database;
+
+ struct sqlite3 *pdb;
const char *bind; /* listen socket binding */
const char *perms; /* user:group */
@@ -200,7 +203,7 @@ int
saip_parse_tasmota_status(tasmota_parse_t *tp);
void
-saip_ss_create_tasmota(void);
+saip_ss_create_pcon_streams(saip_pcon_t *pc);
void
saip_pcon_start_check(void);
diff --git a/src/power/p-sai.c b/src/power/p-sai.c
index de7c4a5..fba4a73 100644
--- a/src/power/p-sai.c
+++ b/src/power/p-sai.c
@@ -286,7 +286,7 @@ sul_broadcast_energy_cb(lws_sorted_usec_list_t *sul)
} lws_end_foreach_dll(p);
if (!polled)
- lwsl_notice("%s: No PCONs polled\n", __func__);
+ lwsl_info("%s: No PCONs polled\n", __func__);
/* 2. Queue energy report to server (sends whatever latest data we have) */
/* We iterate servers, though usually only one */
@@ -536,7 +536,47 @@ int main(int argc, const char **argv)
goto bail;
}
- saip_ss_create_tasmota();
+ if (power.database) {
+ if (lws_struct_sq3_open(power.context, power.database, 1, &power.pdb)) {
+ lwsl_err("%s: Failed to open sqlite3 db %s\n", __func__, power.database);
+ } else {
+ if (lws_struct_sq3_create_table(power.pdb, lsm_schema_sq3_map_builder_registration)) {
+ lwsl_err("%s: Failed to create builder_registrations table\n", __func__);
+ } else {
+ /* deserialize existing sticky registrations */
+ struct lws_dll2_owner temp_owner;
+ struct lwsac *ac = NULL;
+
+ lws_dll2_owner_clear(&temp_owner);
+ if (lws_struct_sq3_deserialize(power.pdb, "",
+ NULL, lsm_schema_sq3_map_builder_registration,
+ &temp_owner, &ac, 0, 100) >= 0) {
+ /* Create PCONs for them */
+ lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1, temp_owner.head) {
+ sai_builder_registration_t *r = lws_container_of(p, sai_builder_registration_t, list);
+
+ lwsl_notice("%s: Sticky registration found for PCON %s\n", __func__, r->power_controller_name);
+ saip_pcon_t *pc = saip_pcon_create(&power, r->power_controller_name);
+ if (pc) {
+ if (r->power_on_type[0])
+ lws_strncpy(pc->type, r->power_on_type, sizeof(pc->type));
+ if (r->power_on_url[0])
+ lws_strncpy(pc->url_on, r->power_on_url, sizeof(pc->url_on));
+ if (r->power_on_mac[0])
+ lws_strncpy(pc->mac, r->power_on_mac, sizeof(pc->mac));
+ if (r->power_off_url[0])
+ lws_strncpy(pc->url_off, r->power_off_url, sizeof(pc->url_off));
+ if (r->power_monitor_url[0])
+ lws_strncpy(pc->url_monitor, r->power_monitor_url, sizeof(pc->url_monitor));
+
+ saip_ss_create_pcon_streams(pc);
+ }
+ } lws_end_foreach_dll_safe(p, p1);
+ }
+ lwsac_free(&ac);
+ }
+ }
+ }
#if defined(LWS_WITH_SPAWN)
{
diff --git a/src/power/p-smartplug.c b/src/power/p-smartplug.c
index f2265aa..1b0b49f 100644
--- a/src/power/p-smartplug.c
+++ b/src/power/p-smartplug.c
@@ -132,40 +132,31 @@ LWS_SS_INFO("sai_power_smartplug", saip_smartplug_t)
};
void
-saip_ss_create_tasmota()
+saip_ss_create_pcon_streams(saip_pcon_t *pc)
{
- /* let's create any needed tasmota ss */
-
- lws_start_foreach_dll(struct lws_dll2 *, px, power.sai_pcon_owner.head) {
- saip_pcon_t *pc = lws_container_of(px, saip_pcon_t, list);
-
- if (pc->type && !strcmp(pc->type, "tasmota") && pc->url) {
- lws_snprintf(pc->url_on, sizeof(pc->url_on),
- "%s/cm?cmnd=Power%%20On", pc->url);
- if (lws_ss_create(power.context, 0, &ssi_saip_smartplug_t,
- (void *)pc,
- &pc->ss_tasmota_on, NULL, NULL))
- lwsl_err("%s: %s: failed to create ON smartplug secure stream %s\n",
- __func__, pc->name, pc->url_on);
-
- lws_snprintf(pc->url_off, sizeof(pc->url_off),
- "%s/cm?cmnd=Power%%20Off", pc->url);
- if (lws_ss_create(power.context, 0, &ssi_saip_smartplug_t,
- (void *)pc,
- &pc->ss_tasmota_off, NULL, NULL))
- lwsl_err("%s: %s: failed to create OFF smartplug secure stream %s\n",
- __func__, pc->name, pc->url_off);
-
- lws_snprintf(pc->url_monitor, sizeof(pc->url_monitor),
- "%s/?m=1", pc->url);
- if (lws_ss_create(power.context, 0, &ssi_saip_smartplug_t,
- (void *)pc,
- &pc->ss_tasmota_monitor, NULL, NULL))
- lwsl_err("%s: %s: failed to create MONITOR smartplug secure stream %s\n",
- __func__, pc->name, pc->url_monitor);
- else
- lwsl_ss_warn(pc->ss_tasmota_monitor, "============================ creating monitor SS for %s", pc->url_monitor);
- }
+ /* let's create any needed smartplug ss */
+
+ if (pc->url_on[0] && !pc->ss_tasmota_on) {
+ if (lws_ss_create(power.context, 0, &ssi_saip_smartplug_t,
+ (void *)pc,
+ &pc->ss_tasmota_on, NULL, NULL))
+ lwsl_err("%s: %s: failed to create ON smartplug secure stream %s\n",
+ __func__, pc->name, pc->url_on);
+ }
- } lws_end_foreach_dll(px);
+ if (pc->url_off[0] && !pc->ss_tasmota_off) {
+ if (lws_ss_create(power.context, 0, &ssi_saip_smartplug_t,
+ (void *)pc,
+ &pc->ss_tasmota_off, NULL, NULL))
+ lwsl_err("%s: %s: failed to create OFF smartplug secure stream %s\n",
+ __func__, pc->name, pc->url_off);
+ }
+
+ if (pc->url_monitor[0] && !pc->ss_tasmota_monitor) {
+ if (lws_ss_create(power.context, 0, &ssi_saip_smartplug_t,
+ (void *)pc,
+ &pc->ss_tasmota_monitor, NULL, NULL))
+ lwsl_err("%s: %s: failed to create MONITOR smartplug secure stream %s\n",
+ __func__, pc->name, pc->url_monitor);
+ }
}
diff --git a/src/power/p-utils.c b/src/power/p-utils.c
index 4d64b7a..e239343 100644
--- a/src/power/p-utils.c
+++ b/src/power/p-utils.c
@@ -66,7 +66,8 @@ saip_switch(saip_pcon_t *pc, int on)
struct lws_ss_handle *h = on ? pc->ss_tasmota_on : pc->ss_tasmota_off;
int wol_fired = 0;
- if (on && pc->mac) {
+ if (on && pc->mac[0]) {
+#if defined(LWS_WITH_SPAWN)
char buf[64];
size_t n = (size_t)lws_snprintf(buf, sizeof(buf), "%s\n", pc->mac);
@@ -79,12 +80,15 @@ saip_switch(saip_pcon_t *pc, int on)
__func__, pc->name);
wol_fired = 1;
}
+#else
+ lwsl_notice("%s: WOL needed but LWS_WITH_SPAWN disabled\n", __func__);
+#endif
}
if (!h) {
if (!wol_fired) {
- if (pc->type && !strcmp(pc->type, "wol")) {
- if (on && !pc->mac)
+ if (pc->type[0] && !strcmp(pc->type, "wol")) {
+ if (on && !pc->mac[0])
lwsl_err("%s: %s: WOL type but no MAC configured\n",
__func__, pc->name);
else
@@ -94,8 +98,8 @@ saip_switch(saip_pcon_t *pc, int on)
} else {
lwsl_err("%s: %s: no ss handle for %s (type: %s, mac: %s)\n",
__func__, pc->name, on ? "ON" : "OFF",
- pc->type ? pc->type : "null",
- pc->mac ? pc->mac : "null");
+ pc->type[0] ? pc->type : "null",
+ pc->mac[0] ? pc->mac : "null");
}
}
return;
diff --git a/src/power/p-ws-server.c b/src/power/p-ws-server.c
index 99f69e3..c1282b0 100644
--- a/src/power/p-ws-server.c
+++ b/src/power/p-ws-server.c
@@ -147,13 +147,13 @@ saip_queue_stay_info(saip_server_t *sps)
saip_pcon_t *pc = lws_container_of(p, saip_pcon_t, list);
sai_power_controller_t *pc1 = lwsac_use_zero(&ac, sizeof(*pc1), 2048);
- if (pc1 && pc->name) {
+ if (pc1 && pc->name[0]) {
lws_strncpy(pc1->name, pc->name, sizeof(pc1->name));
pc1->on = (unsigned int)pc->on;
pc1->manual_on = !!(pc->flags & SAIP_PCON_F_MANUAL_STAY);
- if (pc->depends_on)
+ if (pc->depends_on[0])
lws_strncpy(pc1->depends_on, pc->depends_on, sizeof(pc1->depends_on));
- if (pc->type)
+ if (pc->type[0])
lws_strncpy(pc1->type, pc->type, sizeof(pc1->type));
lws_dll2_add_tail(&pc1->list, &pmb.power_controllers);
diff --git a/src/resource/CMakeLists.txt b/src/resource/CMakeLists.txt
index 5eb6cb6..f22f908 100644
--- a/src/resource/CMakeLists.txt
+++ b/src/resource/CMakeLists.txt
@@ -16,6 +16,7 @@ require_lws_config(LWS_WITH_DIR 1 requirements)
if (requirements AND NOT MSVC)
add_executable(${SUB} ${SRCS})
+add_dependencies(${SUB} sai_git_hash)
if (APPLE)
set_property(TARGET sai-resource PROPERTY MACOSX_RPATH YES)
endif()
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 8595ed7..ee66246 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -39,6 +39,7 @@ require_lws_config(LWS_WITH_STRUCT_SQLITE3 1 requirements)
if (requirements)
add_executable(${SUB} ${SRCS})
+add_dependencies(${SUB} sai_git_hash)
if (APPLE)
set_property(TARGET sai-server PROPERTY MACOSX_RPATH YES)
endif()
diff --git a/src/server/s-ws-web.c b/src/server/s-ws-web.c
index 5311f09..c8d4f6e 100644
--- a/src/server/s-ws-web.c
+++ b/src/server/s-ws-web.c
@@ -458,7 +458,7 @@ websrvss_ws_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
sai_db_result_t r;
int n;
- lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags);
+ lwsl_info("%s: len %d, flags: %d\n", __func__, (int)len, flags);
lwsl_hexdump_info(buf, len);
memset(&a, 0, sizeof(a));
diff --git a/src/web/CMakeLists.txt b/src/web/CMakeLists.txt
index 0f413fc..8ee5585 100644
--- a/src/web/CMakeLists.txt
+++ b/src/web/CMakeLists.txt
@@ -22,6 +22,7 @@ require_lws_config(LWS_WITH_UNIX_SOCK 1 requirements)
if (requirements)
add_executable(${SUB} ${SRCS})
+add_dependencies(${SUB} sai_git_hash)
if (APPLE)
set_property(TARGET sai-web PROPERTY MACOSX_RPATH YES)
endif()
diff --git a/src/web/w-comms.c b/src/web/w-comms.c
index c156d0f..7cde616 100644
--- a/src/web/w-comms.c
+++ b/src/web/w-comms.c
@@ -465,7 +465,7 @@ http_resp:
lws_hdr_copy(wsi, (char *)buf, sizeof(buf),
WSI_TOKEN_X_FORWARDED_FOR);
- lwsl_wsi_warn(wsi, "ESTABLISHED: %s %s", (char *)buf, pss->alang);
+ lwsl_wsi_info(wsi, "ESTABLISHED: %s %s", (char *)buf, pss->alang);
if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) {
if (lws_hdr_copy(wsi, (char *)start, 64,
@@ -559,7 +559,7 @@ http_resp:
case LWS_CALLBACK_CLOSED:
- lwsl_wsi_err(wsi, "CLOSED browse conn");
+ lwsl_wsi_info(wsi, "CLOSED browse conn");
lws_buflist_destroy_all_segments(&pss->raw_tx);
saiw_browser_state_changed(pss, 0);
lws_dll2_remove(&pss->subs_list);
diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c
index 417a07c..33f4bc5 100644
--- a/src/web/w-ws-browser.c
+++ b/src/web/w-ws-browser.c
@@ -556,8 +556,8 @@ saiw_ws_json_rx_browser(struct vhd *vhd, struct pss *pss, uint8_t *buf,
sai_cancel_t *can;
int m, ret = -1;
- lwsl_notice("%s: len %d, flags: %d\n", __func__, (int)bl, ss_flags);
- /* lwsl_hexdump_notice(buf, bl); */
+ lwsl_info("%s: len %d, flags: %d\n", __func__, (int)bl, ss_flags);
+ /* lwsl_hexdump_info(buf, bl); */
memset(&a, 0, sizeof(a));
/*