Zwei neue Einstellungen, beide wie fade_in/fade_out ueber POST /api/v1/device/state les- und schreibbar und sofort wirksam: - transition_default (Voreinstellung 300 ms) fuellt die Transition fuer Farb-, Weiss- und Helligkeitswechsel bei eingeschalteter Lampe, wenn der Aufruf kein eigenes "transition" mitbringt. Beim Ein- und Ausschalten behalten fade_in/fade_out weiterhin Vorrang. - wake_on_change (Voreinstellung aus) schaltet die Lampe bei einer Farb-, Weiss- oder Helligkeitsaenderung ein, wenn sie aus war. Ein ausdrueckliches "on": false im selben Aufruf gewinnt immer. Beide Felder haengen am Ende von nl_settings_t, damit bestehende Lampen ueber die Laengentoleranz von read_rec() ihre echten Voreinstellungen bekommen statt Nullen. nl_ctrl_set_fades() heisst jetzt nl_ctrl_set_options(). Dazu ein Treiberfehler, der erst an der migrierten GU10 RGB auffiel: der WY-Zweig von nl_sm2135eh_set() schrieb nur Header und WY-Daten, nie die RGB-Datenregister. Der Chip behielt also die zuletzt gesetzte Farbe, und bei einem direkten Wechsel Farbe -> Weiss (ohne Zwischenschritt ueber dunkel) schaelte sie sich beim Ausblenden wieder frei. Der Header sendet jetzt die - in Weiss immer nullwertigen - RGB-Daten mit. Die Bruno-Collection zeigt Transition jetzt zusammen mit einem Farb- und einem Weisswechsel im selben Aufruf und hat einen Request fuer die beiden neuen Einstellungen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
131 lines
3.5 KiB
C
131 lines
3.5 KiB
C
#include <string.h>
|
|
|
|
#include "wm_include.h"
|
|
#include "wm_mem.h"
|
|
|
|
#include "cJSON.h"
|
|
#include "light/nl_control.h"
|
|
#include "light/nl_engine.h"
|
|
#include "net/nl_mdns.h"
|
|
#include "net/nl_names.h"
|
|
#include "net/nl_wifi.h"
|
|
#include "sys/nl_app.h"
|
|
#include "sys/nl_app_api.h"
|
|
#include "sys/nl_ota.h"
|
|
|
|
#include "nl_version.h"
|
|
|
|
static void *json_alloc(size_t n) { return tls_mem_alloc(n); }
|
|
static void json_free(void *p) { tls_mem_free(p); }
|
|
|
|
static void get_state(nl_light_state_t *out)
|
|
{
|
|
nl_app_lock();
|
|
nl_ctrl_get(out);
|
|
nl_app_unlock();
|
|
}
|
|
|
|
static nl_ctrl_err_t apply(const nl_light_change_t *c)
|
|
{
|
|
nl_ctrl_err_t e;
|
|
nl_app_lock();
|
|
e = nl_ctrl_apply(c, nl_app_now_ms());
|
|
nl_app_unlock();
|
|
return e;
|
|
}
|
|
|
|
static void get_settings(nl_settings_t *out)
|
|
{
|
|
nl_app_lock();
|
|
*out = *nl_app_settings();
|
|
nl_app_unlock();
|
|
}
|
|
|
|
/* The API never changes Wi-Fi credentials through here (that goes through the onboarding test),
|
|
* so the current ones are kept even if the network task stored new ones meanwhile. */
|
|
static int save_settings(const nl_settings_t *s)
|
|
{
|
|
nl_settings_t *cur;
|
|
char name[NL_NAME_LEN];
|
|
bool name_changed;
|
|
|
|
nl_app_lock();
|
|
cur = nl_app_settings();
|
|
name_changed = strcmp(cur->name, s->name) != 0;
|
|
{
|
|
nl_settings_t merged = *s;
|
|
memcpy(merged.wifi_ssid, cur->wifi_ssid, sizeof merged.wifi_ssid);
|
|
memcpy(merged.wifi_pass, cur->wifi_pass, sizeof merged.wifi_pass);
|
|
*cur = merged;
|
|
}
|
|
nl_ctrl_set_options(cur->fade_in_ms, cur->fade_out_ms, cur->transition_ms, cur->wake_on_change != 0);
|
|
memcpy(name, cur->name, sizeof name);
|
|
nl_app_unlock();
|
|
if (name_changed)
|
|
nl_mdns_set_name(name);
|
|
return nl_app_save_settings();
|
|
}
|
|
|
|
static int wifi_configure(const char *ssid, const char *pass) { return nl_wifi_request_onboard(ssid, pass); }
|
|
static bool open_access(void) { return nl_wifi_open_access(); }
|
|
|
|
static void get_info(nl_sys_info_t *out)
|
|
{
|
|
nl_wifi_status_t w;
|
|
uint8_t mac[6];
|
|
|
|
memset(out, 0, sizeof *out);
|
|
nl_wifi_mac(mac);
|
|
nl_names_mac_str(mac, out->mac);
|
|
nl_app_lock();
|
|
memcpy(out->name, nl_app_settings()->name, sizeof out->name);
|
|
nl_app_unlock();
|
|
nl_wifi_status(&w);
|
|
out->wifi_mode = w.mode;
|
|
memcpy(out->ssid, w.ssid, sizeof out->ssid);
|
|
out->rssi = w.rssi;
|
|
memcpy(out->ip, w.ip, sizeof out->ip);
|
|
memcpy(out->sta_ip, w.sta_ip, sizeof out->sta_ip);
|
|
out->wifi_error = w.error;
|
|
out->uptime_s = nl_app_now_ms() / 1000u;
|
|
out->free_heap = tls_mem_get_avail_heapsize();
|
|
out->last_ota_error = nl_ota_last_error();
|
|
}
|
|
|
|
static void factory_reset(void) { nl_app_request_factory_reset(); }
|
|
|
|
static void ping(void)
|
|
{
|
|
nl_app_lock();
|
|
nl_engine_blink(3);
|
|
nl_app_unlock();
|
|
}
|
|
|
|
static int fw_update(const char *url) { return nl_ota_start(url); }
|
|
|
|
const nl_api_ctx_t *nl_app_api_ctx(void)
|
|
{
|
|
static nl_api_ctx_t ctx;
|
|
static bool ready;
|
|
|
|
if (!ready) {
|
|
cJSON_Hooks hooks = {json_alloc, json_free};
|
|
cJSON_InitHooks(&hooks);
|
|
ctx.board = nl_board_get();
|
|
ctx.fw_version = NINLIGHT_FW_VERSION;
|
|
ctx.build_date = NINLIGHT_BUILD_DATE;
|
|
ctx.get_state = get_state;
|
|
ctx.apply = apply;
|
|
ctx.get_settings = get_settings;
|
|
ctx.save_settings = save_settings;
|
|
ctx.wifi_configure = wifi_configure;
|
|
ctx.open_access = open_access;
|
|
ctx.get_info = get_info;
|
|
ctx.factory_reset = factory_reset;
|
|
ctx.ping = ping;
|
|
ctx.fw_update = fw_update;
|
|
ready = true;
|
|
}
|
|
return &ctx;
|
|
}
|