(), nullptr, 0); }
// TxRadio dBm
const JsonVariant &val_txradio = GetCaseInsensitive(json, PSTR("TxRadio"));
if (nullptr != &val_txradio) { zb_txradio_dbm = strToUInt(val_txradio); }
// Check if a parameter was changed after all
if ( (zb_channel != Settings.zb_channel) ||
(zb_pan_id != Settings.zb_pan_id) ||
(zb_ext_panid != Settings.zb_ext_panid) ||
(zb_precfgkey_l != Settings.zb_precfgkey_l) ||
(zb_precfgkey_h != Settings.zb_precfgkey_h) ||
(zb_txradio_dbm != Settings.zb_txradio_dbm) ) {
Settings.zb_channel = zb_channel;
Settings.zb_pan_id = zb_pan_id;
Settings.zb_ext_panid = zb_ext_panid;
Settings.zb_precfgkey_l = zb_precfgkey_l;
Settings.zb_precfgkey_h = zb_precfgkey_h;
Settings.zb_txradio_dbm = zb_txradio_dbm;
restart_flag = 2; // save and reboot
}
}
// display the current or new configuration
char hex_ext_panid[20] = "0x";
Uint64toHex(zb_ext_panid, &hex_ext_panid[2], 64);
char hex_precfgkey_l[20] = "0x";
Uint64toHex(zb_precfgkey_l, &hex_precfgkey_l[2], 64);
char hex_precfgkey_h[20] = "0x";
Uint64toHex(zb_precfgkey_h, &hex_precfgkey_h[2], 64);
// {"ZbConfig":{"Channel":11,"PanID":"0x1A63","ExtPanID":"0xCCCCCCCCCCCCCCCC","KeyL":"0x0F0D0B0907050301L","KeyH":"0x0D0C0A0806040200L"}}
Response_P(PSTR("{\"" D_PRFX_ZB D_JSON_ZIGBEE_CONFIG "\":{"
"\"Channel\":%d"
",\"PanID\":\"0x%04X\""
",\"ExtPanID\":\"%s\""
",\"KeyL\":\"%s\""
",\"KeyH\":\"%s\""
",\"TxRadio\":%d"
"}}"),
zb_channel, zb_pan_id,
hex_ext_panid,
hex_precfgkey_l, hex_precfgkey_h,
zb_txradio_dbm);
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void ZigbeeShow(bool json)
{
if (json) {
return;
#ifdef USE_WEBSERVER
} else {
uint32_t zigbee_num = zigbee_devices.devicesSize();
if (!zigbee_num) { return; }
// Calculate fixed column width for best visual result (Theos opinion)
const uint8_t px_batt = (strlen(D_BATT) + 5 + 1) * 10; // Batt 100% = 90px + 10px column separator
const uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px
WSContentSend_P(PSTR("{t}")); // Terminate current two column table and open new table
for (uint32_t i = 0; i < zigbee_num; i++) {
const Z_Device &device = zigbee_devices.devicesAt(i);
uint16_t shortaddr = device.shortaddr;
{ // exxplicit scope to free up stack allocated strings
char *name = (char*) device.friendlyName;
char sdevice[33];
if (nullptr == name) {
snprintf_P(sdevice, sizeof(sdevice), PSTR(D_DEVICE " 0x%04X"), shortaddr);
name = sdevice;
}
char slqi[8];
snprintf_P(slqi, sizeof(slqi), PSTR("-"));
if (device.validLqi()) {
snprintf_P(slqi, sizeof(slqi), PSTR("%d"), device.lqi);
}
char sbatt[20];
snprintf_P(sbatt, sizeof(sbatt), PSTR(" "));
if (device.validBatteryPercent()) {
snprintf_P(sbatt, sizeof(sbatt), PSTR(D_BATT " %d%%"), device.batterypercent);
}
if (!i) { // First row needs style info
WSContentSend_PD(PSTR("%s | %s | " D_LQI " %s{e}"),
name, px_batt, sbatt, px_lqi, slqi);
} else { // Following rows don't need style info so reducing ajax package
WSContentSend_PD(PSTR(" |
%s | %s | " D_LQI " %s{e}"), name, sbatt, slqi);
}
}
// Sensor
bool temperature_ok = device.validTemperature();
bool humidity_ok = device.validHumidity();
bool pressure_ok = device.validPressure();
if (temperature_ok || humidity_ok || pressure_ok) {
WSContentSend_P(PSTR(" |
| "));
if (temperature_ok) {
char buf[12];
dtostrf(device.temperature / 10.0f, 3, 1, buf);
WSContentSend_PD(PSTR(" ☀️%s°C"), buf);
}
if (humidity_ok) {
WSContentSend_P(PSTR(" 💧%d%%"), device.humidity);
}
if (pressure_ok) {
WSContentSend_P(PSTR(" ⛅ %d hPa"), device.pressure);
}
WSContentSend_P(PSTR("{e}"));
}
}
WSContentSend_P(PSTR("{t}")); // Terminate current multi column table and open new table
#endif
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xdrv23(uint8_t function)
{
bool result = false;
if (zigbee.active) {
switch (function) {
case FUNC_EVERY_50_MSECOND:
if (!zigbee.init_phase) {
zigbee_devices.runTimer();
}
break;
case FUNC_LOOP:
#ifdef USE_ZIGBEE_EZSP
if (ZigbeeUploadXmodem()) {
return false;
}
#endif
if (ZigbeeSerial) {
ZigbeeInputLoop();
ZigbeeOutputLoop(); // send any outstanding data
}
if (zigbee.state_machine) {
ZigbeeStateMachine_Run();
}
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
ZigbeeShow(false);
break;
#endif // USE_WEBSERVER
case FUNC_PRE_INIT:
ZigbeeInit();
break;
case FUNC_COMMAND:
result = DecodeCommand(kZbCommands, ZigbeeCommand);
break;
}
}
return result;
}
#endif // USE_ZIGBEE
|