mirror of https://github.com/arendst/Tasmota.git
Merge pull request #9165 from s-hadinger/zigbee_light_ui
Add Zigbee web ui widget for Lights
This commit is contained in:
commit
33f3f9ef62
|
@ -3,6 +3,7 @@
|
||||||
### 8.4.0.3 20200823
|
### 8.4.0.3 20200823
|
||||||
|
|
||||||
- Add command ``PowerDelta1`` to ``PowerDelta3`` to trigger on up to three phases (#9134)
|
- Add command ``PowerDelta1`` to ``PowerDelta3`` to trigger on up to three phases (#9134)
|
||||||
|
- Add Zigbee web ui widget for Lights
|
||||||
|
|
||||||
### 8.4.0.2 20200813
|
### 8.4.0.2 20200813
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,14 @@ public:
|
||||||
inline bool getReachable(void) const { return bitRead(power, 7); }
|
inline bool getReachable(void) const { return bitRead(power, 7); }
|
||||||
inline void setPower(bool power_on) { bitWrite(power, 0, power_on); bitWrite(power, 1, false); }
|
inline void setPower(bool power_on) { bitWrite(power, 0, power_on); bitWrite(power, 1, false); }
|
||||||
inline bool getPower(void) const { return bitRead(power, 0); }
|
inline bool getPower(void) const { return bitRead(power, 0); }
|
||||||
|
|
||||||
|
// If light, returns the number of channels, or 0xFF if unknown
|
||||||
|
uint8_t getLightChannels(void) const {
|
||||||
|
if ((zb_profile & 0xF0) == 0x00) {
|
||||||
|
return zb_profile & 0x07;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -682,21 +690,21 @@ void Z_Devices::updateZbProfile(uint16_t shortaddr) {
|
||||||
{
|
{
|
||||||
uint32_t channels = zb_profile & 0x07;
|
uint32_t channels = zb_profile & 0x07;
|
||||||
// depending on the bulb type, the default parameters from unknown to credible defaults
|
// depending on the bulb type, the default parameters from unknown to credible defaults
|
||||||
if (!device.validPower()) { device.setPower(false); }
|
// if (!device.validPower()) { device.setPower(false); }
|
||||||
if (1 <= channels) {
|
// if (1 <= channels) {
|
||||||
if (0xFF == device.dimmer) { device.dimmer = 0; }
|
// if (0xFF == device.dimmer) { device.dimmer = 0; }
|
||||||
}
|
// }
|
||||||
if (3 <= channels) {
|
// if (3 <= channels) {
|
||||||
if (0xFF == device.sat) { device.sat = 0; }
|
// if (0xFF == device.sat) { device.sat = 0; }
|
||||||
if (0xFFFF == device.hue) { device.hue = 0; }
|
// if (0xFFFF == device.hue) { device.hue = 0; }
|
||||||
if (0xFFFF == device.x) { device.x = 0; }
|
// if (0xFFFF == device.x) { device.x = 0; }
|
||||||
if (0xFFFF == device.y) { device.y = 0; }
|
// if (0xFFFF == device.y) { device.y = 0; }
|
||||||
if (0xFF == device.colormode) { device.colormode = 0; } // HueSat mode
|
// if (0xFF == device.colormode) { device.colormode = 0; } // HueSat mode
|
||||||
}
|
// }
|
||||||
if ((2 == channels) || (5 == channels)) {
|
// if ((2 == channels) || (5 == channels)) {
|
||||||
if (0xFFFF == device.ct) { device.ct = 200; }
|
// if (0xFFFF == device.ct) { device.ct = 200; }
|
||||||
if (0xFF == device.colormode) { device.colormode = 2; } // CT mode
|
// if (0xFF == device.colormode) { device.colormode = 2; } // CT mode
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,7 +681,7 @@ ZBM(ZBS_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*false*/, 0
|
||||||
ZBM(ZBR_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*ok*/) // 100000
|
ZBM(ZBR_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*ok*/) // 100000
|
||||||
|
|
||||||
// setInitialSecurityState
|
// setInitialSecurityState
|
||||||
#define EZ_SECURITY_MODE EMBER_TRUST_CENTER_GLOBAL_LINK_KEY | EMBER_PRECONFIGURED_NETWORK_KEY_MODE | EMBER_HAVE_NETWORK_KEY | EMBER_HAVE_PRECONFIGURED_KEY
|
#define EZ_SECURITY_MODE EMBER_TRUST_CENTER_GLOBAL_LINK_KEY | EMBER_PRECONFIGURED_NETWORK_KEY_MODE | EMBER_HAVE_NETWORK_KEY | EMBER_HAVE_PRECONFIGURED_KEY | EMBER_NO_FRAME_COUNTER_RESET
|
||||||
ZBR(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/,
|
ZBR(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/,
|
||||||
Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE),
|
Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE),
|
||||||
// preConfiguredKey
|
// preConfiguredKey
|
||||||
|
|
|
@ -1348,6 +1348,7 @@ void ZigbeeShow(bool json)
|
||||||
const uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px
|
const uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px
|
||||||
|
|
||||||
WSContentSend_P(PSTR("</table>{t}")); // Terminate current two column table and open new table
|
WSContentSend_P(PSTR("</table>{t}")); // Terminate current two column table and open new table
|
||||||
|
WSContentSend_P(PSTR("<style>.bx{height:14px;width:14px;display:inline-block;border:1px solid currentColor;background-color:var(--cl,#fff)}</style>"));
|
||||||
|
|
||||||
// sort elements by name, then by id
|
// sort elements by name, then by id
|
||||||
uint8_t sorted_idx[zigbee_num];
|
uint8_t sorted_idx[zigbee_num];
|
||||||
|
@ -1393,20 +1394,45 @@ void ZigbeeShow(bool json)
|
||||||
bool pressure_ok = device.validPressure();
|
bool pressure_ok = device.validPressure();
|
||||||
|
|
||||||
if (temperature_ok || humidity_ok || pressure_ok) {
|
if (temperature_ok || humidity_ok || pressure_ok) {
|
||||||
WSContentSend_P(PSTR("<tr><td colspan=\"3\">| "));
|
WSContentSend_P(PSTR("<tr><td colspan=\"3\">┆"));
|
||||||
if (temperature_ok) {
|
if (temperature_ok) {
|
||||||
char buf[12];
|
char buf[12];
|
||||||
dtostrf(device.temperature / 10.0f, 3, 1, buf);
|
dtostrf(device.temperature / 10.0f, 3, 1, buf);
|
||||||
WSContentSend_PD(PSTR(" ☀️%s°C"), buf);
|
WSContentSend_PD(PSTR(" ☀️%s°C"), buf);
|
||||||
}
|
}
|
||||||
if (humidity_ok) {
|
if (humidity_ok) {
|
||||||
WSContentSend_P(PSTR(" 💧%d%%"), device.humidity);
|
WSContentSend_P(PSTR(" 💧%d%%"), device.humidity);
|
||||||
}
|
}
|
||||||
if (pressure_ok) {
|
if (pressure_ok) {
|
||||||
WSContentSend_P(PSTR(" ⛅ %d hPa"), device.pressure);
|
WSContentSend_P(PSTR(" ⛅ %d hPa"), device.pressure);
|
||||||
}
|
}
|
||||||
WSContentSend_P(PSTR("{e}"));
|
WSContentSend_P(PSTR("{e}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Light and switches
|
||||||
|
bool power_ok = device.validPower();
|
||||||
|
if (power_ok) {
|
||||||
|
uint8_t channels = device.getLightChannels();
|
||||||
|
if (0xFF == channels) { channels = 5; } // if number of channel is unknown, display all known attributes
|
||||||
|
WSContentSend_P(PSTR("<tr><td colspan=\"3\">┆ %s"), device.getPower() ? PSTR(D_ON) : PSTR(D_OFF));
|
||||||
|
if (device.validDimmer() && (channels >= 1)) {
|
||||||
|
WSContentSend_P(PSTR(" 🔅%d%%"), changeUIntScale(device.dimmer,0,254,0,100));
|
||||||
|
}
|
||||||
|
if (device.validCT() && ((channels == 2) || (channels == 5))) {
|
||||||
|
uint32_t ct_k = (((1000000 / device.ct) + 25) / 50) * 50;
|
||||||
|
WSContentSend_P(PSTR(" <span title=\"CT %d\"><small>⚪ </small>%dK</span>"), device.ct, ct_k);
|
||||||
|
}
|
||||||
|
if (device.validHue() && device.validSat() && (channels >= 3)) {
|
||||||
|
uint8_t r,g,b;
|
||||||
|
uint8_t sat = changeUIntScale(device.sat, 0, 254, 0, 255); // scale to 0..255
|
||||||
|
LightStateClass::HsToRgb(device.hue, sat, &r, &g, &b);
|
||||||
|
WSContentSend_P(PSTR(" <i class=\"bx\" style=\"--cl:#%02X%02X%02X\"></i>#%02X%02X%02X"), r,g,b,r,g,b);
|
||||||
|
} else if (device.validX() && device.validY() && (channels >= 3)) {
|
||||||
|
uint8_t r,g,b;
|
||||||
|
LightStateClass::XyToRgb(device.x / 65535.0f, device.y / 65535.0f, &r, &g, &b);
|
||||||
|
WSContentSend_P(PSTR(" <i class=\"bx\" style=\"--cl:#%02X%02X%02X\"></i> #%02X%02X%02X"), r,g,b,r,g,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WSContentSend_P(PSTR("</table>{t}")); // Terminate current multi column table and open new table
|
WSContentSend_P(PSTR("</table>{t}")); // Terminate current multi column table and open new table
|
||||||
|
|
Loading…
Reference in New Issue