Files
MeshCore/examples/companion_radio/NodePrefs.h
T
shade 28e802dcf0
Run Unit Tests / test (push) Canceled after 0s
Build and deploy Docs site to GitHub Pages / github-pages (push) Canceled after 0s
PR Build Check / build (Heltec_v3_companion_radio_ble) (push) Canceled after 0s
PR Build Check / build (Heltec_v3_repeater) (push) Canceled after 0s
PR Build Check / build (Heltec_v3_room_server) (push) Canceled after 0s
PR Build Check / build (LilyGo_Tlora_C6_repeater_) (push) Canceled after 0s
PR Build Check / build (PicoW_repeater) (push) Canceled after 0s
PR Build Check / build (RAK_4631_companion_radio_ble) (push) Canceled after 0s
PR Build Check / build (RAK_4631_companion_radio_ethernet) (push) Canceled after 0s
PR Build Check / build (RAK_4631_repeater) (push) Canceled after 0s
PR Build Check / build (RAK_4631_repeater_ethernet) (push) Canceled after 0s
PR Build Check / build (RAK_4631_room_server) (push) Canceled after 0s
PR Build Check / build (RAK_4631_room_server_ethernet) (push) Canceled after 0s
PR Build Check / build (Tbeam_SX1276_repeater) (push) Canceled after 0s
PR Build Check / build (wio-e5-mini_repeater) (push) Canceled after 0s
PR Build Check / build (wio_wm1110_repeater) (push) Canceled after 0s
уведомления: режимы по каналам, тихие часы с часовым поясом, отключение автовключения дисплея
2026-10-08 20:28:59 +03:00

207 lines
8.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <cstdint> // For uint8_t, uint32_t
#include <helpers/ConfigSerializer.h>
#define TELEM_MODE_DENY 0
#define TELEM_MODE_ALLOW_FLAGS 1 // use contact.flags
#define TELEM_MODE_ALLOW_ALL 2
#define ADVERT_LOC_NONE 0
#define ADVERT_LOC_SHARE 1
// Режимы уведомлений по каналам (по 2 бита на канал)
#define CH_MODE_POPUP 0 // звук + экран переключается на сообщение
#define CH_MODE_SILENT 1 // в непрочитанные, но без звука и без всплытия
#define CH_MODE_OFF 2 // на устройстве не уведомляем вообще
// Сколько каналов покрываем настройками. Совпадает с MAX_GROUP_CHANNELS у companion-сборок,
// но этот заголовок его не включает, поэтому задаём свой предел.
#ifndef NOTIFY_MAX_CHANNELS
#define NOTIFY_MAX_CHANNELS 40
#endif
#define CH_MODE_BYTES ((NOTIFY_MAX_CHANNELS * 2 + 7) / 8)
class NodePrefs : public ConfigSerializer { // persisted to file
public:
float airtime_factor = 0;
char node_name[32];
double node_lat = 0, node_lon = 0;
float freq = 0;
uint8_t sf = 0;
uint8_t cr = 0;
uint8_t multi_acks = 0;
uint8_t manual_add_contacts = 0;
float bw = 0;
int8_t tx_power_dbm = 0;
uint8_t telemetry_mode_base = 0;
uint8_t telemetry_mode_loc = 0;
uint8_t telemetry_mode_env = 0;
float rx_delay_base = 0;
uint32_t ble_pin = 0;
uint8_t advert_loc_policy = 0;
uint8_t buzzer_quiet = 0;
uint8_t vibe_quiet = 0;
uint8_t gps_enabled = 0; // GPS enabled flag (0=disabled, 1=enabled)
uint32_t gps_interval = 0; // GPS read interval in seconds
uint8_t autoadd_config = 0; // bitmask for auto-add contacts config
uint8_t rx_boosted_gain = 0; // SX126x RX boosted gain mode (0=power saving, 1=boosted)
uint8_t radio_fem_rxgain = 0; // external LoRa FEM RX gain (LNA)
uint8_t radio_fem_txgain = 0; // external LoRa FEM TX gain (low by default)
uint8_t _client_repeat = 0; // DEPRECATED -> use repeat.disable_fwd
uint8_t path_hash_mode = 0; // which path mode to use when sending
uint8_t autoadd_max_hops = 0; // 0 = no limit, 1 = direct (0 hops), N = up to N-1 hops (max 64)
char default_scope_name[31];
uint8_t default_scope_key[16];
char ui_theme[12]; // имя темы дисплея; пусто = тема по умолчанию для платы
// Уведомления о входящих (меню на первом экране)
uint8_t msg_popup = 1; // переключать экран на входящее сообщение
uint8_t msg_wake_display = 1; // зажигать дисплей при входящем сообщении
uint8_t quiet_en = 0; // часы тишины включены
uint8_t quiet_from = 23; // час начала (локальный)
uint8_t quiet_to = 7; // час окончания (локальный)
int8_t tz_offset = 0; // смещение от UTC в часах, -12..+14
uint8_t ch_mode[CH_MODE_BYTES]; // режимы по каналам (CH_MODE_*), по 2 бита
private:
class RadioPrefs : public ConfigSerializer { // COPIED from CommonCLI (for now)
NodePrefs* _parent;
protected:
void structure() override {
def("freq", _parent->freq);
def("bw", _parent->bw);
def("sf", _parent->sf);
def("cr", _parent->cr);
//def("cad", _parent->cad_enabled);
//def("int_thr", _parent->interference_threshold);
def("rxgain", _parent->rx_boosted_gain);
#if 0
// NOTE: these cannot be set (yet) so don't load/save until we can.
// also, fem_rxgain WAS mapped to wrong JSON property previously
def("fem_rxgain", _parent->radio_fem_rxgain);
def("fem_txgain", _parent->radio_fem_txgain);
#endif
def("tx", _parent->tx_power_dbm);
def("af", _parent->airtime_factor);
def("rxdelay", _parent->rx_delay_base);
//def("f_txdelay", _parent->tx_delay_factor); currently hard-coded
//def("d_txdelay", _parent->direct_tx_delay_factor); currently hard-coded
//def("agc_int", _parent->agc_reset_interval);
def("hash_mode", _parent->path_hash_mode);
def("multi_ack", _parent->multi_acks);
}
public:
RadioPrefs(NodePrefs* parent) : _parent(parent) { }
};
RadioPrefs radio;
class GPSPrefs : public ConfigSerializer { // COPIED from CommonCLI (for now)
NodePrefs* _parent;
protected:
void structure() override {
def("en", _parent->gps_enabled); // boolean
def("int", _parent->gps_interval); // interval in seconds
def("adv_loc", _parent->advert_loc_policy);
}
public:
GPSPrefs(NodePrefs* parent) : _parent(parent) { }
};
GPSPrefs gps;
class RepeatPrefs : public ConfigSerializer { // COPIED from CommonCLI (for now)
public:
uint8_t disable_fwd = 1;
protected:
void structure() override {
def("disable", disable_fwd);
//def("f_max", flood_max);
//def("f_max_uns", flood_max_unscoped);
//def("f_max_adv", flood_max_advert);
//def("loop", loop_detect);
}
};
RepeatPrefs repeat;
class CompanionPrefs : public ConfigSerializer {
NodePrefs* _parent;
protected:
void structure() override {
def("auto_max", _parent->autoadd_max_hops); // 0 = no limit, 1 = direct (0 hops), N = up to N-1 hops (max 64)
def("defs_nm", _parent->default_scope_name, sizeof(_parent->default_scope_name));
def("defs_key", (void *) _parent->default_scope_key, sizeof(_parent->default_scope_key));
def("pin", _parent->ble_pin);
def("buzz_q", _parent->buzzer_quiet);
def("vibe_q", _parent->vibe_quiet);
def("auto_add", _parent->autoadd_config); // bitmask for auto-add contacts config
def("man_add", _parent->manual_add_contacts);
def("theme", _parent->ui_theme, sizeof(_parent->ui_theme)); // имя темы дисплея
// уведомления
def("msg_popup", _parent->msg_popup);
def("msg_wake", _parent->msg_wake_display);
def("quiet_en", _parent->quiet_en);
def("quiet_from", _parent->quiet_from);
def("quiet_to", _parent->quiet_to);
def("tz", _parent->tz_offset);
def("ch_mode", (void *)_parent->ch_mode, sizeof(_parent->ch_mode)); // hex-блоб
def("tel_base", _parent->telemetry_mode_base);
def("tel_loc", _parent->telemetry_mode_loc);
def("tel_env", _parent->telemetry_mode_env);
}
public:
CompanionPrefs(NodePrefs* parent) : _parent(parent) { }
};
CompanionPrefs companion;
protected:
void structure() override {
def("name", node_name, sizeof(node_name));
//def("adv_int", advert_interval);
//def("f_adv_int", flood_advert_interval);
def("lat", node_lat);
def("lon", node_lon);
def("radio", radio);
def("gps", gps);
def("repeat", repeat);
def("comp", companion);
}
public:
NodePrefs() : radio(this), gps(this), companion(this) {
node_name[0] = 0;
default_scope_name[0] = 0;
ui_theme[0] = 0;
memset(ch_mode, 0, sizeof(ch_mode)); // все каналы — CH_MODE_POPUP
memset(default_scope_key, 0, sizeof(default_scope_key));
}
// new accessor methods
bool isRepeatEn() const { return repeat.disable_fwd == 0; }
void setRepeatEn(bool en) { repeat.disable_fwd = en ? 0 : 1; }
// Настройки уведомлений по каналам
uint8_t getChannelMode(uint8_t idx) const {
if (idx >= NOTIFY_MAX_CHANNELS) return CH_MODE_POPUP;
uint8_t sh = (uint8_t)((idx & 3) * 2);
return (uint8_t)((ch_mode[idx >> 2] >> sh) & 0x03);
}
void setChannelMode(uint8_t idx, uint8_t mode) {
if (idx >= NOTIFY_MAX_CHANNELS) return;
uint8_t sh = (uint8_t)((idx & 3) * 2);
ch_mode[idx >> 2] = (uint8_t)((ch_mode[idx >> 2] & ~(0x03 << sh)) | ((mode & 0x03) << sh));
}
// Локальный час суток по unix-времени RTC и смещению часового пояса
uint8_t localHour(uint32_t utc) const {
int32_t h = (int32_t)((utc / 3600) % 24) + tz_offset;
h %= 24;
if (h < 0) h += 24;
return (uint8_t)h;
}
// Тихие часы: окно может пересекать полночь (например, 23..7)
bool isQuietNow(uint32_t utc) const {
if (!quiet_en) return false;
if (quiet_from == quiet_to) return false;
uint8_t h = localHour(utc);
if (quiet_from < quiet_to) return h >= quiet_from && h < quiet_to;
return h >= quiet_from || h < quiet_to;
}
};