"
"%s | " // name
"%s | " // sbatt (Battery Indicator)
"" // slqi
), shortaddr,
device.modelId ? device.modelId : "",
device.manufacturerId ? device.manufacturerId : "",
name, sbatt, slqi);
if(device.validLqi()) {
for(uint32_t j = 0; j < 4; ++j) {
WSContentSend_PD(PSTR(""), j, (num_bars < j) ? PSTR(" o30") : PSTR(""));
}
}
char dhm[48];
snprintf_P(dhm, sizeof(dhm), PSTR(" | "));
if (device.validLastSeen()) {
char unit;
uint8_t color;
uint16_t val = convert_seconds_to_dhm(now - device.last_seen, &unit, &color);
if (val < 100) {
snprintf_P(dhm, sizeof(dhm), PSTR(" | 🕗%02d%c"),
color, color, color, val, unit);
}
}
WSContentSend_PD(PSTR(
" | " // Close LQI
"%s{e}" // dhm (Last Seen)
), dhm );
// Sensors
const Z_Data_Thermo & thermo = device.data.find();
if (&thermo != nullptr) {
bool validTemp = thermo.validTemperature();
bool validTempTarget = thermo.validTempTarget();
bool validThSetpoint = thermo.validThSetpoint();
bool validHumidity = thermo.validHumidity();
bool validPressure = thermo.validPressure();
if (validTemp || validTempTarget || validThSetpoint || validHumidity || validPressure) {
WSContentSend_P(PSTR("┆"));
if (validTemp) {
char buf[12];
dtostrf(thermo.getTemperature() / 100.0f, 3, 1, buf);
WSContentSend_PD(PSTR(" ☀️ %s°C"), buf);
}
if (validTempTarget) {
char buf[12];
dtostrf(thermo.getTempTarget() / 100.0f, 3, 1, buf);
WSContentSend_PD(PSTR(" 🎯 %s°C"), buf);
}
if (validThSetpoint) {
WSContentSend_PD(PSTR(" ⚙️ %d%%"), thermo.getThSetpoint());
}
if (validHumidity) {
WSContentSend_P(PSTR(" 💧 %d%%"), (uint16_t)(thermo.getHumidity() / 100.0f + 0.5f));
}
if (validPressure) {
WSContentSend_P(PSTR(" ⛅ %d hPa"), thermo.getPressure());
}
WSContentSend_P(PSTR("{e}"));
}
}
// Light, switches and plugs
const Z_Data_OnOff & onoff = device.data.find();
bool onoff_display = (&onoff != nullptr) ? onoff.validPower() : false;
const Z_Data_Light & light = device.data.find();
bool light_display = (&light != nullptr) ? light.validDimmer() : false;
const Z_Data_Plug & plug = device.data.find();
bool plug_voltage = (&plug != nullptr) ? plug.validMainsVoltage() : false;
bool plug_power = (&plug != nullptr) ? plug.validMainsPower() : false;
if (onoff_display || light_display || plug_voltage || plug_power) {
int8_t channels = device.getLightChannels();
if (channels < 0) { channels = 5; } // if number of channel is unknown, display all known attributes
WSContentSend_P(PSTR("┆"));
if (onoff_display) {
WSContentSend_P(PSTR(" %s"), onoff.getPower() ? PSTR(D_ON) : PSTR(D_OFF));
}
if (&light != nullptr) {
if (light.validDimmer() && (channels >= 1)) {
WSContentSend_P(PSTR(" 🔅 %d%%"), changeUIntScale(light.getDimmer(),0,254,0,100));
}
if (light.validCT() && ((channels == 2) || (channels == 5))) {
uint32_t ct_k = (((1000000 / light.getCT()) + 25) / 50) * 50;
WSContentSend_P(PSTR(" ⚪ %dK"), light.getCT(), ct_k);
}
if (light.validHue() && light.validSat() && (channels >= 3)) {
uint8_t r,g,b;
uint8_t sat = changeUIntScale(light.getSat(), 0, 254, 0, 255); // scale to 0..255
LightStateClass::HsToRgb(light.getHue(), sat, &r, &g, &b);
WSContentSend_P(PSTR(" #%02X%02X%02X"), r,g,b,r,g,b);
} else if (light.validX() && light.validY() && (channels >= 3)) {
uint8_t r,g,b;
LightStateClass::XyToRgb(light.getX() / 65535.0f, light.getY() / 65535.0f, &r, &g, &b);
WSContentSend_P(PSTR(" #%02X%02X%02X"), r,g,b,r,g,b);
}
}
if (plug_voltage || plug_power) {
WSContentSend_P(PSTR(" ⚡ "));
if (plug_voltage) {
WSContentSend_P(PSTR(" %dV"), plug.getMainsVoltage());
}
if (plug_power) {
WSContentSend_P(PSTR(" %dW"), plug.getMainsPower());
}
}
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
#ifdef USE_ZIGBEE_EZSP
ZigbeeGlowPermitJoinLight();
#endif // USE_ZIGBEE_EZSP
}
if (zigbee.state_machine) {
ZigbeeStateMachine_Run();
}
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
ZigbeeShow(false);
break;
#ifdef USE_ZIGBEE_EZSP
// GUI xmodem
case FUNC_WEB_ADD_HANDLER:
WebServer_on(PSTR("/" WEB_HANDLE_ZIGBEE_XFER), HandleZigbeeXfer);
break;
#endif // USE_ZIGBEE_EZSP
#endif // USE_WEBSERVER
case FUNC_PRE_INIT:
ZigbeeInit();
break;
case FUNC_COMMAND:
result = DecodeCommand(kZbCommands, ZigbeeCommand);
break;
case FUNC_SAVE_BEFORE_RESTART:
#ifdef USE_ZIGBEE_EZSP
hibernateAllData();
#endif // USE_ZIGBEE_EZSP
restoreDumpAllDevices();
break;
}
}
return result;
}
#endif // USE_ZIGBEE
| |