mirror of https://github.com/arendst/Tasmota.git
Merge pull request #14807 from Staars/development
add yeelight dimmer to legacy Mi32
This commit is contained in:
commit
09ab5d2673
|
@ -236,6 +236,7 @@ struct mi_sensor_t{
|
|||
uint32_t NMT:1;
|
||||
uint32_t motion:1;
|
||||
uint32_t Btn:1;
|
||||
uint32_t knob:1;
|
||||
uint32_t door:1;
|
||||
uint32_t leak:1;
|
||||
};
|
||||
|
@ -254,6 +255,8 @@ struct mi_sensor_t{
|
|||
uint32_t motion:1;
|
||||
uint32_t noMotion:1;
|
||||
uint32_t Btn:1;
|
||||
uint32_t knob:1;
|
||||
uint32_t longpress:1; //needs no extra feature bit, because knob is sufficient
|
||||
uint32_t door:1;
|
||||
uint32_t leak:1;
|
||||
};
|
||||
|
@ -285,11 +288,15 @@ struct mi_sensor_t{
|
|||
}; // MJ_HT_V1, LYWSD0x
|
||||
struct {
|
||||
uint16_t events; //"alarms" since boot
|
||||
uint32_t NMT; // no motion time in seconds for the MJYD2S
|
||||
uint32_t NMT; // no motion time in seconds for the MJYD2S and NLIGHT
|
||||
};
|
||||
struct {
|
||||
uint16_t Btn;
|
||||
uint8_t leak;
|
||||
uint8_t Btn; // number starting with 0
|
||||
uint8_t BtnType; // 0 -single, 1 - double, 2 - hold
|
||||
uint8_t leak; // the leak sensor is the only non-RC device so far with a button fuctionality, so we handle it here
|
||||
int8_t dimmer;
|
||||
uint8_t pressed; // dimmer knob pressed while rotating
|
||||
uint8_t longpress; // dimmer knob pressed without rotating
|
||||
};
|
||||
uint8_t door;
|
||||
};
|
||||
|
@ -315,9 +322,9 @@ struct mi_sensor_t{
|
|||
|
||||
#define D_CMND_MI32 "MI32"
|
||||
|
||||
const char kMI32_Commands[] PROGMEM = D_CMND_MI32 "|Key|"/*Time|Battery|Unit|Beacon|*/"Cfg|Option";
|
||||
const char kMI32_Commands[] PROGMEM = D_CMND_MI32 "|Key|Cfg|Option";
|
||||
|
||||
void (*const MI32_Commands[])(void) PROGMEM = {&CmndMi32Key, /*&CmndMi32Time, &CmndMi32Battery, &CmndMi32Unit, &CmndMi32Beacon,*/ &CmndMi32Cfg, &CmndMi32Option };
|
||||
void (*const MI32_Commands[])(void) PROGMEM = {&CmndMi32Key, &CmndMi32Cfg, &CmndMi32Option };
|
||||
|
||||
#define FLORA 1
|
||||
#define MJ_HT_V1 2
|
||||
|
@ -327,7 +334,7 @@ void (*const MI32_Commands[])(void) PROGMEM = {&CmndMi32Key, /*&CmndMi32Time, &C
|
|||
#define CGD1 6
|
||||
#define NLIGHT 7
|
||||
#define MJYD2S 8
|
||||
#define YEERC 9
|
||||
#define YLYK01 9
|
||||
#define MHOC401 10
|
||||
#define MHOC303 11
|
||||
#define ATC 12
|
||||
|
@ -346,7 +353,7 @@ const uint16_t kMI32DeviceID[MI32_TYPES]={ 0x0098, // Flora
|
|||
0x0576, // CGD1
|
||||
0x03dd, // NLIGHT
|
||||
0x07f6, // MJYD2S
|
||||
0x0153, // yee-rc
|
||||
0x0153, // YLYK01, old name yee-rc
|
||||
0x0387, // MHO-C401
|
||||
0x06d3, // MHO-C303
|
||||
0x0a1c, // ATC -> this is a fake ID
|
||||
|
@ -364,7 +371,7 @@ const char kMI32DeviceType5[] PROGMEM = "CGG1";
|
|||
const char kMI32DeviceType6[] PROGMEM = "CGD1";
|
||||
const char kMI32DeviceType7[] PROGMEM = "NLIGHT";
|
||||
const char kMI32DeviceType8[] PROGMEM = "MJYD2S";
|
||||
const char kMI32DeviceType9[] PROGMEM = "YEERC";
|
||||
const char kMI32DeviceType9[] PROGMEM = "YLYK01"; //old name yeerc
|
||||
const char kMI32DeviceType10[] PROGMEM ="MHOC401";
|
||||
const char kMI32DeviceType11[] PROGMEM ="MHOC303";
|
||||
const char kMI32DeviceType12[] PROGMEM ="ATC";
|
||||
|
@ -382,6 +389,8 @@ const char kMI32_ConnErrorMsg[] PROGMEM = "no Error|could not connect|got no ser
|
|||
const char kMI32_BLEInfoMsg[] PROGMEM = "Scan ended|Got Notification|Did connect|Did disconnect|Start scanning";
|
||||
|
||||
const char kMI32_HKInfoMsg[] PROGMEM = "HAP core started|HAP core did not start!!|HAP controller disconnected|HAP controller connected|HAP outlet added";
|
||||
|
||||
const char kMI32_ButtonMsg[] PROGMEM = "Single|Double|Hold"; //mapping: in Tasmota: 1,2,3 ; for HomeKit and Xiaomi 0,1,2
|
||||
/*********************************************************************************************\
|
||||
* enumerations
|
||||
\*********************************************************************************************/
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
--------------------------------------------------------------------------------------------
|
||||
Version yyyymmdd Action Description
|
||||
--------------------------------------------------------------------------------------------
|
||||
0.9.5.1 20220209 changed - rename YEERC to YLYK01, add dimmer YLKG08 (incl. YLKG07), change button report scheme
|
||||
-------
|
||||
0.9.5.0 20211016 changed - major rewrite, added mi32cfg (file and command), Homekit-Bridge,
|
||||
extended GUI,
|
||||
removed BLOCK, PERIOD, TIME, UNIT, BATTERY and PAGE -> replaced via Berry-Support
|
||||
-------
|
||||
0.9.1.7 20201116 changed - small bugfixes, add BLOCK and OPTION command, send BLE scan via MQTT
|
||||
-------
|
||||
0.9.1.0 20200712 changed - add lights and yeerc, add pure passive mode with decryption,
|
||||
0.9.1.0 20200712 changed - add lights and YLYK01, add pure passive mode with decryption,
|
||||
lots of refactoring
|
||||
-------
|
||||
0.9.0.1 20200706 changed - adapt to new NimBLE-API, tweak scan process
|
||||
|
@ -44,7 +46,7 @@
|
|||
#ifdef USE_MI_ESP32
|
||||
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
// #define USE_MI_ESP32_ENERGY //perpare for some GUI extensions
|
||||
// #define USE_MI_ESP32_ENERGY //prepare for some GUI extensions
|
||||
#endif
|
||||
|
||||
#define XSNS_62 62
|
||||
|
@ -256,6 +258,7 @@ void MI32AddKey(mi_bindKey_t keyMAC){
|
|||
_sensor.key = _key;
|
||||
unknownMAC=false;
|
||||
_sensor.status.hasWrongKey = 0;
|
||||
AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*) _sensor.key, 16);
|
||||
}
|
||||
}
|
||||
if(unknownMAC){
|
||||
|
@ -278,7 +281,7 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3
|
|||
mi_beacon_t *_beacon = (mi_beacon_t *)_buf;
|
||||
|
||||
uint8_t nonce[13]; //v3:13, v5:12
|
||||
uint32_t nonceLen =12; // most devices are v5
|
||||
uint32_t nonceLen = 12; // most devices are v5
|
||||
uint8_t tag[4] = {0};
|
||||
const unsigned char authData[1] = {0x11};
|
||||
size_t dataLen = _bufSize - 11 ; // _bufsize - frame - type - frame.counter - MAC
|
||||
|
@ -288,13 +291,6 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3
|
|||
return -2;
|
||||
}
|
||||
|
||||
// uint8_t _testBuf[] = {0x58,0x30,0xb6,0x03,0x36,0x8b,0x98,0xc5,0x41,0x24,0xf8,0x8b,0xb8,0xf2,0x66,0x13,0x51,0x00,0x00,0x00,0xd6};
|
||||
// uint8_t _testKey[] = {0xb8,0x53,0x07,0x51,0x58,0x48,0x8d,0x3d,0x3c,0x97,0x7c,0xa3,0x9a,0x5b,0x5e,0xa9};
|
||||
// _beacon = (mi_beacon_t *)_testBuf;
|
||||
// _bufSize = sizeof(_testBuf);
|
||||
// dataLen = _bufSize - 11 ; // _bufsize - frame - type - frame.counter - MAC
|
||||
|
||||
|
||||
uint32_t _version = (uint32_t)_beacon->frame.version;
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: encrypted msg from %s with version:%u"),kMI32DeviceType[MIBLEsensors[_slot].type-1],_version);
|
||||
|
||||
|
@ -335,8 +331,7 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3
|
|||
for (uint32_t i = 0; i<5; i++){
|
||||
nonce[i+8] = _beacon->MAC[i];
|
||||
}
|
||||
tag[0] = _buf[_bufSize-1];
|
||||
// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*) nonce, 13);
|
||||
// tag[0] = _buf[_bufSize-1]; // it is unclear, if this value is a checksum
|
||||
dataLen -= 4;
|
||||
}
|
||||
else{
|
||||
|
@ -345,7 +340,6 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3
|
|||
|
||||
br_aes_small_ctrcbc_keys keyCtx;
|
||||
br_aes_small_ctrcbc_init(&keyCtx, MIBLEsensors[_slot].key, 16);
|
||||
// br_aes_small_ctrcbc_init(&keyCtx, _testKey, 16);
|
||||
|
||||
br_ccm_context ctx;
|
||||
br_ccm_init(&ctx, &keyCtx.vtable);
|
||||
|
@ -355,9 +349,9 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3
|
|||
br_ccm_run(&ctx, 0, _payload, dataLen);
|
||||
|
||||
if(br_ccm_check_tag(&ctx, &tag)) return 0;
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: decrypted in %.2f mSec"),enctime);
|
||||
// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*) _payload, dataLen);
|
||||
if(_version == 3 && _payload[1] == 0x10) return 0; // no known way to really verify decryption, but 0x10 is expected here for button events
|
||||
return -1; // wrong key ... maybe corrupt data packet too
|
||||
}
|
||||
|
||||
|
@ -457,9 +451,13 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter)
|
|||
_newSensor.feature.bat=1;
|
||||
_newSensor.NMT=0;
|
||||
break;
|
||||
case YEERC: case YLKG08:
|
||||
_newSensor.feature.Btn=1;
|
||||
_newSensor.Btn=99;
|
||||
case YLYK01: case YLKG08:
|
||||
_newSensor.feature.Btn = 1;
|
||||
_newSensor.Btn = 99;
|
||||
if(_type == YLKG08){
|
||||
_newSensor.feature.knob = 1;
|
||||
_newSensor.dimmer = 0;
|
||||
}
|
||||
#ifdef USE_MI_HOMEKIT
|
||||
_newSensor.button_hap_service[0] = nullptr;
|
||||
#endif //USE_MI_HOMEKIT
|
||||
|
@ -1222,40 +1220,46 @@ if(decryptRet!=0){
|
|||
MIBLEsensors[_slot].lastTime = millis();
|
||||
switch(_payload.type){
|
||||
case 0x01:
|
||||
if(_payload.Btn.type == 4){ //knob dimmer
|
||||
if(_payload.Btn.type == 4){ //dimmer knob rotation
|
||||
MIBLEsensors[_slot].eventType.knob = 1;
|
||||
if(_payload.Btn.num == 0){
|
||||
if(_payload.Btn.value<128){
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("Rotate right: %u"),_payload.Btn.value);
|
||||
}
|
||||
else{
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("Rotate left: %u"),256 - _payload.Btn.value);
|
||||
}
|
||||
MIBLEsensors[_slot].pressed = 0;
|
||||
MIBLEsensors[_slot].dimmer = _payload.Btn.value;
|
||||
}
|
||||
else if(_payload.Btn.num<128){
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("Rotate right: %u"),_payload.Btn.num);
|
||||
else {
|
||||
MIBLEsensors[_slot].pressed = 1;
|
||||
MIBLEsensors[_slot].dimmer = _payload.Btn.num;
|
||||
}
|
||||
else{
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("Rotate left: %u"),256 - _payload.Btn.num);
|
||||
}
|
||||
return; //TODO: implement MQTT later
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
break; //To-Do: Map to HomeKit somehow or wait for real support of this device class in HomeKit
|
||||
}
|
||||
if(_payload.Btn.num == 1 && MIBLEsensors[_slot].feature.knob){ //dimmer knob long press
|
||||
MIBLEsensors[_slot].longpress = _payload.Btn.value;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
MIBLEsensors[_slot].eventType.longpress = 1;
|
||||
#ifdef USE_MI_HOMEKIT
|
||||
if((void**)MIBLEsensors[_slot].button_hap_service[0] != nullptr){
|
||||
mi_homekit_update_value(MIBLEsensors[_slot].button_hap_service[0], (float)2.0f, 0x01); // only one button, long press = 2
|
||||
}
|
||||
#endif //USE_MI_HOMEKIT
|
||||
break;
|
||||
}
|
||||
// single, double, long
|
||||
MIBLEsensors[_slot].Btn = _payload.Btn.num;
|
||||
if(MIBLEsensors[_slot].feature.knob){
|
||||
MIBLEsensors[_slot].BtnType = _payload.Btn.value - 1;
|
||||
}
|
||||
else{
|
||||
MIBLEsensors[_slot].BtnType = _payload.Btn.type;
|
||||
}
|
||||
MIBLEsensors[_slot].Btn=_payload.Btn.num + (_payload.Btn.type/2)*6;
|
||||
MIBLEsensors[_slot].eventType.Btn = 1;
|
||||
MI32.mode.shallTriggerTele = 1;
|
||||
#ifdef USE_MI_HOMEKIT
|
||||
{
|
||||
// {uint32_t _button = _payload.Btn.num + (_payload.Btn.type/2)*6;
|
||||
uint32_t _singleLong = 0;
|
||||
if(MIBLEsensors[_slot].Btn>5){
|
||||
MIBLEsensors[_slot].Btn = MIBLEsensors[_slot].Btn - 6;
|
||||
_singleLong = 2;
|
||||
}
|
||||
if(MIBLEsensors[_slot].Btn>5) break; //
|
||||
if(MIBLEsensors[_slot].Btn>5) break; // hard coded limit for now
|
||||
if((void**)MIBLEsensors[_slot].button_hap_service[MIBLEsensors[_slot].Btn] != nullptr){
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("Send Button %u: SingleLong:%u, pointer: %x"), MIBLEsensors[_slot].Btn,_singleLong,MIBLEsensors[_slot].button_hap_service[MIBLEsensors[_slot].Btn] );
|
||||
mi_homekit_update_value(MIBLEsensors[_slot].button_hap_service[MIBLEsensors[_slot].Btn], (float)_singleLong, 0x01);
|
||||
}
|
||||
}
|
||||
mi_homekit_update_value(MIBLEsensors[_slot].button_hap_service[MIBLEsensors[_slot].Btn], (float)MIBLEsensors[_slot].BtnType, 0x01);
|
||||
}
|
||||
#endif //USE_MI_HOMEKIT
|
||||
// AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 1: U16: %u Button"), MIBLEsensors[_slot].Btn );
|
||||
break;
|
||||
|
@ -1774,8 +1778,19 @@ void MI32sendWidget(uint32_t slot){
|
|||
WSContentSend_P(PSTR("</p>"));
|
||||
}
|
||||
}
|
||||
if(_sensor.feature.knob){
|
||||
if(_sensor.pressed == 0) {
|
||||
WSContentSend_P(PSTR("<p>Dimmer Steps: %d</p>"),_sensor.dimmer);
|
||||
}
|
||||
else {
|
||||
WSContentSend_P(PSTR("<p>Dimmer Steps pressed: %d</p>"),_sensor.dimmer);
|
||||
}
|
||||
WSContentSend_P(PSTR("<p>Long: %u</p>"),_sensor.longpress);
|
||||
}
|
||||
if(_sensor.feature.Btn){
|
||||
if(_sensor.Btn<12) WSContentSend_P(PSTR("<p>Last Button: %u</p>"),_sensor.Btn);
|
||||
char _message[16];
|
||||
GetTextIndexed(_message, sizeof(_message), _sensor.BtnType, kMI32_ButtonMsg);
|
||||
if(_sensor.Btn<12) WSContentSend_P(PSTR("<p>Button%u: %s</p>"),_sensor.Btn,_message);
|
||||
}
|
||||
if(_sensor.feature.motion){
|
||||
WSContentSend_P(PSTR("<p>Events: %u</p>"),_sensor.events);
|
||||
|
@ -1797,7 +1812,7 @@ void MI32sendWidget(uint32_t slot){
|
|||
WSContentSend_P(PSTR("<p>Leak !!!</p>"));
|
||||
}
|
||||
else{
|
||||
WSContentSend_P(PSTR("<p>no leak</p>"));
|
||||
WSContentSend_P(PSTR("<p>No leak</p>"));
|
||||
}
|
||||
}
|
||||
WSContentSend_P(PSTR("</div>"));
|
||||
|
@ -1990,7 +2005,29 @@ void MI32Show(bool json)
|
|||
#endif //USE_HOME_ASSISTANT
|
||||
){
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"Btn\":%u"),MIBLEsensors[i].Btn);
|
||||
ResponseAppend_P(PSTR("\"Button%u\":%u"),MIBLEsensors[i].Btn,MIBLEsensors[i].BtnType + 1); //internal type is Xiaomi/Homekit 0,1,2 -> Tasmota 1,2,3
|
||||
}
|
||||
}
|
||||
if (MIBLEsensors[i].feature.knob){
|
||||
if(MIBLEsensors[i].eventType.knob
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
||(hass_mode==2)
|
||||
#endif //USE_HOME_ASSISTANT
|
||||
){
|
||||
MI32ShowContinuation(&commaflg);
|
||||
char _pressed[3] = {'_','P',0};
|
||||
if (MIBLEsensors[i].pressed == 0){
|
||||
_pressed[0] = 0;
|
||||
}
|
||||
ResponseAppend_P(PSTR("\"Dimmer%s\":%d"),_pressed, MIBLEsensors[i].dimmer);
|
||||
}
|
||||
if(MIBLEsensors[i].eventType.longpress
|
||||
#ifdef USE_HOME_ASSISTANT
|
||||
||(hass_mode==2)
|
||||
#endif //USE_HOME_ASSISTANT
|
||||
){
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"Hold\":%d"), MIBLEsensors[i].longpress);
|
||||
}
|
||||
}
|
||||
} // minimal summary
|
||||
|
@ -1998,14 +2035,14 @@ void MI32Show(bool json)
|
|||
if(MIBLEsensors[i].eventType.motion || !MI32.mode.triggeredTele){
|
||||
if(MI32.mode.triggeredTele) {
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"motion\":1")); // only real-time
|
||||
ResponseAppend_P(PSTR("\"Motion\":1")); // only real-time
|
||||
}
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events);
|
||||
}
|
||||
else if(MIBLEsensors[i].eventType.noMotion && MI32.mode.triggeredTele){
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"motion\":0"));
|
||||
ResponseAppend_P(PSTR("\"Motion\":0"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2013,7 +2050,7 @@ void MI32Show(bool json)
|
|||
if(MIBLEsensors[i].eventType.door || !MI32.mode.triggeredTele){
|
||||
if(MI32.mode.triggeredTele) {
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"DOOR\":%u"),MIBLEsensors[i].door); // only real-time
|
||||
ResponseAppend_P(PSTR("\"Door\":%u"),MIBLEsensors[i].door);
|
||||
}
|
||||
MI32ShowContinuation(&commaflg);
|
||||
ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events);
|
||||
|
@ -2131,7 +2168,7 @@ void MI32Show(bool json)
|
|||
if(MIBLEsensors[i].bat!=0x00){
|
||||
WSContentSend_PD(HTTP_BATTERY, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat);
|
||||
}
|
||||
if (MIBLEsensors[i].type==YEERC){
|
||||
if (MIBLEsensors[i].type==YLYK01){
|
||||
WSContentSend_PD(HTTP_LASTBUTTON, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].Btn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ static bool MIBridgeWasNeverConnected = true;
|
|||
#define CGD1 6
|
||||
#define NLIGHT 7
|
||||
#define MJYD2S 8
|
||||
#define YEERC 9
|
||||
#define YLYK01 9
|
||||
#define MHOC401 10
|
||||
#define MHOC303 11
|
||||
#define ATC 12
|
||||
|
@ -221,7 +221,7 @@ static void MI32_bridge_thread_entry(void *p)
|
|||
MI32saveHAPhandles(i,0x0a,hap_serv_get_char_by_uuid(service, HAP_CHAR_UUID_BATTERY_LEVEL));
|
||||
break;
|
||||
}
|
||||
case YEERC:
|
||||
case YLYK01:
|
||||
{
|
||||
bridge_cfg.cid = HAP_CID_PROGRAMMABLE_SWITCH;
|
||||
hap_serv_t * _label = hap_serv_service_label_create(1);
|
||||
|
@ -237,6 +237,20 @@ static void MI32_bridge_thread_entry(void *p)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case YLKG08: //without the dimmer function due to lack of HomeKit support
|
||||
{
|
||||
bridge_cfg.cid = HAP_CID_PROGRAMMABLE_SWITCH;
|
||||
hap_serv_t * _label = hap_serv_service_label_create(1);
|
||||
hap_acc_add_serv(accessory, _label);
|
||||
hap_serv_t * _newSwitch = hap_serv_stateless_programmable_switch_create(0);
|
||||
const uint8_t _validVals[] = {0,1,2};
|
||||
hap_char_add_valid_vals(hap_serv_get_char_by_uuid(_newSwitch, HAP_CHAR_UUID_PROGRAMMABLE_SWITCH_EVENT), _validVals, 3);
|
||||
hap_char_t *_index = hap_char_service_label_index_create(1);
|
||||
hap_serv_add_char(_newSwitch,_index);
|
||||
hap_acc_add_serv(accessory, _newSwitch);
|
||||
MI32saveHAPhandles(i,1000,hap_serv_get_char_by_uuid(_newSwitch, HAP_CHAR_UUID_PROGRAMMABLE_SWITCH_EVENT));
|
||||
}
|
||||
break;
|
||||
case SJWS01L:
|
||||
service = hap_serv_leak_sensor_create(0);
|
||||
hap_serv_set_bulk_read_cb(service, MI32_bridge_read_callback);
|
||||
|
|
Loading…
Reference in New Issue