mirror of https://github.com/arendst/Tasmota.git
Merge pull request #9133 from s-hadinger/zigbee_aug_20
Zigbee device profile phase 1
This commit is contained in:
commit
dd4f185ba8
|
@ -22,7 +22,7 @@
|
|||
#include <vector>
|
||||
|
||||
#ifndef ZIGBEE_SAVE_DELAY_SECONDS
|
||||
#define ZIGBEE_SAVE_DELAY_SECONDS 2; // wait for 2s before saving Zigbee info
|
||||
#define ZIGBEE_SAVE_DELAY_SECONDS 2 // wait for 2s before saving Zigbee info
|
||||
#endif
|
||||
const uint16_t kZigbeeSaveDelaySeconds = ZIGBEE_SAVE_DELAY_SECONDS; // wait for x seconds
|
||||
|
||||
|
@ -63,14 +63,25 @@ typedef struct Z_Device {
|
|||
uint16_t shortaddr; // unique key if not null, or unspecified if null
|
||||
uint8_t seqNumber;
|
||||
// Light information for Hue integration integration, last known values
|
||||
int8_t bulbtype; // number of channel for the bulb: 0-5, or 0xFF if no Hue integration
|
||||
uint8_t zb_profile; // profile of the device
|
||||
// high 4 bits is device type:
|
||||
// 0x0. = bulb
|
||||
// 0x1. = switch
|
||||
// 0x2. = motion sensor
|
||||
// 0x3. = other alarms
|
||||
// 0xE. = reserved for extension
|
||||
// 0xF. = unknown
|
||||
// For Bulb (0x0.)
|
||||
// 0x0N = number of channel for the bulb: 0-5
|
||||
// 0x08 = the device is hidden from Alexa
|
||||
// other status
|
||||
uint8_t power; // power state (boolean), MSB (0x80) stands for reachable
|
||||
uint8_t colormode; // 0x00: Hue/Sat, 0x01: XY, 0x02: CT
|
||||
uint8_t dimmer; // last Dimmer value: 0-254
|
||||
uint8_t sat; // last Sat: 0..254
|
||||
uint16_t ct; // last CT: 153-500
|
||||
uint16_t hue; // last Hue: 0..359
|
||||
uint16_t x, y; // last color [x,y]
|
||||
uint8_t colormode; // 0x00: Hue/Sat, 0x01: XY, 0x02: CT | 0xFF not set, default 0x01
|
||||
uint8_t dimmer; // last Dimmer value: 0-254 | 0xFF not set, default 0x00
|
||||
uint8_t sat; // last Sat: 0..254 | 0xFF not set, default 0x00
|
||||
uint16_t ct; // last CT: 153-500 | 0xFFFF not set, default 200
|
||||
uint16_t hue; // last Hue: 0..359 | 0xFFFF not set, default 0
|
||||
uint16_t x, y; // last color [x,y] | 0xFFFF not set, default 0
|
||||
uint8_t linkquality; // lqi from last message, 0xFF means unknown
|
||||
uint8_t batterypercent; // battery percentage (0..100), 0xFF means unknwon
|
||||
} Z_Device;
|
||||
|
@ -163,9 +174,15 @@ public:
|
|||
String dump(uint32_t dump_mode, uint16_t status_shortaddr = 0) const;
|
||||
int32_t deviceRestore(const JsonObject &json);
|
||||
|
||||
// General Zigbee device profile support
|
||||
void setZbProfile(uint16_t shortaddr, uint8_t zb_profile);
|
||||
uint8_t getZbProfile(uint16_t shortaddr) const ;
|
||||
|
||||
// Hue support
|
||||
void setHueBulbtype(uint16_t shortaddr, int8_t bulbtype);
|
||||
int8_t getHueBulbtype(uint16_t shortaddr) const ;
|
||||
void hideHueBulb(uint16_t shortaddr, bool hidden);
|
||||
bool isHueBulbHidden(uint16_t shortaddr) const ;
|
||||
void updateHueState(uint16_t shortaddr,
|
||||
const bool *power, const uint8_t *colormode,
|
||||
const uint8_t *dimmer, const uint8_t *sat,
|
||||
|
@ -236,6 +253,8 @@ private:
|
|||
void freeDeviceEntry(Z_Device *device);
|
||||
|
||||
void setStringAttribute(char*& attr, const char * str);
|
||||
|
||||
void updateZbProfile(uint16_t shortaddr);
|
||||
};
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -294,14 +313,14 @@ Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) {
|
|||
shortaddr,
|
||||
0, // seqNumber
|
||||
// Hue support
|
||||
-1, // no Hue support
|
||||
0xFF, // no Hue support
|
||||
0x80, // power off + reachable
|
||||
0, // colormode
|
||||
0, // dimmer
|
||||
0, // sat
|
||||
200, // ct
|
||||
0, // hue
|
||||
0, 0, // x, y
|
||||
0xFF, // colormode
|
||||
0xFF, // dimmer
|
||||
0xFF, // sat
|
||||
0xFFFF, // ct
|
||||
0xFFFF, // hue
|
||||
0xFFFF, 0xFFFF, // x, y
|
||||
0xFF, // lqi, 0xFF = unknown
|
||||
0xFF // battery percentage x 2, 0xFF means unknown
|
||||
};
|
||||
|
@ -691,24 +710,99 @@ uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Hue support
|
||||
void Z_Devices::setHueBulbtype(uint16_t shortaddr, int8_t bulbtype) {
|
||||
// General Zigbee device profile support
|
||||
void Z_Devices::setZbProfile(uint16_t shortaddr, uint8_t zb_profile) {
|
||||
Z_Device &device = getShortAddr(shortaddr);
|
||||
if (bulbtype != device.bulbtype) {
|
||||
device.bulbtype = bulbtype;
|
||||
if (zb_profile != device.zb_profile) {
|
||||
device.zb_profile = zb_profile;
|
||||
updateZbProfile(shortaddr);
|
||||
dirty();
|
||||
}
|
||||
}
|
||||
int8_t Z_Devices::getHueBulbtype(uint16_t shortaddr) const {
|
||||
|
||||
// Do all the required action when a profile is changed
|
||||
void Z_Devices::updateZbProfile(uint16_t shortaddr) {
|
||||
Z_Device &device = getShortAddr(shortaddr);
|
||||
uint8_t zb_profile = device.zb_profile;
|
||||
if (0xFF == zb_profile) { return; }
|
||||
|
||||
switch (zb_profile & 0xF0) {
|
||||
case 0x00: // bulb profile
|
||||
{
|
||||
uint32_t channels = zb_profile & 0x07;
|
||||
// depending on the bulb type, the default parameters from unknown to credible defaults
|
||||
if (0xFF == device.power) { device.power = 0; }
|
||||
if (1 <= channels) {
|
||||
if (0xFF == device.dimmer) { device.dimmer = 0; }
|
||||
}
|
||||
if (3 <= channels) {
|
||||
if (0xFF == device.sat) { device.sat = 0; }
|
||||
if (0xFFFF == device.hue) { device.hue = 0; }
|
||||
if (0xFFFF == device.x) { device.x = 0; }
|
||||
if (0xFFFF == device.y) { device.y = 0; }
|
||||
if (0xFF == device.colormode) { device.colormode = 0; } // HueSat mode
|
||||
}
|
||||
if ((2 == channels) || (5 == channels)) {
|
||||
if (0xFFFF == device.ct) { device.ct = 200; }
|
||||
if (0xFF == device.colormode) { device.colormode = 2; } // CT mode
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the device profile or 0xFF if the device or profile is unknown
|
||||
uint8_t Z_Devices::getZbProfile(uint16_t shortaddr) const {
|
||||
int32_t found = findShortAddr(shortaddr);
|
||||
if (found >= 0) {
|
||||
return _devices[found]->bulbtype;
|
||||
return _devices[found]->zb_profile;
|
||||
} else {
|
||||
return -1; // Hue not activated
|
||||
return 0xFF; // Hue not activated
|
||||
}
|
||||
}
|
||||
|
||||
// Hue support
|
||||
void Z_Devices::setHueBulbtype(uint16_t shortaddr, int8_t bulbtype) {
|
||||
uint8_t zb_profile = (0 > bulbtype) ? 0xFF : (bulbtype & 0x07);
|
||||
setZbProfile(shortaddr, zb_profile);
|
||||
}
|
||||
|
||||
int8_t Z_Devices::getHueBulbtype(uint16_t shortaddr) const {
|
||||
uint8_t zb_profile = getZbProfile(shortaddr);
|
||||
if (0x00 == (zb_profile & 0xF0)) {
|
||||
return (zb_profile & 0x07);
|
||||
} else {
|
||||
// not a bulb
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Z_Devices::hideHueBulb(uint16_t shortaddr, bool hidden) {
|
||||
uint8_t hue_hidden_flag = hidden ? 0x08 : 0x00;
|
||||
|
||||
Z_Device &device = getShortAddr(shortaddr);
|
||||
if (0x00 == (device.zb_profile & 0xF0)) {
|
||||
// bulb type
|
||||
// set bit 3 accordingly
|
||||
if (hue_hidden_flag != (device.zb_profile & 0x08)) {
|
||||
device.zb_profile = (device.zb_profile & 0xF7) | hue_hidden_flag;
|
||||
dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
// true if device is not knwon or not a bulb - it wouldn't make sense to publish a non-bulb
|
||||
bool Z_Devices::isHueBulbHidden(uint16_t shortaddr) const {
|
||||
int32_t found = findShortAddr(shortaddr);
|
||||
if (found >= 0) {
|
||||
uint8_t zb_profile = _devices[found]->zb_profile;
|
||||
if (0x00 == (zb_profile & 0xF0)) {
|
||||
// bulb type
|
||||
return (zb_profile & 0x08) ? true : false;
|
||||
}
|
||||
}
|
||||
return true; // Fallback - Device is considered as hidden
|
||||
}
|
||||
|
||||
// Hue support
|
||||
void Z_Devices::updateHueState(uint16_t shortaddr,
|
||||
const bool *power, const uint8_t *colormode,
|
||||
|
@ -1056,27 +1150,17 @@ String Z_Devices::dumpLightState(uint16_t shortaddr) const {
|
|||
}
|
||||
|
||||
// expose the last known status of the bulb, for Hue integration
|
||||
dev[F(D_JSON_ZIGBEE_LIGHT)] = device.bulbtype; // sign extend, 0xFF changed as -1
|
||||
if (0 <= device.bulbtype) {
|
||||
// bulbtype is defined
|
||||
dev[F("Power")] = bitRead(device.power, 0);
|
||||
dev[F("Reachable")] = bitRead(device.power, 7);
|
||||
if (1 <= device.bulbtype) {
|
||||
dev[F("Dimmer")] = device.dimmer;
|
||||
}
|
||||
if (2 <= device.bulbtype) {
|
||||
dev[F("Colormode")] = device.colormode;
|
||||
}
|
||||
if ((2 == device.bulbtype) || (5 == device.bulbtype)) {
|
||||
dev[F("CT")] = device.ct;
|
||||
}
|
||||
if (3 <= device.bulbtype) {
|
||||
dev[F("Sat")] = device.sat;
|
||||
dev[F("Hue")] = device.hue;
|
||||
dev[F("X")] = device.x;
|
||||
dev[F("Y")] = device.y;
|
||||
}
|
||||
}
|
||||
dev[F(D_JSON_ZIGBEE_LIGHT)] = getHueBulbtype(shortaddr); // sign extend, 0xFF changed as -1
|
||||
// dump all known values
|
||||
dev[F("Reachable")] = bitRead(device.power, 7); // TODO TODO
|
||||
if (0xFF != device.power) { dev[F("Power")] = bitRead(device.power, 0); }
|
||||
if (0xFF != device.dimmer) { dev[F("Dimmer")] = device.dimmer; }
|
||||
if (0xFF != device.colormode) { dev[F("Colormode")] = device.colormode; }
|
||||
if (0xFFFF != device.ct) { dev[F("CT")] = device.ct; }
|
||||
if (0xFF != device.sat) { dev[F("Sat")] = device.sat; }
|
||||
if (0xFFFF != device.hue) { dev[F("Hue")] = device.hue; }
|
||||
if (0xFFFF != device.x) { dev[F("X")] = device.x; }
|
||||
if (0xFFFF != device.y) { dev[F("Y")] = device.y; }
|
||||
}
|
||||
|
||||
String payload = "";
|
||||
|
@ -1119,8 +1203,9 @@ String Z_Devices::dump(uint32_t dump_mode, uint16_t status_shortaddr) const {
|
|||
if (device.modelId) {
|
||||
dev[F(D_JSON_MODEL D_JSON_ID)] = device.modelId;
|
||||
}
|
||||
if (device.bulbtype >= 0) {
|
||||
dev[F(D_JSON_ZIGBEE_LIGHT)] = device.bulbtype; // sign extend, 0xFF changed as -1
|
||||
int8_t bulbtype = getHueBulbtype(shortaddr);
|
||||
if (bulbtype >= 0) {
|
||||
dev[F(D_JSON_ZIGBEE_LIGHT)] = bulbtype; // sign extend, 0xFF changed as -1
|
||||
}
|
||||
if (device.manufacturerId) {
|
||||
dev[F("Manufacturer")] = device.manufacturerId;
|
||||
|
|
|
@ -103,10 +103,10 @@ void ZigbeeHueStatus(String * response, uint16_t shortaddr) {
|
|||
void ZigbeeCheckHue(String * response, bool &appending) {
|
||||
uint32_t zigbee_num = zigbee_devices.devicesSize();
|
||||
for (uint32_t i = 0; i < zigbee_num; i++) {
|
||||
int8_t bulbtype = zigbee_devices.devicesAt(i).bulbtype;
|
||||
uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr;
|
||||
int8_t bulbtype = zigbee_devices.getHueBulbtype(shortaddr);
|
||||
|
||||
if (bulbtype >= 0) {
|
||||
uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr;
|
||||
// this bulb is advertized
|
||||
if (appending) { *response += ","; }
|
||||
*response += "\"";
|
||||
|
@ -122,7 +122,8 @@ void ZigbeeCheckHue(String * response, bool &appending) {
|
|||
void ZigbeeHueGroups(String * lights) {
|
||||
uint32_t zigbee_num = zigbee_devices.devicesSize();
|
||||
for (uint32_t i = 0; i < zigbee_num; i++) {
|
||||
int8_t bulbtype = zigbee_devices.devicesAt(i).bulbtype;
|
||||
uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr;
|
||||
int8_t bulbtype = zigbee_devices.getHueBulbtype(shortaddr);
|
||||
|
||||
if (bulbtype >= 0) {
|
||||
*lights += ",\"";
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
// str - FriendlyName (null terminated C string, 32 chars max)
|
||||
// reserved for extensions
|
||||
// -- V2 --
|
||||
// int8_t - bulbtype
|
||||
// int8_t - zigbee profile of the device
|
||||
|
||||
// Memory footprint
|
||||
#ifdef ESP8266
|
||||
|
@ -126,8 +126,8 @@ class SBuffer hibernateDevice(const struct Z_Device &device) {
|
|||
}
|
||||
buf.add8(0x00); // end of string marker
|
||||
|
||||
// Hue Bulbtype
|
||||
buf.add8(device.bulbtype);
|
||||
// Zigbee Profile
|
||||
buf.add8(device.zb_profile);
|
||||
|
||||
// update overall length
|
||||
buf.set8(0, buf.len());
|
||||
|
@ -225,7 +225,7 @@ void hydrateDevices(const SBuffer &buf) {
|
|||
|
||||
// Hue bulbtype - if present
|
||||
if (d < dev_record_len) {
|
||||
zigbee_devices.setHueBulbtype(shortaddr, buf_d.get8(d));
|
||||
zigbee_devices.setZbProfile(shortaddr, buf_d.get8(d));
|
||||
d++;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef struct Z_AttributeConverter {
|
|||
uint8_t cluster_short;
|
||||
uint16_t attribute;
|
||||
const char * name;
|
||||
int16_t multiplier; // multiplier for numerical value, (if > 0 multiply by x, if <0 device by x)
|
||||
int8_t multiplier; // multiplier for numerical value, (if > 0 multiply by x, if <0 device by x)
|
||||
uint8_t cb; // callback func from Z_ConvOperators
|
||||
// Z_AttrConverter func;
|
||||
} Z_AttributeConverter;
|
||||
|
@ -142,10 +142,12 @@ enum Z_ConvOperators {
|
|||
};
|
||||
|
||||
ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId)
|
||||
ZF(DateCode) ZF(PowerSource) ZF(SWBuildID) ZF(Power) ZF(SwitchType) ZF(Dimmer)
|
||||
ZF(GenericDeviceClass) ZF(GenericDeviceType) ZF(ProductCode) ZF(ProductURL)
|
||||
ZF(DateCode) ZF(PowerSource) ZF(SWBuildID) ZF(Power) ZF(SwitchType) ZF(Dimmer) ZF(DimmerOptions)
|
||||
ZF(DimmerRemainingTime) ZF(OnOffTransitionTime) ZF(StartUpOnOff)
|
||||
ZF(MainsVoltage) ZF(MainsFrequency) ZF(BatteryVoltage) ZF(BatteryPercentage)
|
||||
ZF(CurrentTemperature) ZF(MinTempExperienced) ZF(MaxTempExperienced) ZF(OverTempTotalDwell)
|
||||
ZF(IdentifyTime)
|
||||
ZF(IdentifyTime) ZF(GroupNameSupport)
|
||||
ZF(SceneCount) ZF(CurrentScene) ZF(CurrentGroup) ZF(SceneValid)
|
||||
ZF(AlarmCount) ZF(Time) ZF(TimeStatus) ZF(TimeZone) ZF(DstStart) ZF(DstEnd)
|
||||
ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) ZF(TimeEpoch)
|
||||
|
@ -243,6 +245,10 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
|||
{ Zstring, Cx0000, 0x0005, Z(ModelId), 1, Z_ModelKeep }, // record Model
|
||||
{ Zstring, Cx0000, 0x0006, Z(DateCode), 1, Z_Nop },
|
||||
{ Zenum8, Cx0000, 0x0007, Z(PowerSource), 1, Z_Nop },
|
||||
{ Zenum8, Cx0000, 0x0008, Z(GenericDeviceClass), 1, Z_Nop },
|
||||
{ Zenum8, Cx0000, 0x0009, Z(GenericDeviceType), 1, Z_Nop },
|
||||
{ Zoctstr, Cx0000, 0x000A, Z(ProductCode), 1, Z_Nop },
|
||||
{ Zstring, Cx0000, 0x000B, Z(ProductURL), 1, Z_Nop },
|
||||
{ Zstring, Cx0000, 0x4000, Z(SWBuildID), 1, Z_Nop },
|
||||
// { Zunk, Cx0000, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values
|
||||
// Cmd 0x0A - Cluster 0x0000, attribute 0xFF01 - proprietary
|
||||
|
@ -263,6 +269,9 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
|||
// Identify cluster
|
||||
{ Zuint16, Cx0003, 0x0000, Z(IdentifyTime), 1, Z_Nop },
|
||||
|
||||
// Groups cluster
|
||||
{ Zmap8, Cx0004, 0x0000, Z(GroupNameSupport), 1, Z_Nop },
|
||||
|
||||
// Scenes cluster
|
||||
{ Zuint8, Cx0005, 0x0000, Z(SceneCount), 1, Z_Nop },
|
||||
{ Zuint8, Cx0005, 0x0001, Z(CurrentScene), 1, Z_Nop },
|
||||
|
@ -272,6 +281,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
|||
|
||||
// On/off cluster
|
||||
{ Zbool, Cx0006, 0x0000, Z(Power), 1, Z_Nop },
|
||||
{ Zenum8, Cx0006, 0x4003, Z(StartUpOnOff), 1, Z_Nop },
|
||||
{ Zbool, Cx0006, 0x8000, Z(Power), 1, Z_Nop }, // See 7280
|
||||
|
||||
// On/Off Switch Configuration cluster
|
||||
|
@ -279,12 +289,13 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
|
|||
|
||||
// Level Control cluster
|
||||
{ Zuint8, Cx0008, 0x0000, Z(Dimmer), 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0001, Z(RemainingTime", 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0010, Z(OnOffTransitionTime", 1, Z_Nop },
|
||||
// { Zuint8, Cx0008, 0x0011, Z(OnLevel", 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0012, Z(OnTransitionTime", 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0013, Z(OffTransitionTime", 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0014, Z(DefaultMoveRate", 1, Z_Nop },
|
||||
{ Zmap8, Cx0008, 0x000F, Z(DimmerOptions), 1, Z_Nop },
|
||||
{ Zuint16, Cx0008, 0x0001, Z(DimmerRemainingTime), 1, Z_Nop },
|
||||
{ Zuint16, Cx0008, 0x0010, Z(OnOffTransitionTime), 1, Z_Nop },
|
||||
// { Zuint8, Cx0008, 0x0011, Z(OnLevel), 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0012, Z(OnTransitionTime), 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0013, Z(OffTransitionTime), 1, Z_Nop },
|
||||
// { Zuint16, Cx0008, 0x0014, Z(DefaultMoveRate), 1, Z_Nop },
|
||||
|
||||
// Alarms cluster
|
||||
{ Zuint16, Cx0009, 0x0000, Z(AlarmCount), 1, Z_Nop },
|
||||
|
@ -615,7 +626,7 @@ typedef union ZCLHeaderFrameControl_t {
|
|||
// If not found:
|
||||
// - returns nullptr
|
||||
const __FlashStringHelper* zigbeeFindAttributeByName(const char *command,
|
||||
uint16_t *cluster, uint16_t *attribute, int16_t *multiplier,
|
||||
uint16_t *cluster, uint16_t *attribute, int8_t *multiplier,
|
||||
uint8_t *cb) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) {
|
||||
const Z_AttributeConverter *converter = &Z_PostProcess[i];
|
||||
|
@ -623,7 +634,7 @@ const __FlashStringHelper* zigbeeFindAttributeByName(const char *command,
|
|||
if (0 == strcasecmp_P(command, converter->name)) {
|
||||
if (cluster) { *cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); }
|
||||
if (attribute) { *attribute = pgm_read_word(&converter->attribute); }
|
||||
if (multiplier) { *multiplier = pgm_read_word(&converter->multiplier); }
|
||||
if (multiplier) { *multiplier = pgm_read_byte(&converter->multiplier); }
|
||||
if (cb) { *cb = pgm_read_byte(&converter->cb); }
|
||||
return (const __FlashStringHelper*) converter->name;
|
||||
}
|
||||
|
@ -1363,7 +1374,6 @@ int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObjec
|
|||
// presentValue = x + 128 = 180º flip to side x on top
|
||||
// presentValue = x + 256 = push/slide cube while side x is on top
|
||||
// presentValue = x + 512 = double tap while side x is on top
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1487,7 +1497,7 @@ int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObj
|
|||
|
||||
// apply the transformation from the converter
|
||||
int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name,
|
||||
uint16_t cluster, uint16_t attr, int16_t multiplier, uint8_t cb) {
|
||||
uint16_t cluster, uint16_t attr, int8_t multiplier, uint8_t cb) {
|
||||
// apply multiplier if needed
|
||||
if (1 == multiplier) { // copy unchanged
|
||||
json[new_name] = value;
|
||||
|
@ -1596,7 +1606,7 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) {
|
|||
const Z_AttributeConverter *converter = &Z_PostProcess[i];
|
||||
uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short));
|
||||
uint16_t conv_attribute = pgm_read_word(&converter->attribute);
|
||||
int16_t conv_multiplier = pgm_read_word(&converter->multiplier);
|
||||
int8_t conv_multiplier = pgm_read_byte(&converter->multiplier);
|
||||
uint8_t conv_cb = pgm_read_byte(&converter->cb); // callback id
|
||||
|
||||
if ((conv_cluster == cluster) &&
|
||||
|
|
|
@ -190,7 +190,7 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint,
|
|||
// multiplier == 1: ignore
|
||||
// multiplier > 0: divide by the multiplier
|
||||
// multiplier < 0: multiply by the -multiplier (positive)
|
||||
void ZbApplyMultiplier(double &val_d, int16_t multiplier) {
|
||||
void ZbApplyMultiplier(double &val_d, int8_t multiplier) {
|
||||
if ((0 != multiplier) && (1 != multiplier)) {
|
||||
if (multiplier > 0) { // inverse of decoding
|
||||
val_d = val_d / multiplier;
|
||||
|
@ -217,7 +217,7 @@ void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t
|
|||
uint16_t attr_id = 0xFFFF;
|
||||
uint16_t cluster_id = 0xFFFF;
|
||||
uint8_t type_id = Znodata;
|
||||
int16_t multiplier = 1; // multiplier to adjust the key value
|
||||
int8_t multiplier = 1; // multiplier to adjust the key value
|
||||
double val_d = 0; // I try to avoid `double` but this type capture both float and (u)int32_t without prevision loss
|
||||
const char* val_str = ""; // variant as string
|
||||
|
||||
|
@ -245,7 +245,7 @@ void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t
|
|||
uint16_t local_attr_id = pgm_read_word(&converter->attribute);
|
||||
uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short));
|
||||
uint8_t local_type_id = pgm_read_byte(&converter->type);
|
||||
int16_t local_multiplier = pgm_read_word(&converter->multiplier);
|
||||
int8_t local_multiplier = pgm_read_byte(&converter->multiplier);
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Try cluster = 0x%04X, attr = 0x%04X, type_id = 0x%02X"), local_cluster_id, local_attr_id, local_type_id);
|
||||
|
||||
if (delimiter) {
|
||||
|
|
Loading…
Reference in New Issue