Merge pull request #8573 from randocollaboration/development

Add ability to toggle displayed temperature unit on Xiaomi LYWSD02
This commit is contained in:
Theo Arends 2020-05-30 08:19:36 +02:00 committed by GitHub
commit 01d92ca3a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 100 additions and 2 deletions

View File

@ -53,6 +53,8 @@ struct {
uint32_t willSetTime:1;
uint32_t shallReadBatt:1;
uint32_t willReadBatt:1;
uint32_t shallSetUnit:1;
uint32_t willSetUnit:1;
} mode;
struct {
uint8_t sensor; // points to to the number 0...255
@ -152,7 +154,7 @@ BLEScanResults MI32foundDevices;
const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}";
const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}";
const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery";
const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit";
#define FLORA 1
#define MJ_HT_V1 2
@ -185,7 +187,8 @@ enum MI32_Commands { // commands useable in console or rules
CMND_MI32_PERIOD, // set period like TELE-period in seconds between read-cycles
CMND_MI32_TIME, // set LYWSD02-Time from ESP8266-time
CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated
CMND_MI32_BATTERY // read all battery levels
CMND_MI32_BATTERY, // read all battery levels
CMND_MI32_UNIT // toggles the displayed unit between C/F (LYWSD02)
};
enum MI32_TASK {
@ -193,6 +196,7 @@ enum MI32_TASK {
MI32_TASK_CONN = 1,
MI32_TASK_TIME = 2,
MI32_TASK_BATT = 3,
MI32_TASK_UNIT = 4,
};
/*********************************************************************************************\
@ -394,6 +398,10 @@ void MI32StartTask(uint32_t task){
if (MI32.mode.willReadBatt == 1) return;
MI32StartBatteryTask();
break;
case MI32_TASK_UNIT:
if (MI32.mode.shallSetUnit == 0) return;
MI32StartUnitTask();
break;
default:
break;
}
@ -616,6 +624,72 @@ void MI32TimeTask(void *pvParameters){
vTaskDelete( NULL );
}
void MI32StartUnitTask(){
MI32.mode.willConnect = 1;
xTaskCreatePinnedToCore(
MI32UnitTask, /* Function to implement the task */
"MI32UnitTask", /* Name of the task */
8912, /* Stack size in words */
NULL, /* Task input parameter */
15, /* Priority of the task */
NULL, /* Task handle. */
0); /* Core where the task should run */
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Start unit set"),D_CMND_MI32);
// AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: with sensor: %u"),D_CMND_MI32, MI32.state.sensor);
}
void MI32UnitTask(void *pvParameters){
if (MIBLEsensors[MI32.state.sensor].type != LYWSD02) {
MI32.mode.shallSetUnit = 0;
vTaskDelete( NULL );
}
if(MI32ConnectActiveSensor()){
uint32_t timer = 0;
while (MI32.mode.connected == 0){
if (timer>1000){
break;
}
timer++;
vTaskDelay(10/ portTICK_PERIOD_MS);
}
NimBLERemoteService* pSvc = nullptr;
NimBLERemoteCharacteristic* pChr = nullptr;
static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6");
static BLEUUID charUUID("EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6");
pSvc = MI32Client->getService(serviceUUID);
if(pSvc) {
pChr = pSvc->getCharacteristic(charUUID);
}
if(pChr->canRead()){
uint8_t curUnit;
const char *buf = pChr->readValue().c_str();
if( buf[0] != 0 && buf[0]<101 ){
curUnit = buf[0];
}
if(pChr->canWrite()) {
curUnit = curUnit == 0x01?0xFF:0x01; // C/F
if(!pChr->writeValue(&curUnit,sizeof(curUnit),true)) { // true is important !
MI32.mode.willConnect = 0;
MI32Client->disconnect();
}
else {
MI32.mode.shallSetUnit = 0;
MI32.mode.willSetUnit = 0;
}
}
}
MI32Client->disconnect();
}
vTaskDelay(500/ portTICK_PERIOD_MS);
MI32.mode.connected = 0;
vTaskDelete( NULL );
}
void MI32StartBatteryTask(){
if (MI32.mode.connected) return;
MI32.mode.willReadBatt = 1;
@ -964,6 +1038,15 @@ void MI32EverySecond(bool restart){
}
}
if (MI32.mode.shallSetUnit) {
MI32.mode.canScan = 0;
MI32.mode.canConnect = 0;
if (MI32.mode.willSetUnit == 0){
MI32.mode.willSetUnit = 1;
MI32StartTask(MI32_TASK_UNIT);
}
}
if (MI32.mode.willReadBatt) return;
if (_counter>MI32.period) {
@ -1057,6 +1140,21 @@ bool MI32Cmd(void) {
}
Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload);
break;
case CMND_MI32_UNIT:
if (XdrvMailbox.data_len > 0) {
if(MIBLEsensors.size()>XdrvMailbox.payload){
if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02){
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will set Unit"),D_CMND_MI32);
MI32.state.sensor = XdrvMailbox.payload;
MI32.mode.canScan = 0;
MI32.mode.canConnect = 0;
MI32.mode.shallSetUnit = 1;
MI32.mode.willSetUnit = 0;
}
}
}
Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload);
break;
case CMND_MI32_PAGE:
if (XdrvMailbox.data_len > 0) {
if (XdrvMailbox.payload == 0) XdrvMailbox.payload = MI32.perPage; // ignore 0