From 08ae94ff5b5be0d61d25ce3bd5b6da9f3ae9c788 Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Fri, 7 Oct 2022 16:10:19 +0200 Subject: [PATCH 01/14] cleanups and handle unknown sensors --- tasmota/include/xsns_62_esp32_mi.h | 29 +-- .../xdrv_52_3_berry_MI32.ino | 2 +- .../tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 192 +++++++----------- .../xsns_62_esp32_mi_homekit.c | 5 +- 4 files changed, 80 insertions(+), 148 deletions(-) diff --git a/tasmota/include/xsns_62_esp32_mi.h b/tasmota/include/xsns_62_esp32_mi.h index dd404ab14..409821481 100644 --- a/tasmota/include/xsns_62_esp32_mi.h +++ b/tasmota/include/xsns_62_esp32_mi.h @@ -230,6 +230,7 @@ struct mi_sensor_t{ uint8_t lastCnt; //device generated counter of the packet uint8_t shallSendMQTT; uint8_t MAC[6]; + uint16_t PID; uint8_t *key; uint32_t lastTimeSeen; union { @@ -335,6 +336,7 @@ const char kMI32_Commands[] PROGMEM = D_CMND_MI32 "|Key|Cfg|Option"; void (*const MI32_Commands[])(void) PROGMEM = {&CmndMi32Key, &CmndMi32Cfg, &CmndMi32Option }; +#define UNKNOWN_MI 0 #define FLORA 1 #define MJ_HT_V1 2 #define LYWSD02 3 @@ -351,8 +353,9 @@ void (*const MI32_Commands[])(void) PROGMEM = {&CmndMi32Key, &CmndMi32Cfg, &Cmnd #define SJWS01L 14 #define PVVX 15 #define YLKG08 16 +#define YLAI003 17 -#define MI32_TYPES 16 //count this manually +#define MI32_TYPES 17 //count this manually const uint16_t kMI32DeviceID[MI32_TYPES]={ 0x0098, // Flora 0x01aa, // MJ_HT_V1 @@ -369,29 +372,11 @@ const uint16_t kMI32DeviceID[MI32_TYPES]={ 0x0098, // Flora 0x098b, // MCCGQ02 0x0863, // SJWS01L 0x944a, // PVVX -> this is a fake ID - 0x03b6 // YLKG08 and YLKG07 - version w/wo mains + 0x03b6, // YLKG08 and YLKG07 - version w/wo mains + 0x07bf, // YLAI003 }; -const char kMI32DeviceType1[] PROGMEM = "Flora"; -const char kMI32DeviceType2[] PROGMEM = "MJ_HT_V1"; -const char kMI32DeviceType3[] PROGMEM = "LYWSD02"; -const char kMI32DeviceType4[] PROGMEM = "LYWSD03"; -const char kMI32DeviceType5[] PROGMEM = "CGG1"; -const char kMI32DeviceType6[] PROGMEM = "CGD1"; -const char kMI32DeviceType7[] PROGMEM = "NLIGHT"; -const char kMI32DeviceType8[] PROGMEM = "MJYD2S"; -const char kMI32DeviceType9[] PROGMEM = "YLYK01"; //old name yeerc -const char kMI32DeviceType10[] PROGMEM ="MHOC401"; -const char kMI32DeviceType11[] PROGMEM ="MHOC303"; -const char kMI32DeviceType12[] PROGMEM ="ATC"; -const char kMI32DeviceType13[] PROGMEM ="MCCGQ02"; -const char kMI32DeviceType14[] PROGMEM ="SJWS01L"; -const char kMI32DeviceType15[] PROGMEM ="PVVX"; -const char kMI32DeviceType16[] PROGMEM ="YLKG08"; -const char * kMI32DeviceType[] PROGMEM = {kMI32DeviceType1,kMI32DeviceType2,kMI32DeviceType3,kMI32DeviceType4, - kMI32DeviceType5,kMI32DeviceType6,kMI32DeviceType7,kMI32DeviceType8, - kMI32DeviceType9,kMI32DeviceType10,kMI32DeviceType11,kMI32DeviceType12, - kMI32DeviceType13,kMI32DeviceType14,kMI32DeviceType15,kMI32DeviceType16}; +const char kMI32DeviceType[] PROGMEM = {"Flora|MJ_HT_V1|LYWSD02|LYWSD03|CGG1|CGD1|NLIGHT|MJYD2S|YLYK01|MHOC401|MHOC303|ATC|MCCGQ02|SJWS01L|PVVX|YLKG08|YLAI003"}; const char kMI32_ConnErrorMsg[] PROGMEM = "no Error|could not connect|did disconnect|got no service|got no characteristic|can not read|can not notify|can not write|did not write|notify time out"; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino index 70b3743fa..52f9c02e0 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_MI32.ino @@ -36,7 +36,7 @@ extern "C" { ********************************************************************/ extern uint32_t MI32numberOfDevices(); - extern const char * MI32getDeviceName(uint32_t slot); + extern char * MI32getDeviceName(uint32_t slot); extern void MI32setBatteryForSlot(uint32_t slot, uint8_t value); extern void MI32setHumidityForSlot(uint32_t slot, float value); extern void MI32setTemperatureForSlot(uint32_t slot, float value); diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino index 55d84db7a..035e5a354 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino @@ -22,6 +22,8 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.5.6 20221006 changed - remove old HASS code, allow adding unknown sensors, prepare YLAI003 + ------- 0.9.5.5 20220326 changed - refactored connection task for asynchronous op, add response option, fixed MI32Key command ------- @@ -91,7 +93,7 @@ static BLEScan* MI32Scan; class MI32SensorCallback : public NimBLEClientCallbacks { void onConnect(NimBLEClient* pclient) { - // AddLog(LOG_LEVEL_DEBUG,PSTR("connected %s"), kMI32DeviceType[(MIBLEsensors[MI32.conCtx->slot].type)-1]); + // AddLog(LOG_LEVEL_DEBUG,PSTR("connected %s"), MI32getDeviceName(MI32.conCtx->slot)); MI32.infoMsg = MI32_DID_CONNECT; MI32.mode.willConnect = 0; MI32.mode.connected = 1; @@ -251,14 +253,16 @@ void MI32_ReverseMAC(uint8_t _mac[]){ void MI32AddKey(mi_bindKey_t keyMAC){ bool unknownMAC = true; + uint32_t _slot = 0; for(auto &_sensor : MIBLEsensors){ if(memcmp(keyMAC.MAC,_sensor.MAC,sizeof(keyMAC.MAC))==0){ _sensor.key = new uint8_t[16]; memcpy(_sensor.key,keyMAC.key,16); unknownMAC=false; _sensor.status.hasWrongKey = 0; - AddLog(LOG_LEVEL_INFO,PSTR("add key to %s"),kMI32DeviceType[_sensor.type-1]); + AddLog(LOG_LEVEL_INFO,PSTR("add key to %s"),MI32getDeviceName(_slot)); } + _slot++; } if(unknownMAC){ AddLog(LOG_LEVEL_ERROR,PSTR("M32: unknown MAC")); @@ -291,7 +295,7 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3 } 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); + // AddLog(LOG_LEVEL_DEBUG,PSTR("M32: encrypted msg from %s with version:%u"),MI32getDeviceName(_slot),_version); if(_version == 5){ if(_beacon->frame.includesMAC){ @@ -361,12 +365,13 @@ int MI32_decryptPacket(char * _buf, uint16_t _bufSize, uint8_t * _payload, uint3 /** * @brief Return the slot number of a known sensor or return create new sensor slot * - * @param _MAC BLE address of the sensor + * @param _MAC BLE address of the sensor * @param _type Type number of the sensor * @return uint32_t Known or new slot in the sensors-vector */ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter){ DEBUG_SENSOR_LOG(PSTR("%s: will test ID-type: %x"),D_CMND_MI32, _type); + uint16_t _pid = _type; // save for unknown types bool _success = false; for (uint32_t i=0;iMIBLEsensors.size()-1) return ""; - return kMI32DeviceType[MIBLEsensors[slot].type-1]; + char * MI32getDeviceName(uint32_t slot){ + static char _name[12]; + if( MIBLEsensors[slot].type == UNKNOWN_MI){ + snprintf_P(_name,8,PSTR("MI_%04X"),MIBLEsensors[slot].PID); + } + else{ + GetTextIndexed(_name, sizeof(_name), MIBLEsensors[slot].type-1, kMI32DeviceType); + } + return _name; } } //extern "C" @@ -1337,10 +1349,11 @@ if(decryptRet!=0){ return; } - // AddLog(LOG_LEVEL_DEBUG,PSTR("%s at slot %u with payload type: %02x"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot,_payload.type); + // AddLog(LOG_LEVEL_DEBUG,PSTR("%s at slot %u with payload type: %02x"), MI32getDeviceName(_slot),_slot,_payload.type); MIBLEsensors[_slot].lastTime = millis(); switch(_payload.type){ case 0x01: + MIBLEsensors[_slot].feature.Btn = 1; if(_payload.Btn.type == 4){ //dimmer knob rotation MIBLEsensors[_slot].eventType.knob = 1; if(_payload.Btn.num == 0){ @@ -1385,6 +1398,7 @@ if(decryptRet!=0){ // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 1: U16: %u Button"), MIBLEsensors[_slot].Btn ); break; case 0x04: + MIBLEsensors[_slot].feature.temp = 1; _tempFloat=(float)(_payload.temp)/10.0f; if(_tempFloat<60){ MIBLEsensors[_slot].temp=_tempFloat; @@ -1400,6 +1414,7 @@ if(decryptRet!=0){ // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _payload.temp ); break; case 0x06: + MIBLEsensors[_slot].feature.hum = 1; _tempFloat=(float)(_payload.hum)/10.0f; if(_tempFloat<101){ MIBLEsensors[_slot].hum=_tempFloat; @@ -1415,6 +1430,7 @@ if(decryptRet!=0){ // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _payload.hum); break; case 0x07: + MIBLEsensors[_slot].feature.lux = 1; MIBLEsensors[_slot].lux=_payload.lux & 0x00ffffff; if(MIBLEsensors[_slot].type==MJYD2S){ MIBLEsensors[_slot].eventType.noMotion = 1; @@ -1429,18 +1445,21 @@ if(decryptRet!=0){ // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _payload.lux & 0x00ffffff); break; case 0x08: + MIBLEsensors[_slot].feature.moist = 1; MIBLEsensors[_slot].moisture=_payload.moist; MIBLEsensors[_slot].eventType.moist = 1; DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _payload.moist); break; case 0x09: - MIBLEsensors[_slot].fertility=_payload.fert; - MIBLEsensors[_slot].eventType.fert = 1; - DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); + MIBLEsensors[_slot].feature.fert = 1; + MIBLEsensors[_slot].fertility=_payload.fert; + MIBLEsensors[_slot].eventType.fert = 1; + DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _payload.fert); break; case 0x0a: + MIBLEsensors[_slot].feature.bat = 1; if(MI32.option.ignoreBogusBattery){ if(MIBLEsensors[_slot].type==LYWSD03MMC || MIBLEsensors[_slot].type==MHOC401){ break; @@ -1473,6 +1492,8 @@ if(decryptRet!=0){ case 0x0f: if (_payload.ten!=0) break; + MIBLEsensors[_slot].feature.motion = 1; + MIBLEsensors[_slot].feature.NMT = 1; //only driver based MIBLEsensors[_slot].eventType.motion = 1; MIBLEsensors[_slot].events++; MIBLEsensors[_slot].lux = _payload.lux & 0x00ffffff; @@ -1489,6 +1510,7 @@ if(decryptRet!=0){ // AddLog(LOG_LEVEL_DEBUG,PSTR("motion: primary"),MIBLEsensors[_slot].lux ); break; case 0x14: + MIBLEsensors[_slot].feature.leak = 1; MIBLEsensors[_slot].leak = _payload.leak; MIBLEsensors[_slot].eventType.leak = 1; if(_payload.leak>0) MI32.mode.shallTriggerTele = 1; @@ -1497,12 +1519,14 @@ if(decryptRet!=0){ #endif //USE_MI_HOMEKIT break; case 0x17: + MIBLEsensors[_slot].feature.NMT = 1; MIBLEsensors[_slot].NMT = _payload.NMT; MIBLEsensors[_slot].eventType.NMT = 1; MI32.mode.shallTriggerTele = 1; // AddLog(LOG_LEVEL_DEBUG,PSTR("Mode 17: NMT: %u seconds"), _payload.NMT); break; case 0x19: + MIBLEsensors[_slot].feature.door = 1; MIBLEsensors[_slot].door = _payload.door; MIBLEsensors[_slot].eventType.door = 1; MIBLEsensors[_slot].events++; @@ -1544,7 +1568,7 @@ void MI32ParseATCPacket(char * _buf, uint32_t length, uint8_t addr[6], int RSSI) _slot = MIBLEgetSensorSlot(_packet->MAC, 0x944a, _packet->P.frameCnt); // ... and again } if(_slot==0xff) return; - // AddLog(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); + // AddLog(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), MI32getDeviceName(_slot),_slot); MIBLEsensors[_slot].RSSI=RSSI; MIBLEsensors[_slot].lastTime = millis(); @@ -1581,7 +1605,7 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int RSSI memcpy(_addr,addr,6); uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576, 0); // This must be hard-coded, no object-id in Cleargrass-packet, we have no packet counter too if(_slot==0xff) return; - // AddLog(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); + // AddLog(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), MI32getDeviceName(_slot),_slot); MIBLEsensors[_slot].RSSI=RSSI; MIBLEsensors[_slot].lastTime = millis(); cg_packet_t _packet; @@ -1918,9 +1942,9 @@ void MI32sendWidget(uint32_t slot){ snprintf_P(_bat,24,PSTR("🔋%u%%"), _sensor.bat); if(!_sensor.feature.bat) _bat[0] = 0; if (_sensor.bat == 0) _bat[9] = 0; - WSContentSend_P(HTTP_MI32_WIDGET,slot+1,_opacity,_MAC,_sensor.RSSI,_bat,_key,kMI32DeviceType[_sensor.type-1]); + WSContentSend_P(HTTP_MI32_WIDGET,slot+1,_opacity,_MAC,_sensor.RSSI,_bat,_key,MI32getDeviceName(slot)); - if(_sensor.feature.tempHum){ + if(_sensor.feature.temp && _sensor.feature.hum){ if(!isnan(_sensor.temp)){ char _polyline[176]; MI32createPolyline(_polyline,_sensor.temp_history); @@ -2058,15 +2082,6 @@ void MI32ShowContinuation(bool *commaflg) { void MI32Show(bool json) { if (json) { -#ifdef USE_HOME_ASSISTANT - bool _noSummarySave = MI32.option.noSummary; - bool _minimalSummarySave = MI32.option.minimalSummary; - if(hass_mode==2){ - MI32.option.noSummary = false; - MI32.option.minimalSummary = false; - } -#endif //USE_HOME_ASSISTANT - if(!MI32.mode.triggeredTele){ if(MI32.option.noSummary) return; // no message at TELEPERIOD } @@ -2077,18 +2092,14 @@ void MI32Show(bool json) bool commaflg = false; ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"), - kMI32DeviceType[MIBLEsensors[i].type-1], + MI32getDeviceName(i), MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); if((!MI32.mode.triggeredTele && !MI32.option.minimalSummary)||MI32.mode.triggeredTele){ bool tempHumSended = false; if(MIBLEsensors[i].feature.tempHum){ if(MIBLEsensors[i].eventType.tempHum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ - if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp) -#ifdef USE_HOME_ASSISTANT - ||(hass_mode!=-1) -#endif //USE_HOME_ASSISTANT - ) { + if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { MI32ShowContinuation(&commaflg); ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); tempHumSended = true; @@ -2097,11 +2108,7 @@ void MI32Show(bool json) } if(MIBLEsensors[i].feature.temp && !tempHumSended){ if(MIBLEsensors[i].eventType.temp || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) { - if (!isnan(MIBLEsensors[i].temp) -#ifdef USE_HOME_ASSISTANT - ||(hass_mode!=-1) -#endif //USE_HOME_ASSISTANT - ) { + if (!isnan(MIBLEsensors[i].temp)) { MI32ShowContinuation(&commaflg); ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f"), Settings->flag2.temperature_resolution, &MIBLEsensors[i].temp); @@ -2110,11 +2117,7 @@ void MI32Show(bool json) } if(MIBLEsensors[i].feature.hum && !tempHumSended){ if(MIBLEsensors[i].eventType.hum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) { - if (!isnan(MIBLEsensors[i].hum) -#ifdef USE_HOME_ASSISTANT - ||(hass_mode!=-1) -#endif //USE_HOME_ASSISTANT - ) { + if (!isnan(MIBLEsensors[i].hum)) { char hum[FLOATSZ]; dtostrfd(MIBLEsensors[i].hum, Settings->flag2.humidity_resolution, hum); MI32ShowContinuation(&commaflg); @@ -2124,17 +2127,7 @@ void MI32Show(bool json) } if (MIBLEsensors[i].feature.lux){ if(MIBLEsensors[i].eventType.lux || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ -#ifdef USE_HOME_ASSISTANT - if ((hass_mode != -1) && (MIBLEsensors[i].lux == 0x0ffffff)) { - MI32ShowContinuation(&commaflg); - ResponseAppend_P(PSTR("\"" D_JSON_ILLUMINANCE "\":null")); - } else -#endif //USE_HOME_ASSISTANT - if ((MIBLEsensors[i].lux != 0x0ffffff) -#ifdef USE_HOME_ASSISTANT - || (hass_mode != -1) -#endif //USE_HOME_ASSISTANT - ) { // this is the error code -> no lux + if ((MIBLEsensors[i].lux != 0x0ffffff)) { // this is the error code -> no lux MI32ShowContinuation(&commaflg); ResponseAppend_P(PSTR("\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); } @@ -2142,17 +2135,7 @@ void MI32Show(bool json) } if (MIBLEsensors[i].feature.moist){ if(MIBLEsensors[i].eventType.moist || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ -#ifdef USE_HOME_ASSISTANT - if ((hass_mode != -1) && (MIBLEsensors[i].moisture == 0xff)) { - MI32ShowContinuation(&commaflg); - ResponseAppend_P(PSTR("\"" D_JSON_MOISTURE "\":null")); - } else -#endif //USE_HOME_ASSISTANT - if ((MIBLEsensors[i].moisture != 0xff) -#ifdef USE_HOME_ASSISTANT - || (hass_mode != -1) -#endif //USE_HOME_ASSISTANT - ) { + if ((MIBLEsensors[i].moisture != 0xff)) { MI32ShowContinuation(&commaflg); ResponseAppend_P(PSTR("\"" D_JSON_MOISTURE "\":%u"), MIBLEsensors[i].moisture); } @@ -2160,38 +2143,20 @@ void MI32Show(bool json) } if (MIBLEsensors[i].feature.fert){ if(MIBLEsensors[i].eventType.fert || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ -#ifdef USE_HOME_ASSISTANT - if ((hass_mode != -1) && (MIBLEsensors[i].fertility == 0xffff)) { - MI32ShowContinuation(&commaflg); - ResponseAppend_P(PSTR("\"Fertility\":null")); - } else -#endif //USE_HOME_ASSISTANT - if ((MIBLEsensors[i].fertility != 0xffff) -#ifdef USE_HOME_ASSISTANT - || (hass_mode != -1) -#endif //USE_HOME_ASSISTANT - ) { + if ((MIBLEsensors[i].fertility != 0xffff)) { MI32ShowContinuation(&commaflg); ResponseAppend_P(PSTR("\"Fertility\":%u"), MIBLEsensors[i].fertility); } } } if (MIBLEsensors[i].feature.Btn){ - if(MIBLEsensors[i].eventType.Btn -#ifdef USE_HOME_ASSISTANT - ||(hass_mode==2) -#endif //USE_HOME_ASSISTANT - ){ + if(MIBLEsensors[i].eventType.Btn){ MI32ShowContinuation(&commaflg); 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 - ){ + if(MIBLEsensors[i].eventType.knob){ MI32ShowContinuation(&commaflg); char _pressed[3] = {'_','P',0}; if (MIBLEsensors[i].pressed == 0){ @@ -2199,11 +2164,7 @@ void MI32Show(bool json) } 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 - ){ + if(MIBLEsensors[i].eventType.longpress){ MI32ShowContinuation(&commaflg); ResponseAppend_P(PSTR("\"Hold\":%d"), MIBLEsensors[i].longpress); } @@ -2250,17 +2211,7 @@ void MI32Show(bool json) } if (MIBLEsensors[i].feature.bat){ if(MIBLEsensors[i].eventType.bat || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ -#ifdef USE_HOME_ASSISTANT - if ((hass_mode != -1) && (MIBLEsensors[i].bat == 0x00)) { - MI32ShowContinuation(&commaflg); - ResponseAppend_P(PSTR("\"Battery\":null")); - } else -#endif //USE_HOME_ASSISTANT - if ((MIBLEsensors[i].bat != 0x00) -#ifdef USE_HOME_ASSISTANT - || (hass_mode != -1) -#endif //USE_HOME_ASSISTANT - ) { + if ((MIBLEsensors[i].bat != 0x00)) { MI32ShowContinuation(&commaflg); ResponseAppend_P(PSTR("\"Battery\":%u"), MIBLEsensors[i].bat); } @@ -2279,12 +2230,6 @@ void MI32Show(bool json) } } MI32.mode.triggeredTele = 0; -#ifdef USE_HOME_ASSISTANT - if(hass_mode==2){ - MI32.option.noSummary = _noSummarySave; - MI32.option.minimalSummary = _minimalSummarySave; - } -#endif //USE_HOME_ASSISTANT #ifdef USE_MI_EXT_GUI Mi32invalidateOldHistory(); #ifdef USE_MI_ESP32_ENERGY @@ -2307,22 +2252,23 @@ void MI32Show(bool json) WSContentSend_PD(HTTP_MI32_HL); char _MAC[18]; ToHex_P(MIBLEsensors[i].MAC,6,_MAC,18,':'); - WSContentSend_PD(HTTP_MI32_MAC, kMI32DeviceType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, _MAC); - WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].RSSI); + const char * _sensorName = MI32getDeviceName(i); + WSContentSend_PD(HTTP_MI32_MAC, _sensorName, D_MAC_ADDRESS, _MAC); + WSContentSend_PD(HTTP_RSSI, _sensorName, MIBLEsensors[i].RSSI); if (MIBLEsensors[i].type==FLORA) { if (!isnan(MIBLEsensors[i].temp)) { - WSContentSend_Temp(kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp); + WSContentSend_Temp(_sensorName, MIBLEsensors[i].temp); } if (MIBLEsensors[i].moisture!=0xff) { - WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); + WSContentSend_PD(HTTP_SNS_MOISTURE, _sensorName, MIBLEsensors[i].moisture); } if (MIBLEsensors[i].fertility!=0xffff) { - WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); + WSContentSend_PD(HTTP_MI32_FLORA_DATA, _sensorName, MIBLEsensors[i].fertility); } } if (MIBLEsensors[i].type>FLORA) { // everything "above" Flora if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { - WSContentSend_THD(kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); + WSContentSend_THD(_sensorName, MIBLEsensors[i].temp, MIBLEsensors[i].hum); } } if (MIBLEsensors[i].feature.needsKey) { @@ -2334,20 +2280,20 @@ void MI32Show(bool json) } } if (MIBLEsensors[i].type==NLIGHT || MIBLEsensors[i].type==MJYD2S) { - WSContentSend_PD(HTTP_EVENTS, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].events); - if(MIBLEsensors[i].NMT>0) WSContentSend_PD(HTTP_NMT, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].NMT); + WSContentSend_PD(HTTP_EVENTS, _sensorName, MIBLEsensors[i].events); + if(MIBLEsensors[i].NMT>0) WSContentSend_PD(HTTP_NMT, _sensorName, MIBLEsensors[i].NMT); } if(MIBLEsensors[i].door != 255 && MIBLEsensors[i].type==MCCGQ02){ - WSContentSend_PD(HTTP_DOOR, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].door); + WSContentSend_PD(HTTP_DOOR, _sensorName, MIBLEsensors[i].door); } if (MIBLEsensors[i].lux!=0x00ffffff) { // this is the error code -> no valid value - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, _sensorName, MIBLEsensors[i].lux); } if(MIBLEsensors[i].bat!=0x00){ - WSContentSend_PD(HTTP_BATTERY, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); + WSContentSend_PD(HTTP_BATTERY, _sensorName, MIBLEsensors[i].bat); } if (MIBLEsensors[i].type==YLYK01){ - WSContentSend_PD(HTTP_LASTBUTTON, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].Btn); + WSContentSend_PD(HTTP_LASTBUTTON, _sensorName, MIBLEsensors[i].Btn); } } #endif //USE_MI_EXT_GUI diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c index cc7b25e5b..f706bcdba 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c @@ -18,7 +18,7 @@ static int MI32_accessory_identify(hap_acc_t *ha); static void MI32_bridge_thread_entry(void *p); extern uint32_t MI32numberOfDevices(); -extern const char *MI32getDeviceName(uint32_t slot); +extern char *MI32getDeviceName(uint32_t slot); extern uint32_t MI32getDeviceType(uint32_t slot); extern void MI32saveHAPhandles(uint32_t slot, uint32_t type, void* handle); extern void MI32passHapEvent(uint32_t event); @@ -48,6 +48,7 @@ static bool MIBridgeWasNeverConnected = true; #define SJWS01L 14 #define PVVX 15 #define YLKG08 16 +#define YLAI003 17 /*********************************************************************************************\ * Homekit @@ -139,7 +140,7 @@ static void MI32_bridge_thread_entry(void *p) /* Create and add the Accessory to the Bridge object*/ uint32_t _numDevices = MI32numberOfDevices(); for (uint32_t i = 0; i < _numDevices; i++) { - char *accessory_name = (char*)MI32getDeviceName(i); + char *accessory_name = MI32getDeviceName(i); char _serialNum[4] = {0}; snprintf(_serialNum,sizeof(_serialNum),"%u", i); From 08ef839cd1ce37b6f104dc549d06359ba8faebfb Mon Sep 17 00:00:00 2001 From: Christian Baars Date: Fri, 7 Oct 2022 17:06:50 +0200 Subject: [PATCH 02/14] do not expose unknown sensors to HK --- tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c index f706bcdba..0e1f7f1a3 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c +++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_homekit.c @@ -32,6 +32,7 @@ static bool MIBridgeWasNeverConnected = true; #define CONFIG_EXAMPLE_SETUP_ID "MI32" +#define UNKNOWN_MI 0 #define FLORA 1 #define MJ_HT_V1 2 #define LYWSD02 3 @@ -140,6 +141,7 @@ static void MI32_bridge_thread_entry(void *p) /* Create and add the Accessory to the Bridge object*/ uint32_t _numDevices = MI32numberOfDevices(); for (uint32_t i = 0; i < _numDevices; i++) { + if(MI32getDeviceType(i) == UNKNOWN_MI) continue; char *accessory_name = MI32getDeviceName(i); char _serialNum[4] = {0}; snprintf(_serialNum,sizeof(_serialNum),"%u", i); From 6cc52e0128563fa42d817b5a7749d12e67f4f45b Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 8 Oct 2022 09:44:32 +0200 Subject: [PATCH 03/14] LVGL Fix BMP format for `lv.screenshot()` --- .../xdrv_52_3_berry_lvgl.ino | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino index 56aa6e833..e6ec58e56 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_lvgl.ino @@ -514,15 +514,14 @@ extern "C" { // write BMP header static const uint8_t bmp_sign[] = { 0x42, 0x4d }; // BM = Windows f.write(bmp_sign, sizeof(bmp_sign)); - size_t bmp_size = bmp_width * bmp_height * LV_COLOR_DEPTH / 8 + 0x44; + size_t bmp_size = bmp_width * bmp_height * LV_COLOR_DEPTH / 8 + 0x42; f.write((uint8_t*)&bmp_size, sizeof(bmp_size)); uint32_t zero = 0; f.write((uint8_t*) &zero, sizeof(zero)); // reserved 4-bytes - uint32_t bmp_offset_to_pixels = 0x44; // TODO + uint32_t bmp_offset_to_pixels = 0x42; // TODO f.write((uint8_t*) &bmp_offset_to_pixels, sizeof(bmp_offset_to_pixels)); - // DIB Header BITMAPINFOHEADER - size_t bmp_dib_header_size = 52; // BITMAPV2INFOHEADER + size_t bmp_dib_header_size = 0x28; f.write((uint8_t*) &bmp_dib_header_size, sizeof(bmp_dib_header_size)); f.write((uint8_t*) &bmp_width, sizeof(bmp_width)); @@ -530,13 +529,15 @@ extern "C" { // rest of header // BITMAPV2INFOHEADER = 52 bytes header, 40 bytes sub-header - static const uint8_t bmp_dib_header[] = { + static const uint8_t bmp_dib_header1[] = { 0x01, 0x00, // planes 16, 0x00, // bits per pixel = 16 0x03, 0x00, 0x00, 0x00, // compression = BI_BITFIELDS uncrompressed - 0x00, 0x00, 0x00, 0x00, // Image size, 0 is valid for BI_RGB (uncompressed) TODO - 0x00, 0x00, 0x00, 0x00, // X pixels per meter - 0x00, 0x00, 0x00, 0x00, // Y pixels per meter + }; + + static const uint8_t bmp_dib_header2[] = { + 0xC4, 0xE0, 0x00, 0x00, // X pixels per meter + 0xC4, 0xE0, 0x00, 0x00, // Y pixels per meter 0x00, 0x00, 0x00, 0x00, // Colors in table 0x00, 0x00, 0x00, 0x00, // Important color count @@ -544,10 +545,10 @@ extern "C" { 0x00, 0xF8, 0x00, 0x00, // Red channel mask 0xE0, 0x07, 0x00, 0x00, // Green channel mask 0x1F, 0x00, 0x00, 0x00, // Blue channel mask - - 0x00, 0x00, // Padding to align on 4 bytes boundary }; - f.write(bmp_dib_header, sizeof(bmp_dib_header)); + f.write(bmp_dib_header1, sizeof(bmp_dib_header1)); + f.write((uint8_t*)&bmp_size, sizeof(bmp_size)); + f.write(bmp_dib_header2, sizeof(bmp_dib_header2)); // now we can write the pixels array // redraw screen From d71c06d03d2c5cbd39a7f71c66ec8468b9d8d175 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 8 Oct 2022 14:20:52 +0200 Subject: [PATCH 04/14] LVGL/HASPmota add tiny "pixel perfect" fonts for small screens --- CHANGELOG.md | 1 + .../Berkelium (GEOS)/Berkelium1541.ttf | Bin 0 -> 30292 bytes .../Berkelium (GEOS)/Berkelium64.ttf | Bin 0 -> 34316 bytes .../Berkelium (GEOS)/FreeLicense.txt | 20 ++++++++++++++++++ .../fonts/pixel_perfect/Berkelium64.lvfont | Bin 0 -> 952 bytes .../pixel_perfect/Daniel Linssen/m3x6.ttf | Bin 0 -> 10044 bytes .../pixel_perfect/Daniel Linssen/m5x7.ttf | Bin 0 -> 34300 bytes .../PrintChar (Apple II Font)/FreeLicense.txt | 20 ++++++++++++++++++ .../PrintChar (Apple II Font)/PrintChar21.ttf | Bin 0 -> 501992 bytes .../fonts/pixel_perfect/PrintChar21.lvfont | Bin 0 -> 948 bytes .../Shaston (GSOS)/FreeLicense.txt | 20 ++++++++++++++++++ .../Shaston (GSOS)/Shaston320.ttf | Bin 0 -> 50732 bytes .../fonts/pixel_perfect/Shaston320.lvfont | Bin 0 -> 1076 bytes .../fonts/pixel_perfect/m3x6.lvfont | Bin 0 -> 824 bytes .../fonts/pixel_perfect/m5x7.lvfont | Bin 0 -> 952 bytes .../fonts/pixel_perfect/pages.jsonl | 15 +++++++++++++ 16 files changed, 76 insertions(+) create mode 100755 tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/Berkelium1541.ttf create mode 100755 tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/Berkelium64.ttf create mode 100755 tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium64.lvfont create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/Daniel Linssen/m3x6.ttf create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/Daniel Linssen/m5x7.ttf create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/PrintChar21.ttf create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar21.lvfont create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/Shaston320.ttf create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/Shaston320.lvfont create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/m3x6.lvfont create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/m5x7.lvfont create mode 100644 tasmota/lvgl_berry/fonts/pixel_perfect/pages.jsonl diff --git a/CHANGELOG.md b/CHANGELOG.md index 025864dbf..08bab095f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Support for Shelly Plus 2PM using template ``{"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}`` - Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints - Support for QMC5883L magnetic induction sensor by Helge Scheunemann (#16714) +- LVGL/HASPmota add tiny "pixel perfect" fonts for small screens ### Changed - ESP32 LVGL library from v8.3.0 to v8.3.2 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/Berkelium1541.ttf b/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/Berkelium1541.ttf new file mode 100755 index 0000000000000000000000000000000000000000..120ddbdda8203e2c47282b2db68f8db6272636d9 GIT binary patch literal 30292 zcmeHw4U}Egb>6-+Pd@_^2rPjB8J>PX{K(Qs2#^W3L4Yhk*fL-&$Jj<_2Be^$i8MlT ziyPX~l%#H}Bu?tYNwfU=Rcn6o-`seuS#vpB z@87m->)69r9J<+T=6tk`Jhbyu5B}!sXP|4&Y;)p)_Us$~fq{`#(~n67lX|+%?X=fHn4?K zn-y8xi2a`&#QHI_FK)K(?b&w6`rWXAbzh(57{Fzu8_1eNxI-UG_0t@}%@GViEm=`Z zTeh$8l6|^Q8t@}sw&|MpQxwSvUOhDAk%e^0Gp})9XroV9lBTXxF4{PzV9s{PR~vDl zZQ!|y!#&uey$2u0QNA6)*tnj=m;949Yx1Y>*jJUbb?RB}tMNT;h%VBLSL%;8VXyc~ zM(V{#t$dgCgIz>+6pgQKS6xqqo8xH%^7VS+aKTj3PV!}cA2DZJKmNEE-^z}{I)(gf z|90!z&gqY=iD5cBq^~n3B%gR$pj+V^_iUSzSG1=uOFSm8ie9*Aw?3PtEb`~|;N#3Z zfra!rp0t#w*onH*G4;(_@<3be$tUFpzU*V2edJG>*_ZA8ZNfp!7>Y88G9RDJq4TZN zY(~A=ZbS~8XMfHnnyZ`j%^l6%&DQ2%^L@<^4_r6!<$+%x`0c@;AAG*Myt}%4efK@x zTe?pzK7Vm{@sh>MmkcbKwdC9-7cRMY$yG}>F1dfn=%ru2^eg{s#_O{tCcwFCPd2NY zo0{93yPEsK@zdh?!oXJseoGwZb%(p}?%q&wybK&?E;+m6ICAL=;ApSg#Kgq!PWJ6Aw>(c;Z77?>qVVlXFj=`R2r%Yu~*1_*ajA`S|n4f93cu9lz_9ufKBq zl~-PQ`IUiV6UV-F>>J1a@YwGhd*Rp@k3IFZO<%kHj0H0 z@^!cZ_XAI$ya<=fLwOeETZkxlyt4^qC(4(wDlS67{fwu4y`BmBnNMS_U5IiI%5k&V z8&MubdERWOgR%|<_d`dq34rV~Am@zN%+4G}8Ao{r1^06>Zq7lJ&!N0%Hun~kohUDv zowW=FJkB~|cJ}2ckE4KQ-XfIyQP6%4_?-jVb6z$(7uV;a{am!4`z^C~+<a#;Krf5il%z+3cNLP@Y5iBeRRa|6<6$WF88xFL?_Y1UqCs6@`l;cWhjrLfOgqovr8fGQee3Zm@j+I zZ24Lg)R%+L<=}Az>MNc%yAt@W1lB8o^{PcEV<@}^pB0-?K8u3uccET659Kpvs}`a> zYc{+V1+s?UFk3x>@}k+AjVMo>U5znU??m~!*;?>fi}BYCqdboC8n$!yp}cH%9e7-K z2nB8H(6$ca)`8!sQU*i|hA3WA;9b zd*7odFPYuA4rL3_djK1?5?@yKX@N?Oi9#?%s*=s@Xj^qI|*Z!}Cx!qd=z*qyOIdDEFg4#z%%xUNYMP zSzAE21-w2A86QRc-CN8)2K_%ah5|kxd)e&1C(J$$nvXw*@+Fiv%sv5LpTPJ}g6}7v zkOgr1&Vdq1C8$xkevJa?XLDC#K2@et>3O>O%YPCa>_Y$?ElEoc? z#?$iZX;JZNopnemEOYG~TVNLe#RZb&{qmRYU9J@*DRW&QN_?d*+H*vr2rhv}wgxtj zGaKR_L-c5K`Dg*3BN0<)0v(Ev$=WsM9d|G%$M7jBC+7sRsd+e(k(QdH`NI~-6ONN} zoF`9uVJG^GvAPskmU0}&7psJRg)4bhh3)DKKeTjCfzRMjQ{{D1x3$j}qZUqw*o8G$ z0Clge0z*>5x_vF|K^x{UuGrhod*>YEG0HW_NR$uZAc=2UPGOMp`AVqnL!p`oE#Mp8TOlSd<#(ng;5d;OGoKhUMbTrvBR7GLD}KHq^3 zJwQDfxn>1>)Zd}OD(YUZv<+BcYm}mLivgD!WPB&d5H)ADG7i=-Frd=I8FA!&PpmvOlKv`yFK}8P& z6(q@LsALi5hq89p915qxq0)(*T6)h+eF#K9nRZ?1Pwaz=3+DDfl~Km~;`!WPDH7N- zu?}|eRnjrIzv?;H9|4XdY{RuOJSqCg`#~57J1vZpowfFsISE=|@K0Jqh_F%!G24B8 zOyBr!+lJ0(mnf+L=wxfs>#pvJmV#M!$Eq08LN}L7YeakN4dAW+W?=8j9F;t(xjCzEe-+yI%u!jPpEF0Kr^L4-Jv?rD z^Ayqc#r@RL1GJDI@$V6oYb^OPOEDU0uWBxlck8W!6RmEE$Z51QFe0Bg#yaOw!$~=m zeBFNRbs2%1+TfHD)@^fMo1Y4IjC>2U&KV=pZv}OUC#)Z`-zoQX8dcU2*FE?Hy*xJnLWz|Z(ZJ7Nf*?U{%mg2G4e+Xm9p zZm6gAi;s#=Wmr=2dt6C%X^`n5F?>E1I8`_3@zPH$W7Fn%+ z;#m+iM9cY2ZbO633349TQu?umfqy>J;Ip*~Jx3*?qIKp(p6hdekr5&N+mR8EZWY(j zKU*F>c{M#*(4~Fa3`P4R4(NHs1Nixx)wjRSIf!ogJm)NC2)UP7N#yNWD)YQJ)U>^N zu}3Qq>M}n(H)Kp7YInBc<5A<*AQgUy1ts-NUf$|jI#rHPe(Z~FQe}VZFK7%cp%-lh zPqcc`2O+`fc*m>sm+om<_m+RwK1;u22MVd`A%m)?Ht&T-5{H&yJG98rCT&}!L6 zjG_qY61wJ2PrQ^E%VYTs4OW65&f8JFT7?YO4jaM#+^<#QCu1Ej;npXNBXp$OXep}%czUbILbBg zxPwOcw@A3w9~c{9TDeV-36}DcLyByNB=|v9H`(>ynRVac~fK z`IoJtZl6xe_TJX6tHkSgQlEnA+mxGnW$iwnUT&pl>g(sHTHoHiO2jmI_G;{!Aa-Qw z(?tM{-F|5^un}J0-}d6ryLHpqzSYHX6(0~O3V*yVBOy6s9cwXuO9MmjT`)iE;_aCk z(9=Od-p4$BTQT80a~7Y5V*zi%$#|RYm1*f79gjh z;3q6b&RP*UR*~R!=Aqu+@V%svGE20#=gXe&bZfq%$kj=^Ktv@y-(pXip4{C-0Q&&TKRo{MoRsT0P|%1l51k<=N2;J8GxSwCVh)1+!$GWom9X= zRBT87h&#;#MY-FK)Z)rVDyx7( z-#&>F1VEWPlqz?&*m9lD^JDCyG+U`*?v4YS+R3~1n`C5kQkN1L7#CS!U5T)KX2Lb) zG-Vf=;Z@iIoc)vf^~=URS|@6mX+Q0yux9ki_WVt)sBw7`lPj2OR8}O7((@Zf(Ps&a zP7A2tBV`ISvpH}IEdK6#?8BW`8xO!F-NFK75uU*XdeT-I6GTlt@+8QeG`VGe#zfk% z@NfN;^Q^q>lDk96qQy##;1W8grB3B1jP0=yGa0erhifdqJFTB@@VoZvofOi_7C8?{ z$u^XX!qh5#ntOR@DaksY!8VZWSwPV*4D8Q&7hKg&eT6$X6zi8+T#wGZLLG0^WAZE$ z`t+V_;r1h6SX6j3*W+DswjM3B>NMpP{!`4PT8>V^HGcq-_S5DK;_IC~u0zIx_f9=) zDA{d_T|>MNQ#3=DB-i_{Hg8O6%U;QD#VKtmo2JAPeQwJYJvjn$q#?Cbgpr?cwb?mr zihj*d&0{~3YjSj8OY<#HJ1dw=cN8T*;afyWX0cJFX#QrYNCeb8G*QWIrt3ud4*b1)L&_= zdyMX!j-0Sa`yMKZz#%?)g@UJo@gxFy5%)R^sz!gtL935jGH6pHvXm9*G4{DH>QQl> z5=F@q4%&N9pX!M{A&|9ueq|FLX-_K6Lb$U%C2NaXJ$NVLV z4nOo9%im%1lSwTnt}_leUUtZg+@lG5WGB=;zHu9;JU$1ne&_i_ zXx|0&vEoQN7R?jdBJRC4?|l8rOj@*P&m3>bJ25INkbjS4=bf_$cNhT)9S&0t=<~ny zN|eq`KFs}xbMGIOQoOzH)pfBGaGXLH*QQrmubpzv6e)R*%KcA$j!KV~s9}sLo5&6= z584Cgs3~})eOt|g2l8$~#>ni5TgxM3OrwhB+gNgHMZM=Yr%wxnr^-1Bw)3^3S3l{I zbHV3O#m!}>zx|z9W~-k04oTvYb1o$(9^SjInA@?kVXWo?+G8FjmAJII(cj65H+n^* zS?v7CR^!XuXCyi2^mBZ7%k`>%tt2iYPcIV@xL3AL{lnIQvG_n5>ityFMgA!CxlX@@ z?94~Sc8MXhbP3ecW#>%Hbu8(jvwTp=_A^kw?Dh&G0`g1MMTm@Wsdah$Z~X|XYHN? z7=M<*vqSDxFTnTHHuO&E>vk^|YWcgx7*XUd9MU0V75S|fA=R~uc?rCV^^BH8Supvt zhx}Hn{dS2_BK~Do9RV))S*-KPD`h%L#(H=OqdBI&r&aU@4SG@^jOw6Z9P&Xu&)G;G z5u>@n7aYOAca*OgqC*GeRruO-cJEwFPQ{|6gS_;NaHvhzq}M1xo}r~QcYrgIrkv*x zpVeuRBU7V-O&Img9ymfq?xNZiFSwrCvScrm9bUDlTx2RWklNzjz%Eka0(I96Uc zGVunA(4GUx3nltJPvY&8N$>D+toSO5^`=_Vj0#N5 z@cH)SfU>E-Z-YH4|1M1Oak}=d%vs>V%ELT3)m};n@(C9rxgZiJFcq39d4#N_2=8(> zIG5~?8uecysoXh@%eCb{~UNz$};gtqPZ3b{XLXud&;ETTM^b`72${X~Ve zgSL>(xQ@nrN@<$s--&mRpf9j+=FnHY@9euLTHB`GJMwR6_TMSKo>RC^`TO4aEgDzMK$$Cr$5HEPt|*8h*W7)gr~_iOxqfBW6+WXj;+y*c z{tj1IHnWFoOz%>1%p8t?t9LQ~c>3{1E_WKfS5tiDs^t7nWIybs-@YoI#XFgtO?5xN z#Vq}br84j9SV~)I7wo?s7vF#?zd#aqKeAH(_MG=)T?^W>wrjr(3_bH&_RN#LGNt=0 z+NY#R|M^JHKKFZmGAC1Gw6}A^#{?#D$ZVLj-%kGMOg*0hpRW^;)2CxbWxjEOaeX>Z z!?)N(m~#fay?M%gYS^X!%tE7pGwdeYK$^?RwJyC>&lY0WUZy9HMqWXWI3&NfZHJtP z`F9qGE(&>NX(NCwG4naHr7x$bz>wbW;g@JzDJd;`QexEPpWmZuULv|7pL0`D-}Yx7 zfo%&f{Vj%?qvJ*Ybbo&dF&bH|jceB+d{(%Jk8qES0UEyVK^i^ZV1A(7k~@>S^{o3X zxlj+xrpzDYNG&wO$Z0kk2D{+vGPtLi{60oV(FqvYo8Og_3vEU;{81e%uKGcPAEC)? zh54iv8DqUY-%O2pR(7cQeF9P@nRGTyfo~}~mv%Ne$Jd{6Svdo~4WvGM%E~EyV8yqI zm_7q~#8L4XHK4x!>3n6cTm!{0L3JY+GqTks>#pe+^-{CP&H>{kE1FH$-pNtBL$ zkIxn%{<479Vx4V$UPK&=Z#lV(mm;p{K<|f?>Ld`Yl91=9KmNZ-=DCA=CFKszX=<2S zN;;8*?NZ;||Fy_l4cscB9sE;%KVyNPj6oxP!w=w`Gn6z!klxK)TXIyg;q?Dx!(CyIH(i7&nv`3eIDSv z%(cMd#pef~zWK94dIU23X-1Dn*^`!U-<|SS>|A)d1#+SJxoM>|{yz?u!ZO#MtZ(1xzV3B(Ma^Tp+QDPbS%nM^;*Q-3tr)aJX1~Q0qF=ys9D^q{z*Q4me-ShqV4y9kAvpoB2REsJXh|w zJZ&e5vnc^sw?uC6zfm2(k;uNx1*j8gkN)Y)%oLeB#hunIQRcfNX_nvhICo|&*F0=M zs<1#Rc7q(5rK6 zTtlzU=j~?OYooT+#_>5~U3E9GAG?E_cp z#dhj4nIie#2|JB|rnX6}AS`eI+}PJ^w*zQD02~kZ z(LF3Xj-iLX*#!&l>*KQu-lV7Y0m)dg)T*2Jj&2=@tP-LPl(_=Y`u9~$khSvlOjeEazL*!8PcJ&4u^*}8JygDZEBj$g5U zbnnBXJ9q5g)m?qf+SPZCj^J|rj`4jT*t}!g)_vE5Z}hYK`tF+H)vHUBNbVioyKl#y z-QCqIhf9Z8Z5eKBU$1K_fIjG$Ki|KOiyiv6hwek54m=V;BsIy3pFS&Fs>qXw}PpMkf3X5oZ0 zg#V%POsp+)?JVq2=3xhMF4p7uc#ru!JULs4|HI@${MP0otk4(ZcQ?EE>lI7zzjZ9L zOYwh8E=MlB!mhNdY=ylG^L3Rn(HgrNne7_8)~>U4_HJab@3I^4-xa;r-e))3O~^Vo z+bwo0a_jqTqupk=+a0zEdGG`FL1dK=AzR;V_t=N+Ui*k`v5(q!+sEua`?!6=K56$O zlRRaA(;m0KWd96n<8^X*k80CvHx!W!~UxM4SS*)v}5)S z`ziao_Dwrs|I>cf{=WU1ecAp2a>zF0Ui8)7Z|JGize{Ekx z=Kmx6A^Z1s)czf^*YDdO*bmtEAmcoYytEV9=SgIy??n#Ui(IrH8R-#ZwBNIX_Ghr} z{8{_7J!;R|&)E0j|8#rI{=B_re`x>IezWN`GwgTlcbl2bEPLAiA^u0t|75>x|JnXa zGu!@lGi1MI|FJovIn%yoFWYb1@n(*_(#*BbH)l0xH}kLy_{YsT&AH7x>=*5y*q565 z_Kf|4{mW*7{RR6~`^(LF&H2~`{JrJ^d!e}y`-ERg$Fv#hz)eyO>vS>9aUT+v+FT!p>T^Y$;AcQq@U zRn2g-dgk^|jcp&@eb(6M-W_{JwvFx{AKg1TGH~1N13SKF@YdZA4UX=9XvWSxyC2#& zYya*Y!)va-&g+|RihBKw@f|xyMrV9**XToA*@pZ%9QEp`*9>iaaL10};WfkSqUGAT z`*)8Zt!~=`X%Fn2`@Q@3Q1ByY8Xbu-8@yg~b<}I4z9woRSu=d~>Y>qt+jef<1wP($ z^)0g>+`Dz#IC6I9*8O|;sCD&fAHRByqg%bk@7D}R9jLFl`C5&?=4Q2TxNcbEQA-=t gYuJxkxKIlhYT??jKE|(){`JwnzVwSf#$ES+0XE3_LI3~& literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/Berkelium64.ttf b/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/Berkelium64.ttf new file mode 100755 index 0000000000000000000000000000000000000000..a99b25bd54c69254fa198516256dc2d2e15051b9 GIT binary patch literal 34316 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 MuPyE354v0aH=c+B-v9sr literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt b/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt new file mode 100755 index 000000000..e48a09bba --- /dev/null +++ b/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt @@ -0,0 +1,20 @@ +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium64.lvfont b/tasmota/lvgl_berry/fonts/pixel_perfect/Berkelium64.lvfont new file mode 100644 index 0000000000000000000000000000000000000000..073d1e37ee2c630fd88df9b069fa85816f266ed6 GIT binary patch literal 952 zcmX9+ZD>q>=;|n3e!f^AyQr1YVA5SfrzLej@e(b9|dctKNP8+H@lbTJ@=^=(*ZYz-f<{4fd)H1DyHsEaI_0DjT;yrt`>H+> z9gln&C_@ESU<1Cb0{)hr?j6yt&0M043?CcniFxAD8YhBxrX9OG@$4Be2;-SJH}k_JYvTT2e76<<93cyEW=bLHPLbHq|S zQXdFJ760L1eC<8M{?UqGUe}hi;^R(Ad@lqaTpUn*!Z%}>@p9M;<|hn%-{4XHlD7@m z99lJ%gGr&2X^Tc)Yrmw|@`TL|KNXS*i$;(130YbFMNWL14g>-^#6723$Q??_pBPA( z@!-pr@5EZeD*JVz<;ygOEu=A@|6kwy(-9$4#cutjg+4tR6rpUi!q~5PbSx04GUKi5 zKM)sh@iF5qCx_I6{t9FDql3>Z|Id!iHTi2=vDMWj)wsH%hF*~uvieFwI=VY-_k{Af z19B{0d1?Fb^s5g$f*Ik??TGNv>9FVY*8130n`^~E@!&CY$nGgtQjATCPEEw3!Q`Y# z%WsPI(qaJ_xoOyw>93ESSDcA7J9bZ_&ZM|D)tZn2=x~z8&cZVpg0@3x6-;%@{MeO? e+%t;L`ew=}wSQq8s#FKdbkMY6moEC|3|;_8oDv-X literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Daniel Linssen/m3x6.ttf b/tasmota/lvgl_berry/fonts/pixel_perfect/Daniel Linssen/m3x6.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e0a9664013a09f05ba7bbd450d1a4722684d2a87 GIT binary patch literal 10044 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 literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Daniel Linssen/m5x7.ttf b/tasmota/lvgl_berry/fonts/pixel_perfect/Daniel Linssen/m5x7.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2ed774d4dd99ba547641d9f8e3a12baf324324e1 GIT binary patch literal 34300 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 Nw_L{a_gd>7|6lg}@S6Yt literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt b/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt new file mode 100644 index 000000000..e48a09bba --- /dev/null +++ b/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt @@ -0,0 +1,20 @@ +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/PrintChar21.ttf b/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar (Apple II Font)/PrintChar21.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7204e971878966081d007e0fbf644e1d99e28086 GIT binary patch literal 501992 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 z zTI#HM0r-(BuB9DXMtr+*#n&v$GyHo_vmWMF-Tsn0R78`M)N-O9ucarEIcR>Z`v>*C zHDgeuzWymGu;$cR8|=NXdLF65!$`e;UTJ#WSkPIn-l9(IDKqQqSruHrBG0*}!j)Fv zRgrEeNj}gS^%b{po}Cp!(E6zaF`u+Z2hx6*8hzCLnD@E)t%~3w>&QybKvzuRuTjh^ zd)4cZBRxyY7Y)c6nR)cRES~9K%_78zUJ!jSe6AE{C6Hv9~2jx%G3zk z)j2;y0dK2>u0?XYujuw%S~(MeaLGu{IfzvsMFUV(pAt_z)-f*c`aP+TYQ0sh=4hRy zYX2cV8cGD~pW_)L8*ipGWBcM_bmut(ltE7AlvMOQ zy<WVPVcSQ2-+{)8ZiVE;F%T|4Qgq%D6@xHX&kv9%TsM0pV#6q^^jCUXlQussL zj$XTGlj*8gjd$(vt=}uGz1Y%<2V)2K@=+_KJ6`l%zx%ySm+$i-87tIQm9=t_w$eP3 z|Eqi>j_n27nj(;v=F^wJ7FRyOqD2=%`*Dc=C~w1^*%Tb|3r8AsQh~OQ24q&aJ27p#l8BJU^c`{2ihnjL9`U7^ zb36d;)Jpn%K6OJ)@Ha|n1&}WzGD_yYQ?2}AJYkvp?}&9DISSLm!DZw6?D>oYGeUt5 zu~{uk>xe__4@&g4^((JPWn9ME{e?p4nXdN>RATl?JZ}w`AwSk-PLGXREjhllu}V*x zs4YX%N_@ovwO8)irlV-dNw1bfy(^rN2INq_&>#{n<&g_UY?4#y$=P*#&!A?%sU(Ze z;&dRE>mW8d=DNC*SIN*$fjnD8vUHe$Pl zPxQ?hq{r*VG~d-@4;lSB){gD5{zK$`oUwlUjlr#Qb{u)fr5J#Uk(!ulyMVUvLOn*i zSU5b9Gy0*JWY2p&Ve8v_zKVJ^^hma;(oTAtU&py@z0q89kaPVS=alJa1GFAQVyy|>;6Xe%B|rB-)S%qno&XImva$<_j5Y%BL@LL^y2BTwXap0m*g zT7f41Wt|;%-`HRKj;4bKQrgaS#C79Ga5;F{@{5?Ss~c*reZ7N7_dZG2n3^`}GR-ZF zQV#{oht{$+ge1#oJu@pvL@2yQPs9mQ=1<;waK*JLcMP7pJMJgtGkeErW}m{7oK#C! zp{>}-o?0D9NPa{#=>p3Ot<^ue+*;QwmF9CL)n&ZD z*4C~l)$Tp+OFM7mLJ6QMo7HafRvI*W@|nHuc%Dgo86RX*OT84xLHgiWn?c6QjFdIY zsh-Yj;Y>X2{l?m|!6S$`@5H($T842+|8e?7eTOAgy4+C1wM+w7lC^#z8tpx@gMcL^ z*VLsXuD?_wOZ<(i@$wU6YJYKk%S_FP{-eI)`Iu96YJK1v8p~a0Sv8_`(fzgwO3W+r8qU_qJp}x>bBd91X)-ot^)$7MRrp5-*+*>)BFf?# zU(uteHz+IK-P&+^`pU-R`aTJXKI=;D_dU0ee6a-2`P>nzP^%zCTZwApiQCj@ z)wT)0IPA?Dm5#{xoPXN}#0@-1U;pS!DaUri{dS;PJTCJP%18g3u@<-y&GDC5qV2aj zp`LPBR($PO+^c`t*C&1FKA5kThIJ9Y@U=WiIenEeAeL0E`a@$8TNp4Iy>Ut^mXb0$ z*Ky@J9*tpxcH&9vBYpIBYc@TWSKBDwl!JDNAEHmWL@(Crj}-F@%8}8%P;#5bl8cm( z9Q|e{#x*gNyXn_;u~~rz&2pR;Wj===w1iNFj=E;4O2lLRf;uaYx}&5qF%~KpS&MJ^ z9BbunSC$n|Ri73S#X}xR047YYm8bVPJTrL3CX&zEpk^%!3z>50ldP=Dz5xHy=G&vE zFX)_uB}kWTC_0Oqu0e5d3oh;T>!*!GkpXg9=CyQk-gj($Xc2u!J5v&NSb6f%@A^fA zYWsOh|JVMi{Zwt)Yxsb8QFdXHHq$s+jM^53GWeEm_cKct;&oj^@v1_`0IXX+)&%9j zePqHp<8HK+)mP_Wn%s`8ruX?G7=RzCmSZ_U9;EIa$U6r056$d=Mg3whxUX^F*H%6a z$8d(e;y0L3B+vzYT9{E#`NU3ViHmo?RB52r@^?R-o-;A2^zdXh+8^fHkG~K7y{A8T z`a=Y%KcvmcKhjGkrkwU;KCgMKt$9w}iYw(*TH?=?i*1qT8Y#ys{tjPLKJ1cmLGB*^ z_in0uY2`M(j>!=hXd#UIXEq_+?Tu??)NgB<-jSU9D?YepeeyiV?lT5y+hM8ot%FWBH?(ixJCcru(v3P7%=Rek0dZl-?5$rB%QjW@pkJ`KNDhHX+K6SJ=yzQpW8l%wsP*2{2na)JxU?j{?y0Q!j$Bc zCOX)AqDR{dWKepqaU}^+U+G`}l-3}%T7~Iq5z2Qd=@QLcTKEMep>>a29n`qcy^56XpefzPqdvKY_c3Qx%6upxgpOqgPd$dIg-jFfAnwq1MSCa zf5C*MDIwPTx{kH`?%j7DbKI1rB%n~F_ee_R=Tw!Ou_OJa_C^jdK#kf--UaXI^;kCL zK>KQoTB7?{B@?Llc)5ozX_VfW*cfg(=da|WRFsC8Rhml6W3)1kK``S3-?#HB3dYqe z$se^ARZ!;nt||pF(?o9lPo;iv)XN9VN_B<={E^cay8JjwQ~YV-qoEi5?;I_6kf*wDmK-Y;!Bgng3d=80~Bk3L+=Io9spX*>im9tIj(J_>v_GGEu_cy8Rw9~f5p$1 z9s8<0?MwL>Eu>fHm%Yc7>-ui#9lknaDv!}_+$;qp5kDPs_EJ2f9Fjfdge`orqu5zx z{CV5&VIO7x&iISj4^d_0q_)voI%7|AJX~>AEBHhK|JKh#qjy$J1$!{!g+-A^_YOQ$ zoLRq<6z#VwNwN3yz^tq2vTbhl$Q;5w)${tG6n(a>S|jT{zCyjIocF@`E+{?II!kIv z&xj0f<@t4`DA8tSCu(!&*zUHwx+qybV>j&sWXxkM99{EpPc#bmtxt;V%_sL@g;mQ3frud2!g!#dhX%sFT5itL$|;-j=%>acXowQ0sI12nf0 z4f=b$cHRo$sG<{!48TLxRn`s>V57N>ZwXo3zS45`vPGv>h=$dV8Ck9^{p679y6O2Bjf zD9c>}@TeZFuldB*Xw4i&2by?~a(Y<#4`o9;i`}Ug{%IdZXlnk35|x3qc+OTSZ1h$u zp6Lpyl!D_aUQ43W?=u!{-?+XP38b@Y<~{^^M*Zm^T+L%V4wf8u!y2NLx6Q!SCBXfjV9eBkOim~<=tqlMf*3Z~M_2IYH zmx%F9Q2>lT zwl%Q)Jl792C2uq|z2=fzfAtk1a9J$LD`9lAfucd8#N~uOhh~MXN~Zy&l4r4O)uOimvraqiBQ$-n4#l> zJ+`FfZH#~VMN-civF}zlqP_HHrkOc`Vqz$1ls?WS$>C$VMp+;I7o$E)!iqdQ$`c#x ziaQXjAMx1ou{bXI4xP`^{+?cc&~X4U7k=;h=2;{Pzak8&B4JXBZEXyjtLF3~FY(E^ zgqX92{;}rtj*E=WX8fCU;t_2X!#KX#J-4&oIEY0b%ReZSvvL{-n=_V3FRgyA{v}%! z8P^}V88K1 zTG?-Fl|I=U3C_yrSiySwulA2Fc8&$wz3Y5p!?TnoVn#DZ`4mzbql$%eL_PYO>R#_p z@Oj_fKb}#?X@~NwyuB{{#Wgw7S5u>6?v*)>P2odK)xFKkfz$WQ4n5YC#b6K30F9+bwOOBmjf~(&zzi74+ARNy z=@YYe7t_VFYGF!3Z0lKfPx9O5Sen0GSp%Pyecln>7^5+9_dB5|>%!8sBxF1MuQRRt zxVbxz9@!EE7FEauR7kb=?0StfMW?n2dl+ZI@u)llp+108xpjW{e)ttHVMh#a>jUL_ zeOH6z7T(~-`JqO66W?IH+J(oCV2}8gxgA=Y=dRhi?OOZytSvl*g!2*O(AQ#Y+5O++ zA*tVfN2n^zQZ+uyf{-6a@qzY7DMmu)a1Qt5dG-urSbB%nY*3l;VtSU=;5x};+18gt z+meC|{#gd65MN*W2$n!9OR8>aAAUC@uWT{%kpWUpNtf2Bj)HguCe@b8tCiJnPu$#+S(2$eQW};drlInRX^FefcQj~}H&zv`a;;s6tF#22J{`ez z&a|4WiJ-5@y0>x?{UkZ<0y*0XO1F|)1Flu8Z=v+tZ(a6BsFgyB6Ax*LG)gEW*gEW4 z@jv5X8B{9i)!z zhJ2>;nijJr;E!~z9eC}J{zL6L)oqN*2@!MMc@N+n|l4Q50wom0z+F@DAUfJ~4D5V6OwYxPvWgsO|bqo>R zQ>MK0=(Go|Dvi`8cwV$vTNK0>XW`G|W1i4kH8>w86-f>HL+Ol{Zle$O0a@0;%Wjg=msIsRV99g^|hsqN5t^?`ouB&(3c;%plX+`h_ zH`Ny3BHnx)oxjhv6A$ms;4@A4XT)hC_)+-qi}8O~hm+j;P@rWpLQ zcWb0;`$GE>m18BG*Zff;ONC>{Nf~z{-)o;JN_3_M)((z)N*)_#7sIselpbFS7T{&B z&+naIdOgXN{!_BLWjo$fZrQH#R}0gh*e0E7G30HZe%udk1P~2yss+YUmnbg|k?pdM z^@=%Jr}#qiHu5D6{@U8T-X{$n$ulu1NZ}gBKxv;P4I?6*h1YHO zA@Y!)JbJg}g_)6#R)Kc$O{`Lc7b)>a`o&-6VI5*$ojn@nm2ycPwHjZ_W%7le=3(c) zFVtqO(x*H_O*yqT-W9Fcv7~#&a-!AQET1e;1ZHh}yyT28GIiy4iSmVxl3>@anv-=L zK4VF1yfj0o*MbT>*xLB7bg@1|6FJ3*=rT9I)bZ+EY5{{m5Ea=%f+5~)NIKO@<)v+F zmJ3E4>06OvuX;(7NI+TZZA4n~HLfC$`Tkq$s01~UZ)IGIXj)lJ17kP%FtpCR3-ZwK zx|_yyL7O_=J@3R1yp4I@2W9HwM#6<>CZMYp%ep-W+N%>PICv>7z(k1k1FP)hCTcpro$v0Ri1W&0x!cK(R2Nt4>>%%Y5)*_1| z=y*&$<%l1>&pB&(=FGqSQ4Z6qcM+}TCP&CpcUdznR&CxW$wG&{U1IU@oQSJvcyAx+ z*GAQ^*QS4RhkVz#t9TsC#M&v3K654C)t}Nn^C-cr#ch0}Uv*5Vn3gqO=wHpr>$yzz zv|=AT+H^pYHsop!NC;BJX(*UT-X?csNwMWL3^7^&%hKfb;5kozG% z4Kla#tS8<~r|EEvzyb^KG-dEqft8HifS#2nN#I%==+|$q1 zOWMbH2TCG|@MiCb>sN$Zw*KJq1ipL&oXAJ9rdCCY@)Z4TEtR03O94+f2XF5E zoS7j8)uYYX4qlV^o4R*m@84(!kuhVU1EWsy(z8Iiq8CprLS$iyi_cvm81htty+SiPSnbNT->8Q_T8;ho=WH?9Z=8W7a z+4RBY!_Fnq61OKl_Rp2C$7HN$33?WO94U}*kJ6IYjp@=Km~;-6(u>ny_x^{ykL392 zJ4u)K<5B01O&c#~OatwyQ}rsssG)wW^)z;8xt8o0EPWs8DMo93ztNghO%WEvIrk&l z61C6rar&_a_Qm#d{5@RjkA5m&ja@p{MSl9I$z`oc z!zgK5qv$4wCAy9WdA{1yfz}|biBGZKeRqsOvu46__3yXDpNs8KhwbAX@#lHF>bfLs z)bZ0#XJ5(2wHc2!HuOjwz&C!^mQHV__Vzcl@1qYo()T{mald8sk58VQNXHz7KT4cO zqGwK-d(nUQxr6&R=7fE1q`H1;zEq)^?(xzlIG1g(6C>wqE95)x(qAOCF}7AKrK7L> z>FnRQ#*Ht}z4dJ$$MbOYlMAv%c-F6i_@o#6V%mNztulzSR)6vi*zR_uU$9i|y8Wlu z94YDFjC~l47xP3*=TF7;>|-tnb~c@H6MdUM{R6J3#|YVW#C9yi**@g|NKmU@pS`!u z*ifZN>qloh6%C|{CrWm{cSIKZ3^-4_o7r7`gLlN4%OeCb9gdQ|`u=0kC(dhuU=*ts zMV9F*OYhQmya;;;Rm5Z-=?8eXgE7DKS>A({)$CgL;(fFvyr*6e8pC;3&B1Za`3X{7cpN~H`HAF9=j_@SBQr;=`t-l=;U3= zM-IDrx?;O8GV>k6ytkvTF>&JheKIko?q>y1*lZR^QG0QtNu9(qDc5G4C`v{i41j ztHQG5kFjUlJadSBV~J>VUFV39wST;dt(8+aNfM|BX9@gVj$T9x z*EP(pB)rERSh5st`YkDC?NsL{CrK8rlJGc3URJ`S4XDhMyYPN{y8n{h`tY&KW7`bn z;8mp}pZ?_2@Ne(p)V*2burwLFGB%G6#WL|ATAC)?9{=I!wkIosCR&u9y;HxiZ9Fr@ z%Esd%1u0S5#$ZGeUZaGf7SAJ-(`j4co{?GedQELb@4AQOKrJmicQ2>sX1^xhrAQe- z3;!fZ%H#5SKV0+0_L=r=$wwLU`|A6UY>`4yah16EYS!7}ZxerG#Ti4LzRDPJ-Vv)m zz{BMiY&GD}ct8u*D`b)G$$h@x)wayeJW41!I}g@1(&dw)sTOK(Ebo5F*J;D!hv;)I z(M__%L*%h+1&vYB061aH)!fk4^&%xCgBRup8skfr%sGIH=Xzh({UsZR{e75c<2z|% zbc9Qh12TgJF}goXLX3iw?6fV?h=Q&x3Crl1zalH1^Q;>%JjZv6XtNfC@{~xH0v}Kj zx3OG%2gFixz*rZa0=eSzjX=Xa`vBL%$&tUl$C%r?NQ)pf+L@C5sB_@2z6-f?wdr-< z@y-Gv*t9V8kIPN`*fpE052iie{SdW9FI40Q zqy_r&%jVO+R5J1K?w2a<_*D6HtX>*7Gv=j@l^#~l5ydcPJKsUj(bc21ripcyn5|=E z2S>F;97(_FJQi2VX+4}jt0gW zBWt`f%Mk8t`JnO!rB`Cn_K2A}oj>+wmaLY*b^1Z@xO_`XxPa>V*1;|M&lpAaJ~{Cm z+$bf^$RqEQ+NK!qh|V(MMV%FH-$<-y^x}-fkbAf%k51Mw0a_ zw{dAoX%UC%3oAFJRN9-ALB0@*|Bc_gBSr)v)9z>!y*d3;b`p1S{_4AsUws$SZAC4t zzRCE(bN=Wtyrx%u^<7Bfz$heigqhnguMuV4VjIuy`!M}H!`!1eP*y$A=uv1l+8KMS zE+no@956S;J#t6g@KwCAj4shQ3@frE^T|p7PLA1If;gHtG@P2U1|tZLrYaikies;|@OT zan5g3c7qodk-q@Xa(Us*G7bC&W=Y3z|x1WCZ>2JZ}f9sS~ zts3=MM?Rx7t)EHPT}eCju?*s~cV^@D;XYDv4q_xmPN2z1*^)$;vOnuFX5OE%{LWsm zZy)uC!c8`%cisT%(xjzv=SJ3?c^~OecGWs@tz0>R3MrLZdDgDgXiB`ond5(Zy6hCR zouV^i#({sOGVb6tt6s92Bp(h}udsAv8ht4t{;jWmdG=FnjGg^U@;*r3qdX$*q*(Vz z4O337cQL%%?}b?WiWDyQGr!uuRNp$W`9ja?PfMVcGJEsgAoX$EPtW@CX>-{v% z?PKCrY%VW&gH=`h%Q%ZO(dO1o_r<9;X zq}P_5o}zb&@9XD?XEW}lR;T`^Y&l4;vfR@f8K{%_mU|_=ADRE)$Jj@`EB%fa{$}h= z+V>Ukn<0G8dEO4x`yxcGcE~ZSRj{OR>*%e%&liGmG`tKWcS%h9; z&pE87ak%UiyNT1ATCaVr`#5qt#>KO@ne{92dI{@tL`$8hxvu{->uG#;V(<7otPe^^ z$C}kqpIqeOk&x2j-{Qb`N8X-xq~64%5>|VrT~|k0QWU}WS#;Qb@0ZT^{;+(}77jug zGD-GpUTI5ajzmA(4Wf0n(0Ybl#r+p*Z3Syt6mxPUsT^oSD z9v5eiN$InOYR10Qy=y(dEI1U6dh75ZuX%f2N7Idg;Q8*gf%w0y4r)ZPTn;*Iy~vdZ z*7~xUrHuYbk+tKeYICU}P0su3XJmkvcu(F{UtZagNe>Uo*^=W2>CX@U^4Np-fH40j zrqU7Cl8o`y&Oi>2S!){Q))V*km82mVl#8?U3dKwV_%;S>9yJw@Jm(<`Zm!{Lb-(W@04(pQVq-`IM8 zD(|_yN1^pO$O{Rd;U=WV4w=KlW}3qjsp`}+_apPGU5~DH=f#qxwsLJ6B+NYZhyxGi z@QBTzgqa#zjyc8_ASIqSGQGVdE*I;$w>$T2Wl2&ve_vo<*}l(b-dk2JD=DPws6iS) zM)b_$OE2L+#*B_@{Jq~VG+#gcpm$TWj%dX8KFH^tueUdXobqg2|B7$NI<~@fUs~#8 z1p4t6@ghSD+N!`I9;4&fC#k)c{@3|^+@F_yV40i2+cF=v_qTti2NL(|5m&c%28*Om z8=uW}t%(xL>pkbgqII-Ca6RoV8SE1*$uVeaOu72=m-BnO>}T{fq{Jn9_#1n7H6i*L zTf!1ewZ3Z`qR;Vf(~r3JOXoAb%&$F(5!=%_7C)^h3?YoMWG$YNLZg>jCekJ^y)(<; z*M4>5-#OYvD=$59P25=NNQEUHP;abEJUqVNo4371g2=9`$VQ4r%ev^AY56rKR=UHd z=+Uq6^BCcnS2B(D$!F!?w9y3plFpH(7|D91dezhDDXsBN8lYd}H8@27_IIf7ILm&) za(UzenXVL8Mp059bK1X>_E@coPLIq-J?T8XY5Hi)xw$5Byp^#sw6=JE^-bV>ZLRi) zWnqtEWQ*HgecFa4HDdVb?&Z>a^s8?I%jbb`k*6hQEchYgGVIfs_SH9m)o;*a8Oeg# z#%1^QeeW&SK8dCf#<4!m*r!;KzU6H#U_Af%cj}HvEDMoOxb%=Nd&w#1PO^mM)N`{Fg?ezC@p@(?}J zL{xBnASxbz)AnECy~h43DSJYElT>fd_Y>Gc?%#Yq`em#gd}98(EAj){B^Jm0`K|fq zdt~SB{H$9K^IP!wx3oE))*ASa!Bce@ua3Jq;2-Zm`;r_Sga3HG-D*COuzcuMLQH>E z3*Xga@1TDDQYSul^jpyud^iq5tPqY7d)ahdGmea@Ho`hOoyYF=JrThrPre^)SMn! zh%Mm9YQ9m`06pxH4pFAk~&6-3daZMo}In@tT=68MnHtiZz(ninP z=21>Pq9mk6kKsDei)p)}EVQH3Nd@OBr*AaB?R}5G3}g^3j&}2FSlRZjvEP6C+fV<& z(|`E%A0d+Bhku|sJ&friE%N4?xQF+|td=S2om<6sHI^lnv03l4<$mB$43D`pH0^F= zU-tzkN0z6jH&p$=sN)R3`7B@2VHx4Wv7!9f^hzgOP{wDA zh3mB(TLw$?x;s9ohiXO-)@PZ<>A(01ugE*UXL`HF#=J-rd8+rZcJM{w{Y&vjm_R~f zGj{X!d&EoJ@A%qhANMs6(W>ZFHpapP?JY4-=& zQw1*!|2bN^T9-8Pqtx_iNxwR{{!4r^UN@D)*O6d)qBi$zO21yz`M|U_+*!WFhTbvi zUh4q;I1Ju6&*6BzWbY^_mrg(r0XA8U00>iM%dv zYR1MXNq@z5GGoDG{E~d3xiKYl;uT;2$g}7^GtBm{_L_A(jpIm@k@k2S#WQIj1Njx5 zt8W)umC$%&-Wj{26#ETGu%}Io=lAXLk5Z}kWf`PsjD7e%%TOXjU|~LA6fBlXRVi}; z4I(x%4DWH_e2|)hgG%$7XA`BM9p!f_&JbVO24U~x-NLA$+QNb3FI?4Qu?)o9W8}v)S{&#@>@6_i*SDZ+z_=+1jHfNr3yyc|Kl#6bV`eDwrv6D8j$XHSs z&{p(B!~q6p$vIb#{EXDvX5_M#W^c<_0l{?tqT{azY#gt3p{O1k5R_n4LELk@3&f9Z-} z5EAvG)g$sPIddT`ZFi~PxDq-e5k-k~tw%{=6-hj!n~%-E)@lA|^(_*5s1x5+^{H!9 zD*mJcq|`rfvj_V9ZY)Wzs(}JJLPAO6E4*E7=-JA#b;p#bB{YuJrnkyhe${GPTu~qG zDgD>Jk1?z`wqC6RshrN%fHVDr?3OmyN%#0@a@4nDKFYXqkLIBuDr&}$S_4nqBMDrSJN69?F&0eS>Gq;mKG1ZEt)uxnh_B%d<#%MUHRFbXw6R& zVdGJv#PqzEkJm&?^l&`(Z9^u}oHy9m!lY*{z+IYDX3`MPcu=HUIj`?MnRUTp;@bXF zmnWXMq|C>EYwxaM z$-bnDF#uPDjyS?Km#iZp-!dFNNqR-OEtzSSbEM_G19R5UeR}=PV{{{$v&zt@qOs}7 zQu}jk%62G>s6VZ-SB(lRBPk#WOSuG6IPSN8-LIih#Fl0)^s{Q~rWSsoGc5sXAGGwn zwb9!gQA5ZOS6Z;Lpj}3WZ|GYB$5)`tml6*xd{IW{BiCG!%hI~+7-<8yy`iJuiL)MyLOt@n@9;v z+fs*0=(dFTt(`djVVmfB`prYyR_;7QC7 z{A#^$l|0~9DGuJX(|EinNT1TIHa!yWwgAw~m>Y7xzbuezWMO?iE6#f~$9<`C8(A;+ zNjiFPzZI=7eI5j}?@ybKz2d{i_}tMw_=qCUI}Tv`DUBD#0YF3TW4t%C4s15^(~{;G zD_yT-XO9m#51E<%*FUYFlNVdVZS00rmH;(bz3rXU`=iGRR~~~F^Q1HO<8dAjo*aA4 zw=2d@vDw%KG~|_`-?&d&k`P#_?xC;bz;$SX0&7L;rmnQsBkMJ8>y?I-dQOgfDu*ox z=leW-*GY~Y!qW86M0Cb)Ox5Fm(AS6zblWy2`kieQb&6`}cC~}^Xi{8y@MV^nRMu;HnZhkM`#}(edQx&;|{2+#~50%lonI{8?*Jjn?e3((bYI zzTR7?9^eQ&!QcEoE|0phAF6eP8@-ISj)bj0Ev@PCHh-~=HPl+7t6B@%22et~869B? zrpf1dXXoklZ+k@75~2g|sy(i%D#`4p7*C>~A@`(EIW^;x&r~v$)b-HE{qA7My^H={3h$CVy~fXo zyM-R&-*(a`FY+tos=J%$C+*o!=;Z)<5aoF|@s&M|UD6Y~GxD^t@8;@mZ8Ved`*5 zZ6lySeU`#i-*Vdi*;?SQ>-#S(S_(`j#UeV04L{Xn`)A4e=DwegTHUGrV( z=y_@(p_Kf{6X_tyt=^H(GV_b4h})$_r+#{6Mb)$3D@vp_Y`;ZHaT{_SxXNEz$9(XY z@(Y0jeObGsbJUPDiAM6}P_gdp1Iq-!7Zgyvj9 zz9Pya(ya;8RWkYEva39kR*98SaryN7=j2n57Cqq#E?gOkbmc?Vv{`<#GJ6in zcjdEj&vvYj&pgA@4lg~|Jt%p_;V1SXBA|c7{Y}aUZCjHmBkB66y~fWhvL>j>M!=$c zBr`RI4o$-dtgAgu3opq*EzcT6BKbr^RFamqr1dk}7S^VFRB&f*Oj-zm)KQqmLwH76OFZYh5XWH}Vj4GDPGT-%X{7|gydyKJO(j5bm zldTf>>l3H4f24HxNDduMv!3~~P17@inW7|fd3~fmpwAM6A8K^OcujB2xY4`w+4gz= zCY3N9-vytHUE|&2#x>)}oMR(|=K!^j$}|SECQI`-@i{GT^733cv^e8GJUeUmKb}aQ z*@jVF${o>_D>Shb%SqR+0lsOixc(M?XWw&~WtBf9SN&tA77ElMzpP<2u0jTs;d`H~ zXJxCOx5c#A=(Ui7ukbiOoQg{^KHpbo%qq8M+APPf+1{l-XolWR>c+u$Nh>Ki27-?2 zaSqC39oiM`>49B8A~MM3KT<%PKChJyib`h-$eoO8G#E!iNF%I|u_NcsKh*Q|r%ye9 zkN@Y9BJcBSym)VE+^)GEgBi?g&0>h3S}pnr=;_$d^|kAJ)Y%SFhPbd6a6x_fmH$Hf zu?Q*0=UR?+R5~pd=c?Z$Y9lse&FHcwBJU(dwNm^&cq=xER{IJRC8w1@d@(2G@%*vY z{fB(o5hdHAbxv6+18ZO`BRMbc))7ANA@!*6%Bdwvq;{p+kwe?_1L=aOc&4_ctLDrZ zsTfBPn{Z$HYP+tFCJwO-C7F7S;Q{k-^H#_`utrR0^}L5i~TFQW>z2>p&G(>Josh|~JUM;WVj-2NH!MMX$J4qR7S z9es7$`lbs@RoAIoZ>mq;_@4T+ZoS>|F5l5?&|{w8Cvo9h&11)>UnHfhk9X#^^G&VP z6dQ5l4m9y-ypV09DN9UG5Ui(M(Tc|Pfzc?)ZTmGp{?(6u1B+g%Xe1E^*uK19)S*g z|6}74_s)I98b#eZllCg~BzL49Eqy&67n#={K_lx@)fp6xNos<(k*)quzVgcngJ*id4%%KJIa?*K_+FmcR4#M^Aqj8vR|i|H^S5heEKs zbH=q~hJ95ZJaz1tY|2NLj@{w=u9x+N?Q@-eMXgj$oh;?pcE&O;(z&`k-IcjdRe3_!dydl*73o2bQt)mB%XD&u%>Dw zUvc7m*0^6XK3X?OLJme}9*ur!^yqy)qKYy+4tlw!WXWd=wN#vFq&n-WhwEBI(eJuR zuiLtFpB>oDnhbdfd2o7kEMnv-S+irlcQ~HcYRMi;)z^m()^_hn<~?o{h+4Itj?^DG zl%|f_`{}cz#!*u>F15M}z*_i+9UNE``YohB?{T=onR{gJv(=+;W+1si!Scsa^dwPD z>ezH_kbH1tIe8Z@4-4Q-Us3w z>vfS``()*()<)jP($$&r;`=AJQ4DiCGO-SoIXZpI98vq;KhEl)_g)td)`y0{)JMOy zSuNK-Qrv|CwTW~ZDFKf}3D&NJJT^AUOK6GHA1dFDK;jRL(3a)7bR;vQRYe?Q09>p^ z>{t7Yy@Kr>(@HmfpDyHTT`&j)|j`CAqjw|i|=XmCK z@b=5w9SrdYwT_i=7TTht@g~oFMXHp=`*4`XzPB`ZUCqbx9ix?Qkpve?Pim~+mJZa# zzaBT~{KmuBdhwiya@yE&?X+{A=}`LteMx-t$@HMZh4xpuXx!_!Xb9c*YcWJdGLw#S zs_9L`e5<_(k49_5wo8sn`()jrQQLG|7qk?HrO2ax+jlr6NVIXM6=5I_CLzI)?xnlGAhI;!s*V-n{~=7SMq?jp5ah@u7L9>T;y|O!wP<3zXdb zuHTq<@y%BUAfLu|k0dOwYVK=~cZ|W?B$IUUhw6Ix-M7y-w3RzOPsj^9W8FM*N1k(@ z?{G@nV!w4_1qnk->$B~fdGECMOMVw^|92ZtS{jn5-l@A%%!kqHL)1~3#*DTb?YM6A zLW{fisqit@1Epg(Tcym%r7;U-d{2OTBiz4E{CrVnQawF-^bPFY@Xkc`kopb^^_nOWy=+DN)wQosPAF-0C-S<4Bvq7TNjyQ4*3I;xZLLJ_ zj)Yn9fS6c`L2hcH-~j1V`P0*>u~bW% zcSi$}rM(YoSenX9A5)tI71nHeIm|KI3>V+KrtF>9A1z^ONk(%77ir)tMY+e4$5Wyy z`C7J0Xk4hj&qC$o$@4?g+-HZZZnwXw9lBocrp~0p{dYl?*Y*mg+{Qmharq#8)nTb! z`YzV!EKZ1rQ#tZTE!$d-*5$Q@`iNJH>GP1j5q6Okoyve7!Pi}(mYtD%;fm{)yL&3j zS0dJFyy?u?BiWOxE!C7uAN-xqGujlw!N_QTp3&x|HtsslIJ~Qg^PW~{6+CR^UKuxf z#b81Up)AJ%#xG^+eQ6)gLs|YqdHl=)YjAwZR_(>RXm&IrO<{AFw|_-@?uib^Z3&Wq zr5S%hpZv%J@54h4?$plCt4btGg2rEd*jjknRk4XB)+=Ro_B^DmIYVf+o$KAn7pmB+ z%4_v#)^_@HO2nL^hI1gsfAW$&p0dv!&3nN!cFwzV|9tMSrjG(o)uRMLJiRi~ zi+j?QyW>Ubg__l-eV(wPHu%T$#!P7liukwfXU7qoH+@w7T`%%no>Pzv<#~(`D8(ra zxee#6qmPCx%ik;fJdX8K2%Wn^D@t<2DZd><^$x!zZt_ta(-WZc(cnd;En8fqs2&SDBp7ypuQk1j>u_=9?&E0mCm(C^1UCy9*;i3@6!H0dW7F!>$-GDtD;z$q4(mSoQ{%z zP;cRGB<3+LDqdtvzbz3`)#gNUkZ6w}$|%9vJkQ%2Y2UX0v5V(3_4UT?2NBlq53vE#^GY(r z(y}Adp6w1f@cXn#T2e_R6m*9EM6I1X@otW!#a{-kUF+eV==2OOTifS~cCFINv;FGs)*{!PzAe05ClXBL?=NI4S^*P1R*dRgg^)^Km!dl&_D@j zz<~3#bLu0%{RCEK+@b&F$XzzKF`ajet(|sB0c^Pzm!2c*uxw`rtd5MRIuiAv3E;*>eZ8Jgh(_?I^ z7RCc^`|H{(M_by7M`EPqz#u)bvm@lg{lK(fpN%HU%^swP#Y*ZHJqz}AZ?<1drXW@$ zQTx_zRvPbQUen`j^XyZWVB49eoVnf0yFY?tYx4gem_Z)y9!BKYv=Km~8R=+@{xjzp zXEf9AmYwr7vQIo`Bmn=8isYV?3(Zq4JS{6>m^@d-6kYa>v}{bCz0XSR!qmvnwteh2 zLW%!kspjrKU;{+y$7XXTi+W5fVCNCztj$0AF1}236f2@m-ete!w`cxi7U6Mj%`AcB zd!x>yl#5vcm@K%Vvmr3uKxmu04EG*r^$aQ(&hd25EfhSo6faPgz zi=QK}EpM$J>3+8@f2KusdToT`k~9Cji%@Nnxwf3jRv%4V=XkJBZux*Mm2yXBNk^XQ z;hdJ<1;+cil2-wFwVC&My}ZK*f6$9OZS8~M$mF*Z4=!&E&AbR=bR^qms?P44p`c|n zs73Y~qpZgoT?J|+wcJN_XNFq#D&fp0I)5y+VQKSu(6Q){3j z6D%nbeE0DaV{X~r;yv^#BVj{+t6a2Z-em4S3^tCqZGGhy?c%-Oe0z}m%lEeA41=7D zC%$JEBjd&Yd2+BAw6#8s*|EW_rKH@}$MCsqX+OnS@?6iXrvVRI=#MSS&|*dsQ$Bf& ze8gI@&HI4Q{kW6&hOsbwX0y^t%{o$#)%Nj3$C92su!VdPPux9w?mgH0cD(8!r16*Z zV*VvtXAV=DztisyKqtpb^iRy*@Lo~AuZN>^W;A@4dU~&pPkFuS`RZdXz}iIp(($Q% zt@Hl!MfSx=x8YUsM$Y($ZToEfEFKt9@h9R1wPsD=;mSJeZ(mh^ZR&pI7jNU#`dLdH z;oTIRB~U8$qBguF8GdgP`w!STZ}O{rzoT@l`$ev?G3WRB*xNk;ZAm?`0^iP^=F!Vl zAC;doBqQ_jQy)EA5mh#Z!F|u?HMe`MHl8^=vL&UI1tO(?jbr{-)E^#Qj&??y=NCH1 zCNtp?$K_AV>hYd1y}5#Ijy8Uy|B69t;``b@?}W;)Vz8w=hWfttDK3E)8j~fVH<*AS z{-k`IFBS`VVOCGZt7dNNC&?u%Xz4QlUk1**Y*^0wswxE$P(AbR!{#CK3dzC;M3S5* z1W~r)Pac5oACIh$`w{|(y3*^zBI`bmUwqkn-<+#(ww9+3S&Oppr~049U->E<&}wUM zBZlvslzbc)Zue}23-&Y<)ZAqCzDSxgx|um}&IOE|J*ti0b$0U{{lrgmnfQ=p_N>OL z`}0?d5FekMG7Kj&%9A{3&ZGyvP|L&*(3=U)S@C|>V1<2*4n{Tq*mGv|X$zi{VMM$= z8%As=mLxltNRlzQg#3EnTX;wHhYLhHOD=h=S1IOQ=Jcsz0W9Lr5^h%3-;=+-2_`a4 z_FvCi_xt7^u1k{}#T9$=ve(uKKT3ttN0}k3+>Ka#d-eR zgJ!O&pPVc!WEp)!`HV#6Vt(UYKIW`k!RIJPS>|&KXP9~(M~+1yoLJD9nt7n+C^{!F zzWy@TiYxbgjk(0ck28q&GNuN-`-qa$-Ph>zhlMg-H#><1C28RrNIlQzwKE=ES4l)t6Nr+0Ueiw zpC?jL@(5W}nWiYDcJWA!4ybZT>HO_+Bf# z&;K)KogCNqmFnHVtTDZK#;F~htRb(Q_citT_3OHX-(hAvz(Kt2oy`xzf*Ouf98c}Z zryYk_hq>i_GSIPa^W&=`d(|^~D__`&pH_zX>g@KKHCU5Jh#q||y&EHNa{R5YT&@u- z)5W6gt$RNC*j%rDpxS}QQqfoV4S&v>r*G)|r(;n)X3HQ2@uZd~emzf3CYQbFZ}R%& zJhoYH(877U`q{~+XRf>EU(y4!_s)@Ps<6u_!$yZ-dROF#bTEu>excD0k3szZSQE_#PtqZf_HgD ze%3T5pZ1#L>%0gNrAR{8L^_8|-&SU$CfE7}dnB=|$EZ9G!-$Iu(_a%|C33T(*WAd{@1Wzc}uzLHIRZ z)+P7!9c#^)PB|!xU$DoctS;fdFi`{1vS0E)UvC z%v;Nhw1`rc*GFFSS?|Jpj`@)d$^eJuh_T`*sa?>Mye-W8*X=3o$uFD>H;xTf>ktDx zW`^@k?@+&-`{<3OwJTPt&)V~AZWOuF2cDQmB>RJSEv0e6E!u|#W4b-vf@8KsM-Q(# z7qK-f4iasS@ri-plRrOt-3u#V%!_y^M<#q zp*4`6JLNaFn+Y4WkI_OYlt@&J3-LY?61L(?)TMl^JW`)(BPuGJd_IwNu(cmQnI|`+ zSLXBxm?-(!DiTkxKbSr^PYzq-2_uxZAX6R#b;I99R(m#4VTEnh-p~&6>TN|JYj{*X zvTkwDHbgTv4qxK`*NqZL&X^89%h_37rJula{S^;&T(^$Q!kcM34i2k9@^B8EjIuaV zMBn{7)*o9F7p%#nLWl?*E7^{uk=BPaY`Dc#acC8WbeSk~h z>-;om+gjd){EeB%D3!YKdG7e;5nPSX9Pe-;-XQ~V1AX7;T5If;MtaTrT_56ESF(U=@H@Hdbv}(F&(?Qd z!*RP7OO0Z)5#5oBRzg?(-O(DQjW6TDY6|9_-(KPh=W(yqr**og z^`p^D{|E!EfwwY8M*B-W9<@%+%JA(;Jt8Ga%cJMf>PbD-L0$Z%h3#iM==HiNY;T`x zKVfa#b17jD`Ze|N$+_ZoA9C+(AJvxk8u(cWucJ{9vgwhX@k6-vyD#B^7#pAzpDtMLQBTugG8xMumD7do4X8 z9F8Ka;CvJZ+fxpHqnoWEMW0Cay}MIt9C!{!@iKhKO3L79N(uOmE&k^bl|z|Zjph`0zi{q%aIh{TDBD;>WYmj0GCC`gE}y$Fhed{e z;YSj%x>?OUleAvc6c*MH=iy`WAg}Z3EWQ6H0*nCvvt{mSW}l_rKF_cF-pYaeCQE3; z=o62z<;D$LsAt7i=<&RUmP0fCWbceoyyi-KY76QV^*{Wa5y{x|cq3nVjS%J3FFVlU z^i{UNk@SD;dHn?_S(j~y&KiW1t$*hF$^#Gb)kfn)Tf+|Jt1BMj9Emd%X9?Q<9@=2d z4pDyQteyY#U1xa544E)Xwai;;ZV8WbpIb_AIkzZBDZVB8kN;AywP(DIKD4sjNXxtm zUXQ$%XY10L`^>zl@*$2bVJ(nMAJbKUYcD$p)oan_-rE{cxM~I8f@O`qiJv?%HxUF5 zh>&fd8PdcQdbu(femTqgM5o>q9xXHdr%&Ofjipg4`t9lkY+nt-rv3a`&0^hj=IvP(FZ8$ zPm~Q#?KvZ|yvOm~Ewjb=qkTpW<@H>za)8J6gJae>(w^M29X_hpt@F*xJT-1~I9hwA zf3mgj9@4k+lJlFFe}SX!AK%xXFYo?dV=m=~eOM)wwW@5A9cnM?Mlq4;$jrKpwpQF( zom(ECm@7hMhSqv$ z@xFe?k+fhP)ywr}SmWO#eZ1}~yNMogLch@JJohOH^hQT49;5AzMeGBs_?>>)(cAf% z61^tXci3XBu{or&Ce|anD@Z|u3`YdjDpcl{_oMPX4gK|HXrm31o5(UFYD-IS|HkeC ziffJS8i(h;5NH+?og3+GT|ht_V(E;K;-}cUmhq{-*CQr?nC)d3)NHb5xl*KW! zI;8*SkcG8(-sKN}=`4pWh8JKQN#_oOl&02OX8W1*XGN{8kV(u41o2xv04<8=@Pl%H z%Y1LF zB;2O_d{aqhDXWHi!0PL4$&d3va+;edPqLKHDpj78_02=I{X{kEdeuf&BEb-a&M7=+D&y;!%~vdfH+6(P+;<{C z_gEALKHU;~pteBr)spuReUTr3zh!yw^GyWbJa<>lEE`>7$`r`7Z{ zj6!G&-nnL#t1*ZMlsRLmHETx$_v=;b#sB9%+CF*gw}<}s_jZFUG1olIb(a6{-{bt2 zFcfR;C7h3a3m?O?>&G)beMoAE|Bs)*8{8*U9*%d%WxC z_}A7E&DBCnE5aUQMB@7z$LqaQ=Jjc}=zJT}nkkbf6|3w;zC(1ZY`t!aj7W%jS(h0E zYqGRkYPNkdvpMsco-6D-kL`HBb1r=0Ncw<6Qp1P1LK)GC30Q#d+#~DQ*5BRlHvVM2qwf#llRxzA zto3e^m6=+m^?K`$wk1_~Hi8d7r&5`eFzYLfxi!}~zH!WT9$BntD;~PVTp2uxH?3nU ze`l89=x6=G%s5M5x^Gv#OAlE5CJu>gY(a$3E7(8x+<4wkT(nMjkKWg!W5ro!7|QZ1 z{vk_T`7YmyrC(r$F*;UmYF3&x5w(86GU#V^3Z^SfTX>3|$9YHW3<_*;d}1%$C_;@H zM_HrN%6C0Hy{YP5z~9)dLs!%RM~MpV6H%9Xr_q^QA}dIP^H4S(AI+ z9#$vQfA~4LGGiUI7!qqwqo}-=N9*S5GN&l{J!-WKg%ajA4l8U|>a zb=2=^gB+(G*0ZUneQLFqlq(m$1D9_Q_OlW8y7ZCpbB{oyy=zt72VyZcy%N|auei6( ziamG=yK7vzJhf8$iBwTA=*vJ$M-ud1`YxZ>KKH7@2Ck}@LCWA=bl3gn)y|FS@y+Dy zVv3tRslHcXDvL)(KUrTmr~EvBag9sxMLCnfW=1P)`x=J1YH#&6QMj)EK{vUYYZYO* z{9$DpCG#A#BXd3JCG3#Ot?X-*Vaxp<@Avl09-V%qc?MaPlwYjzW8d+PXdX$_5N(aA zBfas#{z42~{h@UAkGGT&n;xH57)F)-+&X$keypRMMiw|l#LI#+_8si3Nhv`*{PNd( zYxA%ulxPty(0fPrxfjy!W4xT*P*y!*8Md90QVyy7#-pt{$Ii0=Ys{`sPHp4Te(kAr z^Bd%>!OwX&K3ax*0-j#%z*GQjQzC}}C2VkteHXCi!lKZZFgfmK!Bxe}xZH^j| zsg*Xz4x=UCk^!jl0k4;Qzh@Pa$Ke~=F~6Qb>!?H0$$r0MtN9r5;!pT`u7hL3WlQ3n zSP-5whr;!8NoEVlz&zw@#Z>0_z{9w^&cslg7Psd=!v=BY{CNaE$Mjw7-1+U*IXy-Y z;P6P`ct4gXb^w9p&CuB0a(zZQPXvMo#GmD$Ci!U05^er_v#6WYU|t4 zd&wEX�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%0Dw~UCs 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
    ;@enH`FZ*5_qQXW5KtiC=;-n8Z*z?4mwf@4!I}W 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 z<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW z<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW z<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW z<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW z<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<$vXW<^TKV z2EYC{{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N z{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N z{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N z{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N z{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N{x|+N z{x|+N{x|+N{x|+N{x|+N{x|+N?l;~y-Z$Pi-Z$Pi-Z$Pi-Z$Pi-Z$Pi-Z$Pi-Z$Pi z-Z$Pi-Z$Pi-Z#!S&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C z&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C z&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C z&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3C&Nt3?&Uemt&Uemt&Uemt z&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt z&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt z&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt&Uemt 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 XzIF4hn{VBG>*iZG-&+6s-~av(%il(i literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar21.lvfont b/tasmota/lvgl_berry/fonts/pixel_perfect/PrintChar21.lvfont new file mode 100644 index 0000000000000000000000000000000000000000..f2ff7c4f97fc6b430f080a29136020ee9d87e007 GIT binary patch literal 948 zcmW+!T}TvB6h7xFI3eWS6;UhL8C@}=Y<0_pQnPh87mLDbcDArwcPt~7l=h)eaI!@P zn-cni2x2h^gCZ!1>LK>U6(M>EdI&1E^1%$kKw=7WJ9ik)eD^!|JKwqIa(w`B=2TBF z5*C02MUc;n00)bJQy#Fe&;j~2QRss`LyT}Mg-p>6NWmPQCVtryC!YdZad1Hy1VDpv z55Pyt44l(@`UoZZieWvtp^`jmp$_Vy5q3imBCsD0LMPRn1Rc)8FkFB!n1HKr6Yj!2 zn1&g61W(~5WMB^7!h7=l221b@Z1@L-Sd4D0L>X(b4tHV`wqXZ$Vhp?SG!9}CNAMDw zXyFvzz&n`62lyDD;VaDG9KOMK_yIrT0xsb){>D{gOkyRhjBR8Jt7Y4mpY3AJEW{#g zKRd*ttcxYs8M=%CioSu1r)gkc`CqU9xxux=ub(_@*owmjz9%blZAD+4%TTgM3KOj86@slQi=r_>5V$s~teYif>2_9@1K-8Tq@Z&M z>)~XF%(avv3Hh}jG2v*PKPDilSBL|Wzwk)v8|Kr3Es26;JSX=4kc}aX9VNkx!;b$X ziFGu*&jCk5V~P%I^_HG}bT2GoYh9_!?W~yyYQUBeQ6TaM@ piagi8SpJPh+2KKh-jCO>k_|nEf*i^9R~eU6>Qdzv237vN@gIR*AwU2C literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt b/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt new file mode 100644 index 000000000..e48a09bba --- /dev/null +++ b/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt @@ -0,0 +1,20 @@ +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/Shaston320.ttf b/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston (GSOS)/Shaston320.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f4328fed5fa8487633f5b9dfc53a4fc4d7d5bbd0 GIT binary patch literal 50732 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 K%OxLl=lvffBTcRV literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston320.lvfont b/tasmota/lvgl_berry/fonts/pixel_perfect/Shaston320.lvfont new file mode 100644 index 0000000000000000000000000000000000000000..4470f039fa8c80b4adc25e932a863ccf98bcb1db GIT binary patch literal 1076 zcmXX^Uuaup6hG%n)^((F9Xh#Xvx)eyYD;@#V7;|5{bbk%q;F+DI9Ow9DkCG=gV;;g zEX~zaY@`pvKQ)jjMbwun^dTLF^p1!XsVL%~WGx|aa<8&YHpJL8weft3_j35%^XLA~ z`JL~R0pR7Ad{anhfp$0yjfOC2B0wj_0j<_U0?6EC{!6|vBkUt{kX@k61z=781M)Td zB=K12s}qjH2^fUuA!Y~Ip-3>~_e~SF(`%#r33vofgA7CPG&~FAFaa+RmmdNUf>+@x zEWi@H3u*WmK7$NwKpwt^@8Cz+hFfqK{)T_y5FW*c@FYHlz4#aLFQqjY@AK7^K6P; zWS5!BqHKXJv3FRCeZ*GT8q2a9>`V3y`+?nL6=u>h?vPCf)qn%uaN@|pBwy)P4Q^Wt z-A!H%@>zZ1rrq}QF6WjnY~$94&q-eG`fD9W`?l^lAGMd2J-wLlcSy?KR~^noKv!%} zj7DDMeDU#k#24+UUDJ8;SlKcE0Jp5m`40I8aBb)hGo{WDrX*iH!nNUI+?i-$Sj}?H z(`BYBajuONu1LZkF3hC_j#Lu9ge>ZfYBOFmla;JvzQ3)fwgzq`w!XC`=lL~zIikdJ zl5hFF7I#$Qv-#g$7k|oNSwzfq%^IfjendrftQplEiY0zo~qeMSj;t)A}gQfb>o!aZu%FMjc;#(hyr3-L=4 zd2h@J1ZKD;*Crk-`OC}8yL_c~UAQRhwGLEErBZ=w1Eg$H zP?^MBAEY%GKyc9^MU~iUEg_Nx_epB&vdj5tYS6FJP+o1-eJOd$YwhoD$?OkFRoc`U z_0JtK#lS6Tv&`$z T@Wm#T^5&;_uXE@~dLRA+q;8}9 literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/m3x6.lvfont b/tasmota/lvgl_berry/fonts/pixel_perfect/m3x6.lvfont new file mode 100644 index 0000000000000000000000000000000000000000..08dca3ca1f0d72db2b4570d632d1487383fa2282 GIT binary patch literal 824 zcmW+zYe81CPq=#5W*k!fs=^D7E{`y%drdUh*H_S;O+A|_1m|VSSGn#=nn}5 zFHuAiVm~s`AB8LF0)q&m9~Ba25GAb;0tsh7LLxh#yqt5M^FGhH@V*WJtN;)X*h&( zEJ_v#HP*LCOp&t{J77b))MrWE0p!AsqsYf86u^UX@S+m6XhbUvbf618xQ2cVU=YK& zi949UeN5va9^)Bec!f83hY$FKFZh9<_=VqC#|A94g|?H8(rFLbX&>c~lU#I!j?)P$ zpfglLWmH8PwUACB>ZEQ8Qy&e`AdS*(x=Z(Hl4j@;&Cv^bNw4WG&C?=%rmqyIWm=(C z`Xi6x4|KN_Q>scK=9Bwbvo?o4>k(e-Ty}$%3a_eJn@Z9~S=rX67Ys{itjvIv$b+uQ} zzyY&!@$hF386C_iY=CzAJPB;sZ2pF-gT%OsO=YX(lS&}VZ)d*(_P~5rli5y4f_1P9 zM%k-x^jFm|#_+QM7C|DUfD1IxA&YhMU?UVk32cX*tWXIx&;Uo^1hl{zxByq+CIsOw zbVDCJ0TW)rTlm1LUtj{J;3xbB!dO%=8C6_?>9`ixV*wUpDOO-5)?yNJpAlpNM+DByM<&bH;mY2ngbMY}AF zg7VG6@ZIlIT{p_~xUSgmiZBvEPdWcwfwL+Ocs!ufV26mLvxvx7Zm}11I#VSi&S$d! zY*$mhPNDI!)(uSFo|KWHVP{OM%u6n0kJHU`1v;CBkruDUc9kkxLh7kzHMVCHx5jdc zT?QThyvT~3&0v9!$q360e2B?sGPF!cZ*Y84dJ+^Fxj>dO{n3a_cy09-8dh3&OESHf zNz=vYUfW<@X7!tkTtn(G{ePTLhnTT+#K=}zQOwA*afh8tNjV)1 B83_OY literal 0 HcmV?d00001 diff --git a/tasmota/lvgl_berry/fonts/pixel_perfect/pages.jsonl b/tasmota/lvgl_berry/fonts/pixel_perfect/pages.jsonl new file mode 100644 index 000000000..41070b0cf --- /dev/null +++ b/tasmota/lvgl_berry/fonts/pixel_perfect/pages.jsonl @@ -0,0 +1,15 @@ +{"page":0,"comment":"---------- Upper stat line ----------"} +{"id":0,"text_color":"#FFFFFF"} +{"id":11,"obj":"label","x":0,"y":0,"w":320,"pad_right":90,"h":22,"bg_color":"#D00000","bg_opa":255,"radius":0,"border_side":0,"text":"Tasmota","text_font":"montserrat-20"} + +{"id":15,"obj":"lv_wifi_arcs","x":291,"y":0,"w":29,"h":22,"radius":0,"border_side":0,"bg_color":"#000000","line_color":"#FFFFFF"} +{"id":16,"obj":"lv_clock","x":232,"y":3,"w":55,"h":16,"radius":0,"border_side":0} + +{"page":1,"comment":"---------- Page 1 ----------"} +{"id":5,"obj":"label","x":2,"y":30,"w":316,"text":"Berkalium 192.168.x.x ABCDEF\nThe quick brown fox jumps over the lazy dog","text_font":"A:Berkelium64.lvfont"} +{"id":6,"obj":"label","x":2,"y":55,"w":316,"text":"PrintChar21 192.168.x.x ABCDEF\nThe quick brown fox jumps over the lazy dog","text_font":"A:PrintChar21.lvfont"} +{"id":7,"obj":"label","x":2,"y":80,"w":316,"text":"Shaston320 192.168.x.x ABCDEF\nThe quick brown fox jumps over the lazy dog","text_font":"A:Shaston320.lvfont"} +{"id":8,"obj":"label","x":2,"y":105,"w":316,"text":"m5x7 192.168.x.x ABCDEF\nThe quick brown fox jumps over the lazy dog","text_font":"A:m5x7.lvfont"} +{"id":9,"obj":"label","x":2,"y":130,"w":316,"text":"m3x6 192.168.x.x ABCDEF\nThe quick brown fox jumps over the lazy dog","text_font":"A:m3x6.lvfont"} + +{"id":99,"obj":"label","x":2,"y":170,"w":316,"text":"unscii-8 192.168.x.x ABCDEF\nThe quick brown fox jumps over the lazy dog","text_font":"unscii-8"} \ No newline at end of file From fac1b89afa76f7c15da6e046c62e9a69252538e8 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 8 Oct 2022 15:19:38 +0200 Subject: [PATCH 05/14] HASPmota support for TTF fonts --- CHANGELOG.md | 1 + .../berry_tasmota/src/be_lv_haspmota.c | 207 ++++++++++-------- .../haspmota_src/haspmota_core/haspmota.be | 33 ++- 3 files changed, 145 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08bab095f..ce88c2202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints - Support for QMC5883L magnetic induction sensor by Helge Scheunemann (#16714) - LVGL/HASPmota add tiny "pixel perfect" fonts for small screens +- HASPmota support for TTF fonts ### Changed - ESP32 LVGL library from v8.3.0 to v8.3.2 diff --git a/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c b/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c index d4fe42dee..36c7aa7a8 100644 --- a/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c +++ b/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c @@ -1719,7 +1719,7 @@ be_local_closure(lvh_obj_get_pad_left, /* name */ ********************************************************************/ be_local_closure(lvh_obj_set_text_font, /* name */ be_nested_proto( - 12, /* nstack */ + 16, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1727,28 +1727,32 @@ be_local_closure(lvh_obj_set_text_font, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ + ( &(const bvalue[21]) { /* constants */ /* K0 */ be_nested_str_weak(int), /* K1 */ be_nested_str_weak(lv), /* K2 */ be_nested_str_weak(font_embedded), /* K3 */ be_nested_str_weak(robotocondensed), /* K4 */ be_nested_str_weak(montserrat), /* K5 */ be_nested_str_weak(string), - /* K6 */ be_nested_str_weak(split), - /* K7 */ be_nested_str_weak(_X3A), - /* K8 */ be_const_int(1), - /* K9 */ be_nested_str_weak(_X2D), - /* K10 */ be_const_int(0), - /* K11 */ be_nested_str_weak(load_font), + /* K6 */ be_nested_str_weak(re), + /* K7 */ be_nested_str_weak(split), + /* K8 */ be_nested_str_weak(_X3A), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(_X2D), + /* K11 */ be_const_int(0), /* K12 */ be_const_int(2), /* K13 */ be_nested_str_weak(concat), - /* K14 */ be_nested_str_weak(_lv_obj), - /* K15 */ be_nested_str_weak(set_style_text_font), - /* K16 */ be_nested_str_weak(HSP_X3A_X20Unsupported_X20font_X3A), + /* K14 */ be_nested_str_weak(match), + /* K15 */ be_nested_str_weak(_X2E_X2A_X5C_X2Ettf_X24), + /* K16 */ be_nested_str_weak(load_freetype_font), + /* K17 */ be_nested_str_weak(load_font), + /* K18 */ be_nested_str_weak(_lv_obj), + /* K19 */ be_nested_str_weak(set_style_text_font), + /* K20 */ be_nested_str_weak(HSP_X3A_X20Unsupported_X20font_X3A), }), be_str_weak(set_text_font), &be_const_str_solidified, - ( &(const binstruction[114]) { /* code */ + ( &(const binstruction[143]) { /* code */ 0x4C080000, // 0000 LDNIL R2 0x600C0004, // 0001 GETGBL R3 G4 0x5C100200, // 0002 MOVE R4 R1 @@ -1782,87 +1786,116 @@ be_local_closure(lvh_obj_set_text_font, /* name */ 0xB0080000, // 001E RAISE 2 R0 R0 0x70020000, // 001F JMP #0021 0xB0080000, // 0020 RAISE 2 R0 R0 - 0x70020041, // 0021 JMP #0064 + 0x7002005E, // 0021 JMP #0081 0x600C0004, // 0022 GETGBL R3 G4 0x5C100200, // 0023 MOVE R4 R1 0x7C0C0200, // 0024 CALL R3 1 0x1C0C0705, // 0025 EQ R3 R3 K5 - 0x780E003C, // 0026 JMPF R3 #0064 + 0x780E0059, // 0026 JMPF R3 #0081 0xA40E0A00, // 0027 IMPORT R3 K5 - 0x8C100706, // 0028 GETMET R4 R3 K6 - 0x5C180200, // 0029 MOVE R6 R1 - 0x581C0007, // 002A LDCONST R7 K7 + 0xA4120C00, // 0028 IMPORT R4 K6 + 0x8C140707, // 0029 GETMET R5 R3 K7 + 0x5C1C0200, // 002A MOVE R7 R1 0x58200008, // 002B LDCONST R8 K8 - 0x7C100800, // 002C CALL R4 4 - 0x8C140706, // 002D GETMET R5 R3 K6 - 0x5C1C0200, // 002E MOVE R7 R1 - 0x58200009, // 002F LDCONST R8 K9 - 0x7C140600, // 0030 CALL R5 3 - 0x6018000C, // 0031 GETGBL R6 G12 - 0x5C1C0800, // 0032 MOVE R7 R4 - 0x7C180200, // 0033 CALL R6 1 - 0x24180D08, // 0034 GT R6 R6 K8 - 0x781A000A, // 0035 JMPF R6 #0041 - 0x6018000C, // 0036 GETGBL R6 G12 - 0x941C090A, // 0037 GETIDX R7 R4 K10 - 0x7C180200, // 0038 CALL R6 1 - 0x1C180D08, // 0039 EQ R6 R6 K8 - 0x781A0005, // 003A JMPF R6 #0041 - 0xB81A0200, // 003B GETNGBL R6 K1 - 0x8C180D0B, // 003C GETMET R6 R6 K11 - 0x5C200200, // 003D MOVE R8 R1 - 0x7C180400, // 003E CALL R6 2 - 0x5C080C00, // 003F MOVE R2 R6 - 0x70020022, // 0040 JMP #0064 - 0x6018000C, // 0041 GETGBL R6 G12 - 0x5C1C0A00, // 0042 MOVE R7 R5 - 0x7C180200, // 0043 CALL R6 1 - 0x28180D0C, // 0044 GE R6 R6 K12 - 0x781A001D, // 0045 JMPF R6 #0064 - 0x60180009, // 0046 GETGBL R6 G9 - 0x541DFFFE, // 0047 LDINT R7 -1 - 0x941C0A07, // 0048 GETIDX R7 R5 R7 - 0x7C180200, // 0049 CALL R6 1 - 0x541DFFFD, // 004A LDINT R7 -2 - 0x401E1407, // 004B CONNECT R7 K10 R7 - 0x941C0A07, // 004C GETIDX R7 R5 R7 - 0x8C1C0F0D, // 004D GETMET R7 R7 K13 - 0x58240009, // 004E LDCONST R9 K9 - 0x7C1C0400, // 004F CALL R7 2 - 0x24200D0A, // 0050 GT R8 R6 K10 - 0x78220011, // 0051 JMPF R8 #0064 - 0x6020000C, // 0052 GETGBL R8 G12 - 0x5C240E00, // 0053 MOVE R9 R7 - 0x7C200200, // 0054 CALL R8 1 - 0x2420110A, // 0055 GT R8 R8 K10 - 0x7822000C, // 0056 JMPF R8 #0064 - 0xA8020007, // 0057 EXBLK 0 #0060 - 0xB8220200, // 0058 GETNGBL R8 K1 - 0x8C201102, // 0059 GETMET R8 R8 K2 - 0x5C280E00, // 005A MOVE R10 R7 - 0x5C2C0C00, // 005B MOVE R11 R6 - 0x7C200600, // 005C CALL R8 3 - 0x5C081000, // 005D MOVE R2 R8 - 0xA8040001, // 005E EXBLK 1 1 - 0x70020003, // 005F JMP #0064 - 0xAC200000, // 0060 CATCH R8 0 0 - 0x70020000, // 0061 JMP #0063 - 0x70020000, // 0062 JMP #0064 - 0xB0080000, // 0063 RAISE 2 R0 R0 - 0x4C0C0000, // 0064 LDNIL R3 - 0x200C0403, // 0065 NE R3 R2 R3 - 0x780E0005, // 0066 JMPF R3 #006D - 0x880C010E, // 0067 GETMBR R3 R0 K14 - 0x8C0C070F, // 0068 GETMET R3 R3 K15 - 0x5C140400, // 0069 MOVE R5 R2 - 0x5818000A, // 006A LDCONST R6 K10 - 0x7C0C0600, // 006B CALL R3 3 - 0x70020003, // 006C JMP #0071 - 0x600C0001, // 006D GETGBL R3 G1 - 0x58100010, // 006E LDCONST R4 K16 - 0x5C140200, // 006F MOVE R5 R1 - 0x7C0C0400, // 0070 CALL R3 2 - 0x80000000, // 0071 RET 0 + 0x58240009, // 002C LDCONST R9 K9 + 0x7C140800, // 002D CALL R5 4 + 0x8C180707, // 002E GETMET R6 R3 K7 + 0x5C200200, // 002F MOVE R8 R1 + 0x5824000A, // 0030 LDCONST R9 K10 + 0x7C180600, // 0031 CALL R6 3 + 0x5C1C0200, // 0032 MOVE R7 R1 + 0x5820000B, // 0033 LDCONST R8 K11 + 0x50240000, // 0034 LDBOOL R9 0 0 + 0x6028000C, // 0035 GETGBL R10 G12 + 0x5C2C0A00, // 0036 MOVE R11 R5 + 0x7C280200, // 0037 CALL R10 1 + 0x24281509, // 0038 GT R10 R10 K9 + 0x782A0003, // 0039 JMPF R10 #003E + 0x6028000C, // 003A GETGBL R10 G12 + 0x942C0B0B, // 003B GETIDX R11 R5 K11 + 0x7C280200, // 003C CALL R10 1 + 0x742A0000, // 003D JMPT R10 #003F + 0x50280001, // 003E LDBOOL R10 0 1 + 0x50280200, // 003F LDBOOL R10 1 0 + 0x602C000C, // 0040 GETGBL R11 G12 + 0x5C300C00, // 0041 MOVE R12 R6 + 0x7C2C0200, // 0042 CALL R11 1 + 0x282C170C, // 0043 GE R11 R11 K12 + 0x782E000B, // 0044 JMPF R11 #0051 + 0x602C0009, // 0045 GETGBL R11 G9 + 0x5431FFFE, // 0046 LDINT R12 -1 + 0x94300C0C, // 0047 GETIDX R12 R6 R12 + 0x7C2C0200, // 0048 CALL R11 1 + 0x5C201600, // 0049 MOVE R8 R11 + 0x542DFFFD, // 004A LDINT R11 -2 + 0x402E160B, // 004B CONNECT R11 K11 R11 + 0x942C0C0B, // 004C GETIDX R11 R6 R11 + 0x8C2C170D, // 004D GETMET R11 R11 K13 + 0x5834000A, // 004E LDCONST R13 K10 + 0x7C2C0400, // 004F CALL R11 2 + 0x5C1C1600, // 0050 MOVE R7 R11 + 0x8C2C090E, // 0051 GETMET R11 R4 K14 + 0x5834000F, // 0052 LDCONST R13 K15 + 0x5C380E00, // 0053 MOVE R14 R7 + 0x7C2C0600, // 0054 CALL R11 3 + 0x782E0006, // 0055 JMPF R11 #005D + 0x8C2C0707, // 0056 GETMET R11 R3 K7 + 0x5C340E00, // 0057 MOVE R13 R7 + 0x58380008, // 0058 LDCONST R14 K8 + 0x7C2C0600, // 0059 CALL R11 3 + 0x5431FFFE, // 005A LDINT R12 -1 + 0x941C160C, // 005B GETIDX R7 R11 R12 + 0x50240200, // 005C LDBOOL R9 1 0 + 0x78260007, // 005D JMPF R9 #0066 + 0xB82E0200, // 005E GETNGBL R11 K1 + 0x8C2C1710, // 005F GETMET R11 R11 K16 + 0x5C340E00, // 0060 MOVE R13 R7 + 0x5C381000, // 0061 MOVE R14 R8 + 0x583C000B, // 0062 LDCONST R15 K11 + 0x7C2C0800, // 0063 CALL R11 4 + 0x5C081600, // 0064 MOVE R2 R11 + 0x7002001A, // 0065 JMP #0081 + 0x782A0005, // 0066 JMPF R10 #006D + 0xB82E0200, // 0067 GETNGBL R11 K1 + 0x8C2C1711, // 0068 GETMET R11 R11 K17 + 0x5C340200, // 0069 MOVE R13 R1 + 0x7C2C0400, // 006A CALL R11 2 + 0x5C081600, // 006B MOVE R2 R11 + 0x70020013, // 006C JMP #0081 + 0x242C110B, // 006D GT R11 R8 K11 + 0x782E0011, // 006E JMPF R11 #0081 + 0x602C000C, // 006F GETGBL R11 G12 + 0x5C300E00, // 0070 MOVE R12 R7 + 0x7C2C0200, // 0071 CALL R11 1 + 0x242C170B, // 0072 GT R11 R11 K11 + 0x782E000C, // 0073 JMPF R11 #0081 + 0xA8020007, // 0074 EXBLK 0 #007D + 0xB82E0200, // 0075 GETNGBL R11 K1 + 0x8C2C1702, // 0076 GETMET R11 R11 K2 + 0x5C340E00, // 0077 MOVE R13 R7 + 0x5C381000, // 0078 MOVE R14 R8 + 0x7C2C0600, // 0079 CALL R11 3 + 0x5C081600, // 007A MOVE R2 R11 + 0xA8040001, // 007B EXBLK 1 1 + 0x70020003, // 007C JMP #0081 + 0xAC2C0000, // 007D CATCH R11 0 0 + 0x70020000, // 007E JMP #0080 + 0x70020000, // 007F JMP #0081 + 0xB0080000, // 0080 RAISE 2 R0 R0 + 0x4C0C0000, // 0081 LDNIL R3 + 0x200C0403, // 0082 NE R3 R2 R3 + 0x780E0005, // 0083 JMPF R3 #008A + 0x880C0112, // 0084 GETMBR R3 R0 K18 + 0x8C0C0713, // 0085 GETMET R3 R3 K19 + 0x5C140400, // 0086 MOVE R5 R2 + 0x5818000B, // 0087 LDCONST R6 K11 + 0x7C0C0600, // 0088 CALL R3 3 + 0x70020003, // 0089 JMP #008E + 0x600C0001, // 008A GETGBL R3 G1 + 0x58100014, // 008B LDCONST R4 K20 + 0x5C140200, // 008C MOVE R5 R1 + 0x7C0C0400, // 008D CALL R3 2 + 0x80000000, // 008E RET 0 }) ) ); diff --git a/tasmota/berry/haspmota_src/haspmota_core/haspmota.be b/tasmota/berry/haspmota_src/haspmota_core/haspmota.be index 6852ae772..390b3fdd7 100644 --- a/tasmota/berry/haspmota_src/haspmota_core/haspmota.be +++ b/tasmota/berry/haspmota_src/haspmota_core/haspmota.be @@ -535,20 +535,35 @@ class lvh_obj end elif type(t) == 'string' import string + import re # look for 'A:name.font' style font file name var drive_split = string.split(t, ':', 1) var fn_split = string.split(t, '-') - if size(drive_split) > 1 && size(drive_split[0]) == 1 + + var name = t + var sz = 0 + var is_ttf = false + var is_binary = (size(drive_split) > 1 && size(drive_split[0])) + + if size(fn_split) >= 2 + sz = int(fn_split[-1]) + name = fn_split[0..-2].concat('-') # rebuild the font name + end + if re.match(".*\\.ttf$", name) + # ttf font + name = string.split(name, ':')[-1] # remove A: if any + is_ttf = true + end + + if is_ttf + font = lv.load_freetype_font(name, sz, 0) + elif is_binary # font is from disk font = lv.load_font(t) - elif size(fn_split) >= 2 # it does contain '-' - var sz = int(fn_split[-1]) - var name = fn_split[0..-2].concat('-') # rebuild the font name - if sz > 0 && size(name) > 0 # looks good, let's have a try - try - font = lv.font_embedded(name, sz) - except .. - end + elif sz > 0 && size(name) > 0 # looks good, let's have a try + try + font = lv.font_embedded(name, sz) + except .. end end end From 3427e1bee324e3d63378a421bfae52d8605ae32a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 8 Oct 2022 16:14:11 +0200 Subject: [PATCH 06/14] Support for Modbus Energy Monitoring devices Support for Modbus Energy Monitoring devices using a rule file. See ``xnrg_29_modbus.ino`` for more information --- CHANGELOG.md | 7 +- RELEASENOTES.md | 8 +- tasmota/tasmota_support/support_features.ino | 4 +- .../tasmota_xnrg_energy/xnrg_29_modbus.ino | 319 ++++++++++++++++-- tools/decode-status.py | 2 +- 5 files changed, 299 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce88c2202..4bf0a61f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,11 @@ All notable changes to this project will be documented in this file. ## [12.1.1.4] ### Added - Support for Shelly Plus 2PM using template ``{"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}`` -- Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints +- Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints (#16718) - Support for QMC5883L magnetic induction sensor by Helge Scheunemann (#16714) -- LVGL/HASPmota add tiny "pixel perfect" fonts for small screens -- HASPmota support for TTF fonts +- LVGL/HASPmota add tiny "pixel perfect" fonts for small screens (#16758) +- HASPmota support for TTF fonts (#16759) +- Support for Modbus Energy Monitoring devices using a rule file. See ``xnrg_29_modbus.ino`` for more information ### Changed - ESP32 LVGL library from v8.3.0 to v8.3.2 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 24224aa94..37b5b91ba 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -124,6 +124,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252) - Zigbee basic support for Green Power [#16407](https://github.com/arendst/Tasmota/issues/16407) - Zigbee friendly names per endpoint +- Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints [#16718](https://github.com/arendst/Tasmota/issues/16718) - Flowrate meter flow amount/duration, show values in table format [#16385](https://github.com/arendst/Tasmota/issues/16385) - Support of optional file calib.dat on ADE7953 based energy monitors like Shelly EM [#16486](https://github.com/arendst/Tasmota/issues/16486) - Support for Ethernet in ESP32 safeboot firmware [#16388](https://github.com/arendst/Tasmota/issues/16388) @@ -131,14 +132,17 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - ESP32-S2 and ESP32-S3 touch button support - Berry has persistent MQTT subscriptions: auto-subscribe at (re)connection - Berry automated solidification of code +- LVGL/HASPmota add tiny "pixel perfect" fonts for small screens [#16758](https://github.com/arendst/Tasmota/issues/16758) +- HASPmota support for TTF fonts [#16759](https://github.com/arendst/Tasmota/issues/16759) ### Breaking Changed ### Changed -- ESP32 NimBLE library from v1.3.6 to v1.4.0 - IRremoteESP8266 library from v2.8.2 to v2.8.4 -- Tasmota Core32 from 2.0.4.1 to 2.0.5 - TasmotaModbus library from v3.5.0 to v3.6.0 [#16351](https://github.com/arendst/Tasmota/issues/16351) +- ESP32 NimBLE library from v1.3.6 to v1.4.0 +- ESP32 LVGL library from v8.3.0 to v8.3.2 +- ESP32 Tasmota Core32 from 2.0.4.1 to 2.0.5 - Button debouncing V3 by adopting switch debounce code [#16339](https://github.com/arendst/Tasmota/issues/16339) - Thermostat max allowed temperature from 100 to 200C [#16363](https://github.com/arendst/Tasmota/issues/16363) - Using command ``SerialBuffer`` raise max allowed buffer size to 2048 characters [#16374](https://github.com/arendst/Tasmota/issues/16374) diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino index 54fe47a23..78d972340 100644 --- a/tasmota/tasmota_support/support_features.ino +++ b/tasmota/tasmota_support/support_features.ino @@ -837,7 +837,9 @@ void ResponseAppendFeatures(void) #if defined(USE_I2C) && defined(USE_QMC5883L) feature9 |= 0x00000008; // xsns_33_qmc5882l.ino #endif -// feature9 |= 0x00000010; +#if defined(USE_ENERGY_SENSOR) && defined(USE_MODBUS_ENERGY) + feature9 |= 0x00000010; // xnrg_29_modbus.ino +#endif // feature9 |= 0x00000020; // feature9 |= 0x00000040; // feature9 |= 0x00000080; diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino index d66f269a8..62fdf451a 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino @@ -20,19 +20,64 @@ #ifdef USE_ENERGY_SENSOR #ifdef USE_MODBUS_ENERGY /*********************************************************************************************\ - * Generic Modbus energy meter - experimental (but works on my SDM230) + * Generic Modbus energy meter * - * Using a rule file called modbus allows to easy configure modbus energy monitor devices. + * Using a rule file called modbus allows to easy configure modbus energy monitor devices up to three phases. * - * Works: - * rule3 on file#modbus do {"Name":"SDM230","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"ImportActive":342,"ExportActive":0x004A} endon - * rule3 on file#modbus do {"Name":"SDM230","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0x0000,"Current":0x0006,"Power":0x000C,"ApparentPower":0x0012,"ReactivePower":0x0018,"Factor":0x001E,"Frequency":0x0046,"ImportActive":0x0156,"ExportActive":0x004A} endon + * Value pair description: + * {"Name":"SDM230","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A} + * Modbus config parameters: + * Name - Name of energy monitoring device + * Baud - Baudrate of device modbus interface + * Config - Serial config parameters like 8N1 - 8 databits, No parity, 1 stop bit + * Address - Modbus device address entered as decimal (1) or hexadecimal (0x01)) + * Function - Modbus function code to access two registers + * Tasmota default embedded register names: + * Voltage - Voltage register entered as decimal or hexadecimal for one phase (0x0000) or up to three phases ([0x0000,0x0002,0x0004]) + * Current - Current register entered as decimal or hexadecimal for one phase (0x0006) or up to three phases ([0x0006,0x0008,0x000A]) + * Power - Active power register entered as decimal or hexadecimal for one phase (0x000C) or up to three phases ([0x000C,0x000E,0x0010]) + * ApparentPower - Apparent power register entered as decimal or hexadecimal for one phase (0x000C) or up to three phases ([0x000C,0x000E,0x0010]) + * ReactivePower - Reactive power register entered as decimal or hexadecimal for one phase (0x0018) or up to three phases ([0x0018,0x001A,0x001C]) + * Factor - Power factor register entered as decimal or hexadecimal for one phase (0x001E) or up to three phases ([0x001E,0x0020,0x0022]) + * Frequency - Frequency register entered as decimal or hexadecimal for one phase (0x0046) or up to three phases ([0x0046,0x0048,0x004A]) + * Total - Total active energy register entered as decimal or hexadecimal for one phase (0x0156) or up to three phases ([0x015A,0x015C,0x015E]) + * ExportActive - Export active energy register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164]) + * Optional user defined registers: + * User - Additional user defined registers + * Value pair description: + * "User":{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2} + * R - Modbus register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164]) + * J - JSON register name (preferrably without spaces like "PhaseAngle") + * G - GUI register name + * U - GUI unit name + * D - Number of decimals for floating point presentation * + * Example using default Energy registers: + * rule3 on file#modbus do {"Name":"SDM230","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A} endon + * rule3 on file#modbus do {"Name":"SDM230 with hex registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0x0000,"Current":0x0006,"Power":0x000C,"ApparentPower":0x0012,"ReactivePower":0x0018,"Factor":0x001E,"Frequency":0x0046,"Total":0x0156,"ExportActive":0x004A} endon + * + * Example using default Energy registers and some user defined registers: + * rule3 on file#modbus do {"Name":"SDM230 with one user register","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}} endon + * rule3 on file#modbus do {"Name":"SDM230 with two user registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon + * + * Note: + * - To enter long rules using a serial console and solve error "Serial buffer overrun" you might need to enlarge the serial input buffer with command serialbuffer 512. + * - Changes to rule file are only executed on restart + * + * Restrictions: + * - Supports Modbus floating point registers + * - Max number of uer defined registers is defined by one rule buffer (511 characters uncompressed, around 800 characters compressed) + * + * To do: + * - Support all three rule slots + * - Support other modbus register like integers * * Test set: - * rule3 on file#modbus do {"Name":"SDM230 test1","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":[70,70,70],"ImportActive":[342,342,342]} endon - * rule3 on file#modbus do {"Name":"SDM230 test2","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"ImportActive":[342,342,342]} endon - * rule3 on file#modbus do {"Name":"SDM230 test3","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"ImportActive":[342,342,342]} endon + * rule3 on file#modbus do {"Name":"SDM230 test1","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":[70,70,70],"Total":[342,342,342]} endon + * rule3 on file#modbus do {"Name":"SDM230 test2","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"Total":[342,342,342]} endon + * rule3 on file#modbus do {"Name":"SDM230 test3","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"Total":[342,342,342]} endon + * rule3 on file#modbus do {"Name":"SDM230 test4","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":[0x004E,0x004E,0x004E],"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon + * rule3 on file#modbus do {"Name":"SDM230 test5","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":[0x004E,0x004E,0x004E],"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon \*********************************************************************************************/ #define XNRG_29 29 @@ -53,7 +98,7 @@ enum EnergyModbusRegisters { NRG_MBS_VOLTAGE, NRG_MBS_REACTIVE_POWER, NRG_MBS_POWER_FACTOR, NRG_MBS_FREQUENCY, - NRG_MBS_IMPORT_ACTIVE_ENERGY, + NRG_MBS_TOTAL_ENERGY, NRG_MBS_EXPORT_ACTIVE_ENERGY, NRG_MBS_MAX_REGS }; @@ -64,7 +109,7 @@ const char kEnergyModbusValues[] PROGMEM = D_JSON_VOLTAGE "|" // Vo D_JSON_REACTIVE_POWERUSAGE "|" // ReactivePower D_JSON_POWERFACTOR "|" // Factor D_JSON_FREQUENCY "|" // Frequency - D_JSON_IMPORT_ACTIVE "|" // ImportActive + D_JSON_TOTAL "|" // Total D_JSON_EXPORT_ACTIVE "|" // ExportActive ; @@ -77,14 +122,30 @@ struct NRGMODBUS { uint16_t register_address[NRG_MBS_MAX_REGS][ENERGY_MAX_PHASES]; uint8_t device_address; uint8_t function; + uint8_t user_adds; uint8_t phase; uint8_t state; uint8_t retry; + bool mutex; } *NrgModbus = nullptr; +typedef struct NRGMODBUSUSER { + float register_data[ENERGY_MAX_PHASES]; + uint16_t register_address[ENERGY_MAX_PHASES]; + uint8_t resolution; + String json_name; + String gui_name; + String gui_unit; +} NrgModbusUser_t; +NrgModbusUser_t* NrgModbusUser = nullptr; + /*********************************************************************************************/ void EnergyModbusLoop(void) { + if (NrgModbus->mutex) { return; } + NrgModbus->mutex = 1; + + uint16_t register_address; bool data_ready = EnergyModbus->ReceiveReady(); if (data_ready) { @@ -148,12 +209,16 @@ void EnergyModbusLoop(void) { case NRG_MBS_FREQUENCY: Energy.frequency[NrgModbus->phase] = value; // 50.0 Hz break; - case NRG_MBS_IMPORT_ACTIVE_ENERGY: + case NRG_MBS_TOTAL_ENERGY: Energy.import_active[NrgModbus->phase] = value; // 6.216 kWh => used in EnergyUpdateTotal() break; case NRG_MBS_EXPORT_ACTIVE_ENERGY: Energy.export_active[NrgModbus->phase] = value; // 478.492 kWh break; + default: + if (NrgModbusUser) { + NrgModbusUser[NrgModbus->state - NRG_MBS_MAX_REGS].register_data[NrgModbus->phase] = value; + } } do { @@ -161,25 +226,94 @@ void EnergyModbusLoop(void) { if (NrgModbus->phase == Energy.phase_count) { NrgModbus->phase = 0; NrgModbus->state++; - if (NrgModbus->state == NRG_MBS_MAX_REGS) { + if (NrgModbus->state == NRG_MBS_MAX_REGS + NrgModbus->user_adds) { NrgModbus->state = 0; NrgModbus->phase = 0; EnergyUpdateTotal(); // update every cycle after all registers have been read break; } } - } while (NrgModbus->register_address[NrgModbus->state][NrgModbus->phase] == nrg_mbs_reg_not_used); + delay(0); + register_address = (NrgModbus->state < NRG_MBS_MAX_REGS) ? NrgModbus->register_address[NrgModbus->state][NrgModbus->phase] : + NrgModbusUser[NrgModbus->state - NRG_MBS_MAX_REGS].register_address[NrgModbus->phase]; + } while (register_address == nrg_mbs_reg_not_used); } } // end data ready if (0 == NrgModbus->retry || data_ready) { NrgModbus->retry = 5; - EnergyModbus->Send(NrgModbus->device_address, NrgModbus->function, NrgModbus->register_address[NrgModbus->state][NrgModbus->phase], 2); + register_address = (NrgModbus->state < NRG_MBS_MAX_REGS) ? NrgModbus->register_address[NrgModbus->state][NrgModbus->phase] : + NrgModbusUser[NrgModbus->state - NRG_MBS_MAX_REGS].register_address[NrgModbus->phase]; + EnergyModbus->Send(NrgModbus->device_address, NrgModbus->function, register_address, 2); } else { NrgModbus->retry--; } + NrgModbus->mutex = 0; } +#ifdef USE_RULES +bool EnergyModbusReadUserRegisters(JsonParserObject user_add_value, uint32_t add_index) { + // {"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3} + JsonParserToken val; + val = user_add_value[PSTR("R")]; // Register address + uint32_t phase = 0; + if (val.isArray()) { + JsonParserArray address_arr = val.getArray(); + for (auto value : address_arr) { + NrgModbusUser[add_index].register_address[phase] = value.getUInt(); + phase++; + if (phase == ENERGY_MAX_PHASES) { break; } + } + } else if (val) { + NrgModbusUser[add_index].register_address[0] = val.getUInt(); + phase++; + } else { + return false; + } + if (phase > Energy.phase_count) { + Energy.phase_count = phase; + } + val = user_add_value[PSTR("J")]; // JSON value name + if (val) { + NrgModbusUser[add_index].json_name = val.getStr(); + } else { + return false; + } + val = user_add_value[PSTR("G")]; // GUI value name + if (val) { + NrgModbusUser[add_index].gui_name = val.getStr(); + } else { + return false; + } + val = user_add_value[PSTR("U")]; // GUI value Unit + if (val) { + NrgModbusUser[add_index].gui_unit = val.getStr(); + } else { + return false; + } + val = user_add_value[PSTR("D")]; // Decimal resolution + if (val) { + NrgModbusUser[add_index].resolution = val.getUInt(); + } else { + return false; + } + +#ifdef ENERGY_MODBUS_DEBUG + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], J '%s', G '%s', U '%s', D %d"), + add_index, + NrgModbusUser[add_index].register_address[0], + NrgModbusUser[add_index].register_address[1], + NrgModbusUser[add_index].register_address[2], + NrgModbusUser[add_index].json_name.c_str(), + NrgModbusUser[add_index].gui_name.c_str(), + NrgModbusUser[add_index].gui_unit.c_str(), + NrgModbusUser[add_index].resolution); +#endif + + return true; +} +#endif // USE_RULES + bool EnergyModbusReadRegisters(void) { #ifdef USE_RULES String modbus = RuleLoadFile("MODBUS"); @@ -196,8 +330,8 @@ bool EnergyModbusReadRegisters(void) { JsonParserObject root = parser.getRootObject(); if (!root) { return false; } // Invalid JSON - NrgModbus = (NRGMODBUS *)calloc(sizeof(struct NRGMODBUS), 1); - if (NrgModbus == nullptr) { return false; } // Unable to allocate variabvles on heap + NrgModbus = (NRGMODBUS *)calloc(1, sizeof(struct NRGMODBUS)); + if (NrgModbus == nullptr) { return false; } // Unable to allocate variables on heap // Init defaults NrgModbus->serial_bps = ENERGY_MODBUS_SPEED; @@ -222,32 +356,33 @@ bool EnergyModbusReadRegisters(void) { } val = root[PSTR("Address")]; if (val) { - NrgModbus->device_address = val.getInt(); // 1 + NrgModbus->device_address = val.getUInt(); // 1 } val = root[PSTR("Function")]; if (val) { - NrgModbus->function = val.getInt(); // 4 + NrgModbus->function = val.getUInt(); // 4 } char register_name[32]; - uint32_t phase; Energy.voltage_available = false; // Disable voltage is measured Energy.current_available = false; // Disable current is measured for (uint32_t names = 0; names < NRG_MBS_MAX_REGS; names++) { - phase = 0; val = root[GetTextIndexed(register_name, sizeof(register_name), names, kEnergyModbusValues)]; - if (val.isArray()) { - JsonParserArray arr = val.getArray(); - for (auto value : arr) { - NrgModbus->register_address[names][phase] = value.getUInt(); + if (val) { + // "Voltage":0 + // "Voltage":[0,0,0] + uint32_t phase = 0; + if (val.isArray()) { + JsonParserArray arr = val.getArray(); + for (auto value : arr) { + NrgModbus->register_address[names][phase] = value.getUInt(); + phase++; + if (phase == ENERGY_MAX_PHASES) { break; } + } + } else if (val) { + NrgModbus->register_address[names][0] = val.getUInt(); phase++; - if (phase == ENERGY_MAX_PHASES) { break; } } - } else if (val) { - NrgModbus->register_address[names][phase] = val.getUInt(); - phase++; - } - if (phase) { if (phase > Energy.phase_count) { Energy.phase_count = phase; } @@ -266,14 +401,65 @@ bool EnergyModbusReadRegisters(void) { Energy.frequency_common = true; // Use common frequency } break; - case NRG_MBS_IMPORT_ACTIVE_ENERGY: + case NRG_MBS_TOTAL_ENERGY: Settings->flag3.hardware_energy_total = 1; // SetOption72 - Enable hardware energy total counter as reference (#6561) break; } + +#ifdef ENERGY_MODBUS_DEBUG + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X]"), + names, + NrgModbus->register_address[names][0], + NrgModbus->register_address[names][1], + NrgModbus->register_address[names][2]); +#endif + } } + + NrgModbus->user_adds = 0; + // "User":{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3} + // "User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}] + val = root[PSTR("User")]; + if (val) { + NrgModbus->user_adds = 1; + if (val.isArray()) { + NrgModbus->user_adds = val.size(); + } + NrgModbusUser = (NrgModbusUser_t*)calloc(NrgModbus->user_adds, sizeof(NrgModbusUser_t)); + if (NrgModbusUser) { + // Init defaults + for (uint32_t i = 0; i < NrgModbus->user_adds; i++) { + for (uint32_t j = 0; j < ENERGY_MAX_PHASES; j++) { + NrgModbusUser[i].register_address[j] = nrg_mbs_reg_not_used; + NrgModbusUser[i].register_data[j] = NAN; + } + } + if (val.isArray()) { + JsonParserArray user_adds_arr = val.getArray(); + uint32_t add_index = 0; + for (auto user_add_values : user_adds_arr) { + if (!user_add_values.isObject()) { break; } + if (EnergyModbusReadUserRegisters(user_add_values.getObject(), add_index)) { + add_index++; + } else { + NrgModbus->user_adds--; + } + } + } else if (val) { + if (val.isObject()) { + if (!EnergyModbusReadUserRegisters(val.getObject(), 0)) { + NrgModbus->user_adds--; + } + } + } + } else { + NrgModbus->user_adds = 0; + } + } + #ifdef ENERGY_MODBUS_DEBUG - AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Registers %*_H"), sizeof(NrgModbus->register_address), NrgModbus->register_address); + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: RAM usage %d + %d"), sizeof(struct NRGMODBUS), NrgModbus->user_adds * sizeof(NrgModbusUser_t)); #endif // NrgModbus->state = 0; // Set by calloc() @@ -310,6 +496,60 @@ void EnergyModbusDrvInit(void) { } } +/*********************************************************************************************\ + * Additional presentation +\*********************************************************************************************/ + +void EnergyModbusReset(void) { + for (uint32_t i = 0; i < NrgModbus->user_adds; i++) { + for (uint32_t j = 0; j < ENERGY_MAX_PHASES; j++) { + if (NrgModbusUser[i].register_address[0] != nrg_mbs_reg_not_used) { + NrgModbusUser[i].register_data[j] = 0; + } + } + } +} + +void EnergyModbusShow(bool json) { + char value_chr[TOPSZ]; + for (uint32_t i = 0; i < NrgModbus->user_adds; i++) { +/* +#ifdef ENERGY_MODBUS_DEBUG + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], J '%s', G '%s', U '%s', D %d, V [%3_f,%3_f,%3_f]"), + i, + NrgModbusUser[i].register_address[0], + NrgModbusUser[i].register_address[1], + NrgModbusUser[i].register_address[2], + NrgModbusUser[i].json_name.c_str(), + NrgModbusUser[i].gui_name.c_str(), + NrgModbusUser[i].gui_unit.c_str(), + NrgModbusUser[i].resolution, + &NrgModbusUser[i].register_data[0], + &NrgModbusUser[i].register_data[1], + &NrgModbusUser[i].register_data[2]); +#endif +*/ + if ((NrgModbusUser[i].register_address[0] != nrg_mbs_reg_not_used) && !isnan(NrgModbusUser[i].register_data[0])) { + float values[ENERGY_MAX_PHASES]; + for (uint32_t j = 0; j < ENERGY_MAX_PHASES; j++) { + values[j] = NrgModbusUser[i].register_data[j]; + } + if (json) { + ResponseAppend_P(PSTR(",\"%s\":%s"), + NrgModbusUser[i].json_name.c_str(), + EnergyFormat(value_chr, values, NrgModbusUser[i].resolution)); +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(PSTR("{s}%s{m}%s %s{e}"), + NrgModbusUser[i].gui_name.c_str(), + WebEnergyFormat(value_chr, values, NrgModbusUser[i].resolution), + NrgModbusUser[i].gui_unit.c_str()); +#endif // USE_WEBSERVER + } + } + } +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -318,12 +558,23 @@ bool Xnrg29(uint8_t function) { bool result = false; switch (function) { -// case FUNC_EVERY_250_MSECOND: case FUNC_EVERY_200_MSECOND: EnergyModbusLoop(); break; + case FUNC_JSON_APPEND: + EnergyModbusShow(1); + break; +#ifdef USE_WEBSERVER +#ifdef USE_ENERGY_COLUMN_GUI + case FUNC_WEB_COL_SENSOR: +#else // not USE_ENERGY_COLUMN_GUI + case FUNC_WEB_SENSOR: +#endif // USE_ENERGY_COLUMN_GUI + EnergyModbusShow(0); + break; +#endif // USE_WEBSERVER case FUNC_ENERGY_RESET: -// EnergyModbusReset(); + EnergyModbusReset(); break; case FUNC_INIT: EnergyModbusSnsInit(); diff --git a/tools/decode-status.py b/tools/decode-status.py index 32afcd966..d076f11a2 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -287,7 +287,7 @@ a_features = [[ "USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF" ],[ "USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L", - "","","","", + "USE_MODBUS_ENERGY","","","", "","","","", "","","","", "","","","", From 36ed0cba7d7eeb35852069c19e7a9f7137c30175 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 8 Oct 2022 17:17:15 +0200 Subject: [PATCH 07/14] Add tasmota resolution option to energy modbus --- .../tasmota_xnrg_energy/xnrg_29_modbus.ino | 83 +++++++++++++++---- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino index 62fdf451a..7e77a6aef 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino @@ -44,24 +44,34 @@ * ExportActive - Export active energy register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164]) * Optional user defined registers: * User - Additional user defined registers - * Value pair description: - * "User":{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2} - * R - Modbus register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164]) - * J - JSON register name (preferrably without spaces like "PhaseAngle") - * G - GUI register name - * U - GUI unit name - * D - Number of decimals for floating point presentation + * Value pair description: + * "User":{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2} + * R - Modbus register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164]) + * J - JSON register name (preferrably without spaces like "PhaseAngle") + * G - GUI register name + * U - GUI unit name + * D - Number of decimals for floating point presentation or a code correspondig to Tasmota resolution command settings: + * 21 - VoltRes (V) + * 22 - AmpRes (A) + * 23 - WattRes (W, VA, VAr) + * 24 - EnergyRes (kWh, kVAh, kVArh) + * 25 - FreqRes (Hz) + * 26 - TempRes (C, F) + * 27 - HumRes (%) + * 28 - PressRes (hPa, mmHg) + * 29 - WeightRes (Kg) * * Example using default Energy registers: * rule3 on file#modbus do {"Name":"SDM230","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A} endon * rule3 on file#modbus do {"Name":"SDM230 with hex registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0x0000,"Current":0x0006,"Power":0x000C,"ApparentPower":0x0012,"ReactivePower":0x0018,"Factor":0x001E,"Frequency":0x0046,"Total":0x0156,"ExportActive":0x004A} endon + * rule3 on file#modbus do {"Name":"SDM72","Baud":9600,"Config":8N1","Address":0x01,"Function":0x04,"Power":0x0034,"Total":0x0156,"ExportActive":0x004A,"User":[{"R":0x0502,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x0502,"J":"ExportPower","G":"Export Power","U":"W","D":23},{"R":0x0500,"J":"ImportPower","G":"Import Power","U":"W","D":23}]} endon * * Example using default Energy registers and some user defined registers: * rule3 on file#modbus do {"Name":"SDM230 with one user register","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}} endon * rule3 on file#modbus do {"Name":"SDM230 with two user registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon * * Note: - * - To enter long rules using a serial console and solve error "Serial buffer overrun" you might need to enlarge the serial input buffer with command serialbuffer 512. + * - To enter long rules using the serial console and solve error "Serial buffer overrun" you might need to enlarge the serial input buffer with command serialbuffer 512 * - Changes to rule file are only executed on restart * * Restrictions: @@ -76,7 +86,7 @@ * rule3 on file#modbus do {"Name":"SDM230 test1","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":[70,70,70],"Total":[342,342,342]} endon * rule3 on file#modbus do {"Name":"SDM230 test2","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"Total":[342,342,342]} endon * rule3 on file#modbus do {"Name":"SDM230 test3","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"Total":[342,342,342]} endon - * rule3 on file#modbus do {"Name":"SDM230 test4","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":[0x004E,0x004E,0x004E],"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon + * rule3 on file#modbus do {"Name":"SDM230 test4","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon * rule3 on file#modbus do {"Name":"SDM230 test5","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":[0x004E,0x004E,0x004E],"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon \*********************************************************************************************/ @@ -88,9 +98,20 @@ #define ENERGY_MODBUS_FUNC 0x04 // default Modbus function code //#define ENERGY_MODBUS_DEBUG +//#define ENERGY_MODBUS_DEBUG_SHOW const uint16_t nrg_mbs_reg_not_used = 1; // Odd number 1 is unused register +enum EnergyModbusResolutions { NRG_RES_VOLTAGE = 21, // V + NRG_RES_CURRENT, // A + NRG_RES_POWER, // W, VA, VAr + NRG_RES_ENERGY, // kWh, kVAh, kVArh + NRG_RES_FREQUENCY, // Hz + NRG_RES_TEMPERATURE, // C, F + NRG_RES_HUMIDITY, // % + NRG_RES_PRESSURE, // hPa, mmHg + NRG_RES_WEIGHT }; // Kg + enum EnergyModbusRegisters { NRG_MBS_VOLTAGE, NRG_MBS_CURRENT, NRG_MBS_ACTIVE_POWER, @@ -510,11 +531,37 @@ void EnergyModbusReset(void) { } } +uint32_t EnergyModbusResolution(uint32_t resolution) { + if (resolution >= NRG_RES_VOLTAGE) { + switch (resolution) { + case NRG_RES_VOLTAGE: + return Settings->flag2.voltage_resolution; + case NRG_RES_CURRENT: + return Settings->flag2.current_resolution; + case NRG_RES_POWER: + return Settings->flag2.wattage_resolution; + case NRG_RES_ENERGY: + return Settings->flag2.energy_resolution; + case NRG_RES_FREQUENCY: + return Settings->flag2.frequency_resolution; + case NRG_RES_TEMPERATURE: + return Settings->flag2.temperature_resolution; + case NRG_RES_HUMIDITY: + return Settings->flag2.humidity_resolution; + case NRG_RES_PRESSURE: + return Settings->flag2.pressure_resolution; + case NRG_RES_WEIGHT: + return Settings->flag2.weight_resolution; + } + } + return resolution; +} + void EnergyModbusShow(bool json) { char value_chr[TOPSZ]; for (uint32_t i = 0; i < NrgModbus->user_adds; i++) { -/* -#ifdef ENERGY_MODBUS_DEBUG + +#ifdef ENERGY_MODBUS_DEBUG_SHOW AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], J '%s', G '%s', U '%s', D %d, V [%3_f,%3_f,%3_f]"), i, NrgModbusUser[i].register_address[0], @@ -528,21 +575,25 @@ void EnergyModbusShow(bool json) { &NrgModbusUser[i].register_data[1], &NrgModbusUser[i].register_data[2]); #endif -*/ + if ((NrgModbusUser[i].register_address[0] != nrg_mbs_reg_not_used) && !isnan(NrgModbusUser[i].register_data[0])) { float values[ENERGY_MAX_PHASES]; for (uint32_t j = 0; j < ENERGY_MAX_PHASES; j++) { values[j] = NrgModbusUser[i].register_data[j]; } + uint32_t resolution = EnergyModbusResolution(NrgModbusUser[i].resolution); + +#ifdef ENERGY_MODBUS_DEBUG_SHOW + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: resolution %d -> %d"), NrgModbusUser[i].resolution, resolution); +#endif + if (json) { - ResponseAppend_P(PSTR(",\"%s\":%s"), - NrgModbusUser[i].json_name.c_str(), - EnergyFormat(value_chr, values, NrgModbusUser[i].resolution)); + ResponseAppend_P(PSTR(",\"%s\":%s"), NrgModbusUser[i].json_name.c_str(), EnergyFormat(value_chr, values, resolution)); #ifdef USE_WEBSERVER } else { WSContentSend_PD(PSTR("{s}%s{m}%s %s{e}"), NrgModbusUser[i].gui_name.c_str(), - WebEnergyFormat(value_chr, values, NrgModbusUser[i].resolution), + WebEnergyFormat(value_chr, values, resolution), NrgModbusUser[i].gui_unit.c_str()); #endif // USE_WEBSERVER } From e0a2a0928d167ba5738fb07459d67e9d128f3cdb Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 9 Oct 2022 14:59:15 +0200 Subject: [PATCH 08/14] Zigbee plugin allow matches to 'starts wth' --- .../xdrv_23_zigbee_5_1_attributes.ino | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino index 78f02b561..75f2537c2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino @@ -342,18 +342,43 @@ public: manufacturer = (const char*)_manuf; } + // check if a matches b, return true if so + // + // Special behavior: + // - return true if `a` is empty or null + // - return false if `b` is null + // - matches start of `a` if `a` ends with `'*'` + // - exact match otherwise + static bool matchStar(const char *_a, const char *_b) { + if (_a == nullptr || *_a == '\0') { return true; } + if (_b == nullptr) { return false; } + + const char *a = _a; + const char *b = _b; + while (1) { + if (a[0] == '*' && a[1] == '\0') { // pattern ends with '*' + return true; // matches worked until now, accept match + } + if (*a != *b) { + return false; + } + if (*a == '\0') { + return true; + } + a++; + b++; + } + } + bool match(const char *match_model, const char *match_manuf) const { bool match = true; - if (model.length() > 0) { - if (!model.equals(match_model)) { - match = false; - } + if (!matchStar(model.c_str(), match_model)) { + match = false; } - if (manufacturer.length() > 0) { - if (!manufacturer.equals(match_manuf)) { + if (!matchStar(manufacturer.c_str(), match_manuf)) { match = false; - } } + // AddLog(LOG_LEVEL_DEBUG, ">match device(%s, %s) compared to (%s, %s) = %i", match_model, match_manuf, model.c_str(), manufacturer.c_str(), match); return match; } From 4f4c6dd150b33cc7b6322417c74433b468699a8a Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 9 Oct 2022 15:02:14 +0200 Subject: [PATCH 09/14] Zigbee plugin for TS0001 switches --- tasmota/zigbee/TS0001_switch.zb | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tasmota/zigbee/TS0001_switch.zb diff --git a/tasmota/zigbee/TS0001_switch.zb b/tasmota/zigbee/TS0001_switch.zb new file mode 100644 index 000000000..f63766bf0 --- /dev/null +++ b/tasmota/zigbee/TS0001_switch.zb @@ -0,0 +1,4 @@ +#Z2Tv1 +# TuYa generic switch https://www.zigbee2mqtt.io/devices/TS0001_switch_module.html +:TS0001,_TZ3000_* +0006/8002%30,StartUpOnOff \ No newline at end of file From 79896fcd3e3bcec332bd58aa576be6bff82e374c Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 9 Oct 2022 15:03:30 +0200 Subject: [PATCH 10/14] Add trailing cr --- tasmota/zigbee/TS0001_switch.zb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/zigbee/TS0001_switch.zb b/tasmota/zigbee/TS0001_switch.zb index f63766bf0..38f0162a3 100644 --- a/tasmota/zigbee/TS0001_switch.zb +++ b/tasmota/zigbee/TS0001_switch.zb @@ -1,4 +1,4 @@ #Z2Tv1 # TuYa generic switch https://www.zigbee2mqtt.io/devices/TS0001_switch_module.html :TS0001,_TZ3000_* -0006/8002%30,StartUpOnOff \ No newline at end of file +0006/8002%30,StartUpOnOff From 409c9888dda6f59a02c24fa6ebb93cf9a75bd921 Mon Sep 17 00:00:00 2001 From: sfromis <47082390+sfromis@users.noreply.github.com> Date: Sun, 9 Oct 2022 16:09:29 +0200 Subject: [PATCH 11/14] Epoch in Berry map for time Uses mktime to calculate the epoch value from the broken-down time structure, could potentially be tuned if deemed too inefficient in case of the caller already having the epoch value nearby. --- tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino index a90a25916..31206442d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino @@ -265,6 +265,7 @@ extern "C" { be_map_insert_int(vm, "min", t->tm_min); be_map_insert_int(vm, "sec", t->tm_sec); be_map_insert_int(vm, "weekday", t->tm_wday); + be_map_insert_int(vm, "epoch", mktime(t)); if (unparsed) be_map_insert_str(vm, "unparsed", unparsed); be_pop(vm, 1); } From 4a3a52cd3eb4a1ac805d00897af635cf8accf7a9 Mon Sep 17 00:00:00 2001 From: sfromis <47082390+sfromis@users.noreply.github.com> Date: Sun, 9 Oct 2022 16:12:16 +0200 Subject: [PATCH 12/14] Epoch in Berry map for time Inserts input epoch value directly into the output map, for consistently having epoch in this data structure --- lib/libesp32/berry/src/be_timelib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libesp32/berry/src/be_timelib.c b/lib/libesp32/berry/src/be_timelib.c index 7b779aa36..a7938e4b7 100644 --- a/lib/libesp32/berry/src/be_timelib.c +++ b/lib/libesp32/berry/src/be_timelib.c @@ -37,6 +37,7 @@ static int m_dump(bvm *vm) time_insert(vm, "min", t->tm_min); time_insert(vm, "sec", t->tm_sec); time_insert(vm, "weekday", t->tm_wday); + time_insert(vm, "epoch", ts); be_pop(vm, 1); be_return(vm); } From 2d15697de46cb87fd7ec0107b80414872eb42c87 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 9 Oct 2022 17:59:27 +0200 Subject: [PATCH 13/14] Increase serial console fixed input buffer size from 520 to 800 --- CHANGELOG.md | 1 + tasmota/include/tasmota.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bf0a61f3..da4e5c951 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 LVGL library from v8.3.0 to v8.3.2 +- Increase serial console fixed input buffer size from 520 to 800 ### Fixed diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index 02949ce9e..1271c64a3 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -196,8 +196,9 @@ const uint8_t OTA_ATTEMPTS = 10; // Number of times to try fetching t const uint8_t OTA_ATTEMPTS = 5; // Number of times to try fetching the new firmware #endif // ESP8266 -const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in Tasmota serial command buffer -const uint16_t MIN_INPUT_BUFFER_SIZE = 256; // Max number of characters in Tasmota serial command buffer +//const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in Tasmota serial command buffer +const uint16_t INPUT_BUFFER_SIZE = 800; // Max number of characters in Tasmota serial command buffer +const uint16_t MIN_INPUT_BUFFER_SIZE = 256; // Max number of characters in Tasmota serial command buffer const uint16_t MAX_INPUT_BUFFER_SIZE = 2048; // Max number of characters in Arduino serial command buffer const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32) const uint16_t CMDSZ = 24; // Max number of characters in command From 3c258f4e31b7566ace256895ec3794299a5f4434 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:38:30 +0200 Subject: [PATCH 14/14] Try to fix energy modbus warchdogs --- .../tasmota_xnrg_energy/xnrg_29_modbus.ino | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino index 7e77a6aef..510e96e56 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino @@ -64,14 +64,16 @@ * Example using default Energy registers: * rule3 on file#modbus do {"Name":"SDM230","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A} endon * rule3 on file#modbus do {"Name":"SDM230 with hex registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0x0000,"Current":0x0006,"Power":0x000C,"ApparentPower":0x0012,"ReactivePower":0x0018,"Factor":0x001E,"Frequency":0x0046,"Total":0x0156,"ExportActive":0x004A} endon - * rule3 on file#modbus do {"Name":"SDM72","Baud":9600,"Config":8N1","Address":0x01,"Function":0x04,"Power":0x0034,"Total":0x0156,"ExportActive":0x004A,"User":[{"R":0x0502,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x0502,"J":"ExportPower","G":"Export Power","U":"W","D":23},{"R":0x0500,"J":"ImportPower","G":"Import Power","U":"W","D":23}]} endon + * rule3 on file#modbus do {"Name":"DDSU666","Baud":9600,"Config":8N1","Address":1,"Function":4,"Voltage":0x2000,"Current":0x2002,"Power":0x2004,"ReactivePower":0x2006,"Factor":0x200A,"Frequency":0x200E,"Total":0x4000,"ExportActive":0x400A} endon * * Example using default Energy registers and some user defined registers: - * rule3 on file#modbus do {"Name":"SDM230 with one user register","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}} endon + * rule3 on file#modbus do {"Name":"SDM72","Baud":9600,"Config":8N1","Address":0x01,"Function":0x04,"Power":0x0034,"Total":0x0156,"ExportActive":0x004A,"User":[{"R":0x0502,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x0502,"J":"ExportPower","G":"Export Power","U":"W","D":23},{"R":0x0500,"J":"ImportPower","G":"Import Power","U":"W","D":23}]} endon + * rule3 on file#modbus do {"Name":"SDM120","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x0048,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x004C,"J":"ImportReactive","G":"Import Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon * rule3 on file#modbus do {"Name":"SDM230 with two user registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon + * rule3 on file#modbus do {"Name":"SDM630","Baud":9600,"Config":8N1","Address":1,"Function":4,"Voltage":[0,2,4],"Current":[6,8,10],"Power":[12,14,16],"ApparentPower":[18,20,22],"ReactivePower":[24,26,28],"Factor":[30,32,34],"Frequency":70,"Total":342,"ExportActive":[352,354,356],"User":{"R":[346,348,350],"J":"ImportActive","G":"Import Active","U":"kWh","D":24}} endon * * Note: - * - To enter long rules using the serial console and solve error "Serial buffer overrun" you might need to enlarge the serial input buffer with command serialbuffer 512 + * - To enter long rules using the serial console and solve error "Serial buffer overrun" you might need to enlarge the serial input buffer with command serialbuffer 800 * - Changes to rule file are only executed on restart * * Restrictions: @@ -88,14 +90,18 @@ * rule3 on file#modbus do {"Name":"SDM230 test3","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":[6,6,6],"Power":[12,12,12],"ApparentPower":[18,18,18],"ReactivePower":[24,24,24],"Factor":[30,30,30],"Frequency":70,"Total":[342,342,342]} endon * rule3 on file#modbus do {"Name":"SDM230 test4","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon * rule3 on file#modbus do {"Name":"SDM230 test5","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":[0,0,0],"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":[0x004E,0x004E,0x004E],"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon + * rule3 on file#modbus do {"Name":"SDM120 test1","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x0048,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x004C,"J":"ImportReactive","G":"Import Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon \*********************************************************************************************/ #define XNRG_29 29 -#define ENERGY_MODBUS_SPEED 9600 // default Modbus baudrate -#define ENERGY_MODBUS_CONFIG TS_SERIAL_8N1 -#define ENERGY_MODBUS_ADDR 1 // default Modbus device_address -#define ENERGY_MODBUS_FUNC 0x04 // default Modbus function code +#define ENERGY_MODBUS_SPEED 9600 // Default Modbus baudrate +#define ENERGY_MODBUS_CONFIG TS_SERIAL_8N1 // Default Modbus serial configuration +#define ENERGY_MODBUS_ADDR 1 // Default Modbus device_address +#define ENERGY_MODBUS_FUNC 0x04 // Default Modbus function code + +#define ENERGY_MODBUS_UNITS "" // Default user GUI unit +#define ENERGY_MODBUS_DECIMALS 0 // Default user decimal resolution //#define ENERGY_MODBUS_DEBUG //#define ENERGY_MODBUS_DEBUG_SHOW @@ -136,6 +142,8 @@ const char kEnergyModbusValues[] PROGMEM = D_JSON_VOLTAGE "|" // Vo #include TasmotaModbus *EnergyModbus; +#include +Ticker ticker_energy_modbus; struct NRGMODBUS { uint32_t serial_bps; @@ -164,14 +172,16 @@ NrgModbusUser_t* NrgModbusUser = nullptr; void EnergyModbusLoop(void) { if (NrgModbus->mutex) { return; } + +// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: EnergyModbusLoop() entry")); + NrgModbus->mutex = 1; uint16_t register_address; bool data_ready = EnergyModbus->ReceiveReady(); if (data_ready) { - uint8_t buffer[14]; // At least 5 + (2 * 2) = 9 - + uint8_t buffer[9]; // At least 5 + (2 * 2) = 9 uint32_t error = EnergyModbus->ReceiveBuffer(buffer, 2); AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NRG: Modbus register %d, phase %d, rcvd %*_H"), @@ -244,10 +254,10 @@ void EnergyModbusLoop(void) { do { NrgModbus->phase++; - if (NrgModbus->phase == Energy.phase_count) { + if (NrgModbus->phase >= Energy.phase_count) { NrgModbus->phase = 0; NrgModbus->state++; - if (NrgModbus->state == NRG_MBS_MAX_REGS + NrgModbus->user_adds) { + if (NrgModbus->state >= NRG_MBS_MAX_REGS + NrgModbus->user_adds) { NrgModbus->state = 0; NrgModbus->phase = 0; EnergyUpdateTotal(); // update every cycle after all registers have been read @@ -262,14 +272,23 @@ void EnergyModbusLoop(void) { } // end data ready if (0 == NrgModbus->retry || data_ready) { - NrgModbus->retry = 5; + NrgModbus->retry = 1; register_address = (NrgModbus->state < NRG_MBS_MAX_REGS) ? NrgModbus->register_address[NrgModbus->state][NrgModbus->phase] : NrgModbusUser[NrgModbus->state - NRG_MBS_MAX_REGS].register_address[NrgModbus->phase]; EnergyModbus->Send(NrgModbus->device_address, NrgModbus->function, register_address, 2); } else { NrgModbus->retry--; + +#ifdef ENERGY_MODBUS_DEBUG + AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Modbus state %d retry %d"), NrgModbus->state, NrgModbus->retry); +#endif + } + delay(0); NrgModbus->mutex = 0; + +// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: EnergyModbusLoop() exit")); + } #ifdef USE_RULES @@ -283,7 +302,7 @@ bool EnergyModbusReadUserRegisters(JsonParserObject user_add_value, uint32_t add for (auto value : address_arr) { NrgModbusUser[add_index].register_address[phase] = value.getUInt(); phase++; - if (phase == ENERGY_MAX_PHASES) { break; } + if (phase >= ENERGY_MAX_PHASES) { break; } } } else if (val) { NrgModbusUser[add_index].register_address[0] = val.getUInt(); @@ -306,17 +325,15 @@ bool EnergyModbusReadUserRegisters(JsonParserObject user_add_value, uint32_t add } else { return false; } + NrgModbusUser[add_index].gui_unit = ENERGY_MODBUS_UNITS; val = user_add_value[PSTR("U")]; // GUI value Unit if (val) { NrgModbusUser[add_index].gui_unit = val.getStr(); - } else { - return false; } + NrgModbusUser[add_index].resolution = ENERGY_MODBUS_DECIMALS; val = user_add_value[PSTR("D")]; // Decimal resolution if (val) { NrgModbusUser[add_index].resolution = val.getUInt(); - } else { - return false; } #ifdef ENERGY_MODBUS_DEBUG @@ -398,7 +415,7 @@ bool EnergyModbusReadRegisters(void) { for (auto value : arr) { NrgModbus->register_address[names][phase] = value.getUInt(); phase++; - if (phase == ENERGY_MAX_PHASES) { break; } + if (phase >= ENERGY_MAX_PHASES) { break; } } } else if (val) { NrgModbus->register_address[names][0] = val.getUInt(); @@ -464,17 +481,20 @@ bool EnergyModbusReadRegisters(void) { if (EnergyModbusReadUserRegisters(user_add_values.getObject(), add_index)) { add_index++; } else { + AddLog(LOG_LEVEL_INFO, PSTR("NRG: Dropped JSON user input %d"), add_index +1); NrgModbus->user_adds--; } } } else if (val) { if (val.isObject()) { if (!EnergyModbusReadUserRegisters(val.getObject(), 0)) { + AddLog(LOG_LEVEL_INFO, PSTR("NRG: Dropped JSON user input")); NrgModbus->user_adds--; } } } } else { + // Unable to allocate variables on heap NrgModbus->user_adds = 0; } } @@ -505,6 +525,7 @@ void EnergyModbusSnsInit(void) { uint8_t result = EnergyModbus->Begin(NrgModbus->serial_bps, NrgModbus->serial_config); if (result) { if (2 == result) { ClaimSerial(); } + ticker_energy_modbus.attach_ms(150, EnergyModbusLoop); return; } } @@ -609,9 +630,12 @@ bool Xnrg29(uint8_t function) { bool result = false; switch (function) { - case FUNC_EVERY_200_MSECOND: +/* + case FUNC_EVERY_200_MSECOND: // Energy ticker interrupt +// case FUNC_EVERY_250_MSECOND: // Tasmota dispatcher EnergyModbusLoop(); break; +*/ case FUNC_JSON_APPEND: EnergyModbusShow(1); break;