From 776f72650fcbaedf5b5b823f37ef1cc0a074e8ae Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 16 Sep 2023 09:39:57 +0200 Subject: [PATCH 1/8] update dump_entities.csv --- dump_entities.csv | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/dump_entities.csv b/dump_entities.csv index 1c99993d3..4f76189c7 100644 --- a/dump_entities.csv +++ b/dump_entities.csv @@ -1583,8 +1583,8 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffheat,temp diff TC3/TC0 heat,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat -Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffcool,temp diff TC3/TC0 cool,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat +Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve @@ -1768,8 +1768,8 @@ Geo 5xx,boiler,173,silentto,silent mode to,uint (>=0<=3810),minutes,true,number. Geo 5xx,boiler,173,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent Geo 5xx,boiler,173,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode Geo 5xx,boiler,173,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix -Geo 5xx,boiler,173,tempdiffheat,temp diff TC3/TC0 heat,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat -Geo 5xx,boiler,173,tempdiffcool,temp diff TC3/TC0 cool,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool +Geo 5xx,boiler,173,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat +Geo 5xx,boiler,173,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool Geo 5xx,boiler,173,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling Geo 5xx,boiler,173,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable Geo 5xx,boiler,173,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve @@ -2635,8 +2635,9 @@ UI800,thermostat,4,noreducetemp,no reduce below temperature,int (>=-126<=126),C, UI800,thermostat,4,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp UI800,thermostat,4,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio UI800,thermostat,4,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling +UI800,thermostat,4,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon UI800,thermostat,4,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -UI800,thermostat,4,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +UI800,thermostat,4,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset UI800,thermostat,4,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff UI800,thermostat,4,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp RC10,thermostat,65,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -2987,8 +2988,9 @@ RC200/CW100,thermostat,157,noreducetemp,no reduce below temperature,int (>=-126< RC200/CW100,thermostat,157,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp RC200/CW100,thermostat,157,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio RC200/CW100,thermostat,157,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling +RC200/CW100,thermostat,157,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon RC200/CW100,thermostat,157,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -RC200/CW100,thermostat,157,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +RC200/CW100,thermostat,157,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset RC200/CW100,thermostat,157,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff RC200/CW100,thermostat,157,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3057,8 +3059,9 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,noreducetem RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp RC100/Moduline 1000/1010,thermostat,165,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3127,8 +3130,9 @@ RC100/Moduline 1000/1010,thermostat,165,noreducetemp,no reduce below temperature RC100/Moduline 1000/1010,thermostat,165,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp RC100/Moduline 1000/1010,thermostat,165,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio RC100/Moduline 1000/1010,thermostat,165,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling +RC100/Moduline 1000/1010,thermostat,165,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon RC100/Moduline 1000/1010,thermostat,165,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset RC100/Moduline 1000/1010,thermostat,165,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp Rego 2000/3000,thermostat,172,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3197,8 +3201,9 @@ Rego 2000/3000,thermostat,172,noreducetemp,no reduce below temperature,int (>=-1 Rego 2000/3000,thermostat,172,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp Rego 2000/3000,thermostat,172,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio Rego 2000/3000,thermostat,172,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling +Rego 2000/3000,thermostat,172,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon Rego 2000/3000,thermostat,172,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset Rego 2000/3000,thermostat,172,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp Comfort RF,thermostat,215,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode @@ -3294,8 +3299,9 @@ Rego 3000/UI800,thermostat,253,noreducetemp,no reduce below temperature,int (>=- Rego 3000/UI800,thermostat,253,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp Rego 3000/UI800,thermostat,253,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio Rego 3000/UI800,thermostat,253,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling +Rego 3000/UI800,thermostat,253,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon Rego 3000/UI800,thermostat,253,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode -Rego 3000/UI800,thermostat,253,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset +Rego 3000/UI800,thermostat,253,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset Rego 3000/UI800,thermostat,253,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff Rego 3000/UI800,thermostat,253,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp ES72/RC20,thermostat,66,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode From ac08bb603718751d7ec74354022e59120680addf Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 16 Sep 2023 09:40:09 +0200 Subject: [PATCH 2/8] add +x to execute scripts --- scripts/api_test.http | 0 scripts/app-tls-size.py | 0 scripts/boot_app0.bin | Bin scripts/bootloader_dio_40m.bin | Bin scripts/build_interface.py | 0 scripts/clang-format.py | 0 scripts/clang-tidy.py | 0 scripts/dump_entities.csv | 0 scripts/dump_entities.py | 3 ++- scripts/dump_entities.sh | 0 scripts/espota.py | 0 scripts/esptool.py | 0 scripts/helpers.py | 0 scripts/partitions.bin | Bin scripts/rename_fw.py | 0 scripts/run_memory_test.py | 0 scripts/run_sonar.sh | 0 scripts/upload_esp32.py | 0 scripts/upload_fw.py | 0 19 files changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 scripts/api_test.http mode change 100644 => 100755 scripts/app-tls-size.py mode change 100644 => 100755 scripts/boot_app0.bin mode change 100644 => 100755 scripts/bootloader_dio_40m.bin mode change 100644 => 100755 scripts/build_interface.py mode change 100644 => 100755 scripts/clang-format.py mode change 100644 => 100755 scripts/clang-tidy.py create mode 100644 scripts/dump_entities.csv mode change 100644 => 100755 scripts/dump_entities.py mode change 100644 => 100755 scripts/dump_entities.sh mode change 100644 => 100755 scripts/espota.py mode change 100644 => 100755 scripts/esptool.py mode change 100644 => 100755 scripts/helpers.py mode change 100644 => 100755 scripts/partitions.bin mode change 100644 => 100755 scripts/rename_fw.py mode change 100644 => 100755 scripts/run_memory_test.py mode change 100644 => 100755 scripts/run_sonar.sh mode change 100644 => 100755 scripts/upload_esp32.py mode change 100644 => 100755 scripts/upload_fw.py diff --git a/scripts/api_test.http b/scripts/api_test.http old mode 100644 new mode 100755 diff --git a/scripts/app-tls-size.py b/scripts/app-tls-size.py old mode 100644 new mode 100755 diff --git a/scripts/boot_app0.bin b/scripts/boot_app0.bin old mode 100644 new mode 100755 diff --git a/scripts/bootloader_dio_40m.bin b/scripts/bootloader_dio_40m.bin old mode 100644 new mode 100755 diff --git a/scripts/build_interface.py b/scripts/build_interface.py old mode 100644 new mode 100755 diff --git a/scripts/clang-format.py b/scripts/clang-format.py old mode 100644 new mode 100755 diff --git a/scripts/clang-tidy.py b/scripts/clang-tidy.py old mode 100644 new mode 100755 diff --git a/scripts/dump_entities.csv b/scripts/dump_entities.csv new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/dump_entities.py b/scripts/dump_entities.py old mode 100644 new mode 100755 index 6fde4b579..34ff99f97 --- a/scripts/dump_entities.py +++ b/scripts/dump_entities.py @@ -1,6 +1,7 @@ # strips out lines between two markers # pipe a file into, for example: -# make clean; make; echo "test dump" | ./emsesp | python3 ./scripts/dump_entities.py +# make clean; make; echo "test entity_dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv +# see dump_entities.sh import fileinput with fileinput.input() as f_input: diff --git a/scripts/dump_entities.sh b/scripts/dump_entities.sh old mode 100644 new mode 100755 diff --git a/scripts/espota.py b/scripts/espota.py old mode 100644 new mode 100755 diff --git a/scripts/esptool.py b/scripts/esptool.py old mode 100644 new mode 100755 diff --git a/scripts/helpers.py b/scripts/helpers.py old mode 100644 new mode 100755 diff --git a/scripts/partitions.bin b/scripts/partitions.bin old mode 100644 new mode 100755 diff --git a/scripts/rename_fw.py b/scripts/rename_fw.py old mode 100644 new mode 100755 diff --git a/scripts/run_memory_test.py b/scripts/run_memory_test.py old mode 100644 new mode 100755 diff --git a/scripts/run_sonar.sh b/scripts/run_sonar.sh old mode 100644 new mode 100755 diff --git a/scripts/upload_esp32.py b/scripts/upload_esp32.py old mode 100644 new mode 100755 diff --git a/scripts/upload_fw.py b/scripts/upload_fw.py old mode 100644 new mode 100755 From 9cdeb7c07a1b20e76c333baa840566018a6b38f4 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 17 Sep 2023 14:26:24 +0200 Subject: [PATCH 3/8] refactor custom vs customizations --- .../src/project/SettingsCustomization.tsx | 6 +- interface/src/project/SettingsEntities.tsx | 4 +- interface/src/project/api.ts | 8 +- mock-api/server.js | 4 +- src/emsdevice.cpp | 4 +- src/emsdevice.h | 4 +- src/emsesp.cpp | 21 +-- src/emsesp.h | 4 +- src/system.cpp | 2 +- src/version.h | 2 +- src/web/WebAPIService.cpp | 2 +- ...Service.cpp => WebCustomEntityService.cpp} | 130 +++++++++++------- ...tityService.h => WebCustomEntityService.h} | 34 ++--- src/web/WebCustomizationService.cpp | 40 +++--- src/web/WebCustomizationService.h | 8 +- src/web/WebDataService.cpp | 4 +- src/web/WebSchedulerService.cpp | 5 +- 17 files changed, 158 insertions(+), 124 deletions(-) rename src/web/{WebEntityService.cpp => WebCustomEntityService.cpp} (81%) rename src/web/{WebEntityService.h => WebCustomEntityService.h} (59%) diff --git a/interface/src/project/SettingsCustomization.tsx b/interface/src/project/SettingsCustomization.tsx index db41d3761..110535f34 100644 --- a/interface/src/project/SettingsCustomization.tsx +++ b/interface/src/project/SettingsCustomization.tsx @@ -65,7 +65,9 @@ const SettingsCustomization: FC = () => { const { data: devices } = useRequest(EMSESP.readDevices); - const { send: writeCustomEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false }); + const { send: writeCustomizationEntities } = useRequest((data) => EMSESP.writeCustomizationEntities(data), { + immediate: false + }); const { send: readDeviceEntities, onSuccess: onSuccess } = useRequest((data) => EMSESP.readDeviceEntities(data), { initialData: [], @@ -312,7 +314,7 @@ const SettingsCustomization: FC = () => { return; } - await writeCustomEntities({ id: devices?.devices[selectedDevice].i, entity_ids: masked_entities }).catch( + await writeCustomizationEntities({ id: devices?.devices[selectedDevice].i, entity_ids: masked_entities }).catch( (error) => { if (error.message === 'Reboot required') { setRestartNeeded(true); diff --git a/interface/src/project/SettingsEntities.tsx b/interface/src/project/SettingsEntities.tsx index 526754df7..fd97ffe95 100644 --- a/interface/src/project/SettingsEntities.tsx +++ b/interface/src/project/SettingsEntities.tsx @@ -33,12 +33,12 @@ const SettingsEntities: FC = () => { data: entities, send: fetchEntities, error - } = useRequest(EMSESP.readEntities, { + } = useRequest(EMSESP.readCustomEntities, { initialData: [], force: true }); - const { send: writeEntities } = useRequest((data) => EMSESP.writeEntities(data), { immediate: false }); + const { send: writeEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false }); function hasEntityChanged(ei: EntityItem) { return ( diff --git a/interface/src/project/api.ts b/interface/src/project/api.ts index 409f6def2..72f86d5af 100644 --- a/interface/src/project/api.ts +++ b/interface/src/project/api.ts @@ -62,7 +62,7 @@ export const readDeviceEntities = (id: number) => }); export const readDevices = () => alovaInstance.Get('/rest/devices'); export const resetCustomizations = () => alovaInstance.Post('/rest/resetCustomizations'); -export const writeCustomEntities = (data: any) => alovaInstance.Post('/rest/customEntities', data); +export const writeCustomizationEntities = (data: any) => alovaInstance.Post('/rest/customizationEntities', data); // SettingsScheduler export const readSchedule = () => @@ -85,8 +85,8 @@ export const readSchedule = () => export const writeSchedule = (data: any) => alovaInstance.Post('/rest/schedule', data); // SettingsEntities -export const readEntities = () => - alovaInstance.Get('/rest/entities', { +export const readCustomEntities = () => + alovaInstance.Get('/rest/customentities', { name: 'entities', transformData(data: any) { return data.entities.map((ei: EntityItem) => ({ @@ -104,4 +104,4 @@ export const readEntities = () => })); } }); -export const writeEntities = (data: any) => alovaInstance.Post('/rest/entities', data); +export const writeCustomEntities = (data: any) => alovaInstance.Post('/rest/customentities', data); diff --git a/mock-api/server.js b/mock-api/server.js index 5d3279d5d..a3ee73053 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -347,7 +347,7 @@ const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'; const EMSESP_WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue'; const EMSESP_WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor'; const EMSESP_WRITE_ANALOG_ENDPOINT = REST_ENDPOINT_ROOT + 'writeAnalogSensor'; -const EMSESP_CUSTOM_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customEntities'; +const EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customizationEntities'; const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations'; const EMSESP_WRITE_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule'; const EMSESP_WRITE_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'entities'; @@ -2355,7 +2355,7 @@ function updateMask(entity, de, dd) { } } -rest_server.post(EMSESP_CUSTOM_ENTITIES_ENDPOINT, (req, res) => { +rest_server.post(EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT, (req, res) => { const id = req.body.id; console.log('customization id = ' + id); console.log(req.body.entity_ids); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 2cc94fd22..e5054c223 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1074,7 +1074,7 @@ void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) { // set mask per device entity based on the id which is prefixed with the 2 char hex mask value // returns true if the entity has a mask set (not 0 the default) -void EMSdevice::setCustomEntity(const std::string & entity_id) { +void EMSdevice::setCustomizationEntity(const std::string & entity_id) { for (auto & dv : devicevalues_) { char entity_name[70]; if (dv.tag < DeviceValueTAG::TAG_HC1) { @@ -1126,7 +1126,7 @@ void EMSdevice::setCustomEntity(const std::string & entity_id) { } // populate a string vector with entities that have masks set or have a custom name -void EMSdevice::getCustomEntities(std::vector & entity_ids) { +void EMSdevice::getCustomizationEntities(std::vector & entity_ids) { for (const auto & dv : devicevalues_) { char name[100]; name[0] = '\0'; diff --git a/src/emsdevice.h b/src/emsdevice.h index 00ab27f1c..569114ec8 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -191,8 +191,8 @@ class EMSdevice { void add_handlers_ignored(const uint16_t handler); void set_climate_minmax(uint8_t tag, int16_t min, uint16_t max); - void setCustomEntity(const std::string & entity_id); - void getCustomEntities(std::vector & entity_ids); + void setCustomizationEntity(const std::string & entity_id); + void getCustomizationEntities(std::vector & entity_ids); void register_telegram_type(const uint16_t telegram_type_id, const char * telegram_type_name, bool fetch, const process_function_p cb); bool handle_telegram(std::shared_ptr telegram); diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 67a591d11..eca1f7633 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -32,13 +32,13 @@ ESP8266React EMSESP::esp8266React(&webServer, &dummyFS); WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager()); WebCustomizationService EMSESP::webCustomizationService = WebCustomizationService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager()); WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager()); -WebEntityService EMSESP::webEntityService = WebEntityService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager()); +WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager()); #else ESP8266React EMSESP::esp8266React(&webServer, &LittleFS); WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager()); WebCustomizationService EMSESP::webCustomizationService = WebCustomizationService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager()); WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager()); -WebEntityService EMSESP::webEntityService = WebEntityService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager()); +WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager()); #endif WebStatusService EMSESP::webStatusService = WebStatusService(&webServer, EMSESP::esp8266React.getSecurityManager()); @@ -481,7 +481,7 @@ void EMSESP::publish_all(bool force) { publish_device_values(EMSdevice::DeviceType::MIXER); publish_other_values(); // switch and heat pump, ... webSchedulerService.publish(); - webEntityService.publish(); + webCustomEntityService.publish(); publish_sensor_values(true); // includes temperature and analog sensors system_.send_heartbeat(); } @@ -514,7 +514,7 @@ void EMSESP::publish_all_loop() { case 5: publish_other_values(); // switch and heat pump webSchedulerService.publish(true); - webEntityService.publish(true); + webCustomEntityService.publish(true); break; case 6: publish_sensor_values(true, true); @@ -605,7 +605,7 @@ void EMSESP::publish_other_values() { // publish_device_values(EMSdevice::DeviceType::ALERT); // publish_device_values(EMSdevice::DeviceType::PUMP); // publish_device_values(EMSdevice::DeviceType::GENERIC); - webEntityService.publish(); + webCustomEntityService.publish(); } // publish both the temperature and analog sensor values @@ -657,7 +657,8 @@ void EMSESP::publish_response(std::shared_ptr telegram) { buffer = nullptr; } -// builds json with the detail of each value, for a specific EMS device type or the temperature sensor +// builds json with the detail of each value, +// for a specific EMS device type or the sensors, scheduler and custom entities bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const int8_t id, const uint8_t devicetype) { for (const auto & emsdevice : emsdevices) { if (emsdevice->device_type() == devicetype) { @@ -684,7 +685,7 @@ bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const in // own entities if (devicetype == DeviceType::CUSTOM) { - return EMSESP::webEntityService.get_value_info(root, cmd); + return EMSESP::webCustomEntityService.get_value_info(root, cmd); } char error[100]; @@ -895,7 +896,7 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { } // Check for custom entities reding this telegram - webEntityService.get_value(telegram); + webCustomEntityService.get_value(telegram); // check for common types, like the Version(0x02) if (telegram->type_id == EMSdevice::EMS_TYPE_VERSION) { @@ -1414,7 +1415,7 @@ void EMSESP::scheduled_fetch_values() { return; } } - webEntityService.fetch(); + webCustomEntityService.fetch(); no = 0; } } @@ -1497,7 +1498,7 @@ void EMSESP::start() { webCustomizationService.begin(); // load the customizations webSchedulerService.begin(); // load the scheduler events - webEntityService.begin(); // load the custom telegram reads + webCustomEntityService.begin(); // load the custom telegram reads // start telnet service if it's enabled // default idle is 10 minutes, default write timeout is 0 (automatic) diff --git a/src/emsesp.h b/src/emsesp.h index e83287fde..d31347574 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -46,7 +46,7 @@ #include "web/WebSchedulerService.h" #include "web/WebAPIService.h" #include "web/WebLogService.h" -#include "web/WebEntityService.h" +#include "web/WebCustomEntityService.h" #include "emsdevicevalue.h" #include "emsdevice.h" @@ -235,7 +235,7 @@ class EMSESP { static WebLogService webLogService; static WebCustomizationService webCustomizationService; static WebSchedulerService webSchedulerService; - static WebEntityService webEntityService; + static WebCustomEntityService webCustomEntityService; private: static std::string device_tostring(const uint8_t device_id); diff --git a/src/system.cpp b/src/system.cpp index a00c7e660..6476c0474 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1031,7 +1031,7 @@ bool System::check_restore() { saveSettings(EMSESP_SCHEDULER_FILE, "Schedule", input); } else if (settings_type == "entities") { // it's a entity file, just replace it and there's no need to reboot - saveSettings(EMSESP_ENTITY_FILE, "Entities", input); + saveSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", input); } else { LOG_ERROR("Unrecognized file uploaded"); } diff --git a/src/version.h b/src/version.h index 149046701..de05626c9 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.2-dev.0" +#define EMSESP_APP_VERSION "3.6.2-dev.1" diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index aa56f582b..67eadf422 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -216,7 +216,7 @@ void WebAPIService::getEntities(AsyncWebServerRequest * request) { root["type"] = "entities"; - System::extractSettings(EMSESP_ENTITY_FILE, "Entities", root); + System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root); response->setLength(); request->send(response); diff --git a/src/web/WebEntityService.cpp b/src/web/WebCustomEntityService.cpp similarity index 81% rename from src/web/WebEntityService.cpp rename to src/web/WebCustomEntityService.cpp index 1919c5eb3..72af0c429 100644 --- a/src/web/WebEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -22,13 +22,19 @@ namespace emsesp { using namespace std::placeholders; // for `_1` etc -WebEntityService::WebEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) - : _httpEndpoint(WebEntity::read, WebEntity::update, this, server, EMSESP_ENTITY_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED) - , _fsPersistence(WebEntity::read, WebEntity::update, this, fs, EMSESP_ENTITY_FILE, FS_BUFFER_SIZE) { +WebCustomEntityService::WebCustomEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) + : _httpEndpoint(WebCustomEntity::read, + WebCustomEntity::update, + this, + server, + EMSESP_CUSTOMENTITY_SERVICE_PATH, + securityManager, + AuthenticationPredicates::IS_AUTHENTICATED) + , _fsPersistence(WebCustomEntity::read, WebCustomEntity::update, this, fs, EMSESP_CUSTOMENTITY_FILE, FS_BUFFER_SIZE) { } // load the settings when the service starts -void WebEntityService::begin() { +void WebCustomEntityService::begin() { _fsPersistence.readFromFS(); EMSESP::logger().info("Starting Custom entity service"); Mqtt::subscribe(EMSdevice::DeviceType::CUSTOM, "custom/#", nullptr); // use empty function callback @@ -36,10 +42,10 @@ void WebEntityService::begin() { // this creates the entity file, saving it to the FS // and also calls when the Entity web page is refreshed -void WebEntity::read(WebEntity & webEntity, JsonObject & root) { +void WebCustomEntity::read(WebCustomEntity & webEntity, JsonObject & root) { JsonArray entity = root.createNestedArray("entities"); uint8_t counter = 0; - for (const EntityItem & entityItem : webEntity.entityItems) { + for (const CustomEntityItem & entityItem : webEntity.customEntityItems) { JsonObject ei = entity.createNestedObject(); ei["id"] = counter++; // id is only used to render the table and must be unique ei["device_id"] = entityItem.device_id; @@ -50,22 +56,38 @@ void WebEntity::read(WebEntity & webEntity, JsonObject & root) { ei["uom"] = entityItem.uom; ei["value_type"] = entityItem.value_type; ei["writeable"] = entityItem.writeable; - EMSESP::webEntityService.render_value(ei, entityItem, true, true); + EMSESP::webCustomEntityService.render_value(ei, entityItem, true, true); } } // call on initialization and also when the Entity web page is updated // this loads the data into the internal class -StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) { - for (EntityItem & entityItem : webEntity.entityItems) { +StateUpdateResult WebCustomEntity::update(JsonObject & root, WebCustomEntity & webCustomEntity) { +#ifdef EMSESP_STANDALONE + // invoke some fake data for testing + // clang-format off + /* prettier-ignore */ + const char * json = + "{\"entities\": [{\"id\":0,\"device_id\":8,\"type_id\":24,\"offset\":0,\"factor\":1,\"name\":\"boiler_flowtemp\",\"uom\":1,\"value_type\":1,\"writeable\":true}]}"; + // clang-format on + StaticJsonDocument<500> doc; + deserializeJson(doc, json); + root = doc.as(); + Serial.println(COLOR_BRIGHT_MAGENTA); + Serial.print(" Using fake custom entity file: "); + serializeJson(root, Serial); + Serial.println(COLOR_RESET); +#endif + + for (CustomEntityItem & entityItem : webCustomEntity.customEntityItems) { Command::erase_command(EMSdevice::DeviceType::CUSTOM, entityItem.name.c_str()); } - webEntity.entityItems.clear(); - EMSESP::webEntityService.ha_reset(); + webCustomEntity.customEntityItems.clear(); + EMSESP::webCustomEntityService.ha_reset(); if (root["entities"].is()) { for (const JsonObject ei : root["entities"].as()) { - auto entityItem = EntityItem(); + auto entityItem = CustomEntityItem(); entityItem.device_id = ei["device_id"]; // send as numeric, will be converted to string in web entityItem.type_id = ei["type_id"]; entityItem.offset = ei["offset"]; @@ -91,13 +113,13 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) { if (entityItem.factor == 0) { entityItem.factor = 1; } - webEntity.entityItems.push_back(entityItem); // add to list + webCustomEntity.customEntityItems.push_back(entityItem); // add to list if (entityItem.writeable) { Command::add( EMSdevice::DeviceType::CUSTOM, - webEntity.entityItems.back().name.c_str(), - [webEntity](const char * value, const int8_t id) { - return EMSESP::webEntityService.command_setvalue(value, webEntity.entityItems.back().name); + webCustomEntity.customEntityItems.back().name.c_str(), + [webCustomEntity](const char * value, const int8_t id) { + return EMSESP::webCustomEntityService.command_setvalue(value, webCustomEntity.customEntityItems.back().name); }, FL_(entity_cmd), CommandFlag::ADMIN_ONLY); @@ -108,9 +130,9 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) { } // set value by api command -bool WebEntityService::command_setvalue(const char * value, const std::string name) { - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); - for (EntityItem & entityItem : *entityItems) { +bool WebCustomEntityService::command_setvalue(const char * value, const std::string name) { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + for (CustomEntityItem & entityItem : *customEntityItems) { if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) { if (entityItem.value_type == DeviceValueType::STRING) { char telegram[84]; @@ -160,7 +182,7 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na } // output of a single value -void WebEntityService::render_value(JsonObject & output, EntityItem entity, const bool useVal, const bool web) { +void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem entity, const bool useVal, const bool web) { char payload[12]; std::string name = useVal ? "value" : entity.name; switch (entity.value_type) { @@ -215,26 +237,33 @@ void WebEntityService::render_value(JsonObject & output, EntityItem entity, cons } // process json output for info/commands and value_info -bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) { - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); - if (entityItems->size() == 0) { - return false; +bool WebCustomEntityService::get_value_info(JsonObject & output, const char * cmd) { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + + // if no entries, return a message instead of an error + // https://github.com/emsesp/EMS-ESP32/issues/1297 + if (customEntityItems->size() == 0) { + output["message"] = "no entries"; + return true; } + if (Helpers::toLower(cmd) == "commands") { output["info"] = "list all values"; output["commands"] = "list all commands"; - for (const auto & entity : *entityItems) { + for (const auto & entity : *customEntityItems) { output[entity.name] = "custom entitiy"; } return true; } + if (strlen(cmd) == 0 || Helpers::toLower(cmd) == "values" || Helpers::toLower(cmd) == "info") { // list all names - for (const EntityItem & entity : *entityItems) { + for (const CustomEntityItem & entity : *customEntityItems) { render_value(output, entity); } return (output.size() != 0); } + char command_s[30]; strlcpy(command_s, cmd, sizeof(command_s)); char * attribute_s = nullptr; @@ -244,7 +273,8 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) { *breakp = '\0'; attribute_s = breakp + 1; } - for (const auto & entity : *entityItems) { + + for (const auto & entity : *customEntityItems) { if (Helpers::toLower(entity.name) == Helpers::toLower(command_s)) { output["name"] = entity.name; if (entity.uom > 0) { @@ -276,16 +306,18 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) { } } } + if (output.size()) { return true; } } + output["message"] = "unknown command"; return false; } // publish single value -void WebEntityService::publish_single(const EntityItem & entity) { +void WebCustomEntityService::publish_single(const CustomEntityItem & entity) { if (!Mqtt::enabled() || !Mqtt::publish_single()) { return; } @@ -302,19 +334,19 @@ void WebEntityService::publish_single(const EntityItem & entity) { } // publish to Mqtt -void WebEntityService::publish(const bool force) { +void WebCustomEntityService::publish(const bool force) { if (force) { ha_registered_ = false; } if (!Mqtt::enabled()) { return; } - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); - if (entityItems->size() == 0) { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + if (customEntityItems->size() == 0) { return; } if (Mqtt::publish_single() && force) { - for (const EntityItem & entityItem : *entityItems) { + for (const CustomEntityItem & entityItem : *customEntityItems) { publish_single(entityItem); } } @@ -322,7 +354,7 @@ void WebEntityService::publish(const bool force) { DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE); JsonObject output = doc.to(); bool ha_created = ha_registered_; - for (const EntityItem & entityItem : *entityItems) { + for (const CustomEntityItem & entityItem : *customEntityItems) { render_value(output, entityItem); // create HA config if (Mqtt::ha_enabled() && !ha_registered_) { @@ -396,39 +428,39 @@ void WebEntityService::publish(const bool force) { } // count only entities with valid value or command to show in dashboard -uint8_t WebEntityService::count_entities() { - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); - if (entityItems->size() == 0) { +uint8_t WebCustomEntityService::count_entities() { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + if (customEntityItems->size() == 0) { return 0; } DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE); JsonObject output = doc.to(); uint8_t count = 0; - for (const EntityItem & entity : *entityItems) { + for (const CustomEntityItem & entity : *customEntityItems) { render_value(output, entity); count += (output.containsKey(entity.name) || entity.writeable) ? 1 : 0; } return count; } -uint8_t WebEntityService::has_commands() { - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); +uint8_t WebCustomEntityService::has_commands() { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); uint8_t count = 0; - for (const EntityItem & entity : *entityItems) { + for (const CustomEntityItem & entity : *customEntityItems) { count += entity.writeable ? 1 : 0; } return count; } // send to dashboard, msgpack don't like serialized, use number -void WebEntityService::generate_value_web(JsonObject & output) { - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); +void WebCustomEntityService::generate_value_web(JsonObject & output) { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); output["label"] = (std::string) "Custom Entities"; JsonArray data = output.createNestedArray("data"); uint8_t index = 0; - for (const EntityItem & entity : *entityItems) { + for (const CustomEntityItem & entity : *customEntityItems) { JsonObject obj = data.createNestedObject(); // create the object, we know there is a value obj["id"] = "00" + entity.name; obj["u"] = entity.uom; @@ -493,10 +525,10 @@ void WebEntityService::generate_value_web(JsonObject & output) { } // fetch telegram, called from emsesp::fetch -void WebEntityService::fetch() { - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); +void WebCustomEntityService::fetch() { + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; - for (auto & entity : *entityItems) { + for (auto & entity : *customEntityItems) { EMSESP::send_read_request(entity.type_id, entity.device_id, entity.offset, @@ -506,12 +538,12 @@ void WebEntityService::fetch() { } // called on process telegram, read from telegram -bool WebEntityService::get_value(std::shared_ptr telegram) { +bool WebCustomEntityService::get_value(std::shared_ptr telegram) { bool has_change = false; - EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); // read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; - for (auto & entity : *entityItems) { + for (auto & entity : *customEntityItems) { if (entity.value_type == DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id && telegram->offset == entity.offset) { auto data = Helpers::data_to_hex(telegram->message_data, telegram->message_length); diff --git a/src/web/WebEntityService.h b/src/web/WebCustomEntityService.h similarity index 59% rename from src/web/WebEntityService.h rename to src/web/WebCustomEntityService.h index 7df9c4243..816b1bdb5 100644 --- a/src/web/WebEntityService.h +++ b/src/web/WebCustomEntityService.h @@ -17,15 +17,15 @@ */ #include "../telegram.h" -#ifndef WebEntityService_h -#define WebEntityService_h +#ifndef WebCustomEntityService_h +#define WebCustomEntityService_h -#define EMSESP_ENTITY_FILE "/config/emsespEntity.json" -#define EMSESP_ENTITY_SERVICE_PATH "/rest/entities" // GET and POST +#define EMSESP_CUSTOMENTITY_FILE "/config/emsespEntity.json" +#define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customentities" // GET and POST namespace emsesp { -class EntityItem { +class CustomEntityItem { public: uint8_t id; uint8_t device_id; @@ -40,26 +40,26 @@ class EntityItem { std::string data; }; -class WebEntity { +class WebCustomEntity { public: - std::list entityItems; + std::list customEntityItems; - static void read(WebEntity & webEntity, JsonObject & root); - static StateUpdateResult update(JsonObject & root, WebEntity & webEntity); + static void read(WebCustomEntity & webEntity, JsonObject & root); + static StateUpdateResult update(JsonObject & root, WebCustomEntity & webEntity); }; -class WebEntityService : public StatefulService { +class WebCustomEntityService : public StatefulService { public: - WebEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); + WebCustomEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); void begin(); - void publish_single(const EntityItem & entity); + void publish_single(const CustomEntityItem & entity); void publish(const bool force = false); bool command_setvalue(const char * value, const std::string name); bool get_value_info(JsonObject & output, const char * cmd); bool get_value(std::shared_ptr telegram); void fetch(); - void render_value(JsonObject & output, EntityItem entity, const bool useVal = false, const bool web = false); + void render_value(JsonObject & output, CustomEntityItem entity, const bool useVal = false, const bool web = false); uint8_t count_entities(); uint8_t has_commands(); void generate_value_web(JsonObject & output); @@ -69,11 +69,11 @@ class WebEntityService : public StatefulService { private: - HttpEndpoint _httpEndpoint; - FSPersistence _fsPersistence; + HttpEndpoint _httpEndpoint; + FSPersistence _fsPersistence; - std::list * entityItems; // pointer to the list of entity items - bool ha_registered_ = false; + std::list * customEntityItems; // pointer to the list of entity items + bool ha_registered_ = false; }; } // namespace emsesp diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 2a1932778..6f1e9f711 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -31,8 +31,8 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f securityManager, AuthenticationPredicates::IS_AUTHENTICATED) , _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE) - , _masked_entities_handler(CUSTOM_ENTITIES_PATH, - securityManager->wrapCallback(std::bind(&WebCustomizationService::custom_entities, this, _1, _2), + , _masked_entities_handler(CUSTOMIZATION_ENTITIES_PATH, + securityManager->wrapCallback(std::bind(&WebCustomizationService::customization_entities, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) { server->on(DEVICE_ENTITIES_PATH, HTTP_GET, @@ -54,10 +54,10 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f } // this creates the customization file, saving it to the FS -void WebCustomization::read(WebCustomization & settings, JsonObject & root) { +void WebCustomization::read(WebCustomization & customizations, JsonObject & root) { // Temperature Sensor customization JsonArray sensorsJson = root.createNestedArray("ts"); - for (const SensorCustomization & sensor : settings.sensorCustomizations) { + for (const SensorCustomization & sensor : customizations.sensorCustomizations) { JsonObject sensorJson = sensorsJson.createNestedObject(); sensorJson["id"] = sensor.id; // ID of chip sensorJson["name"] = sensor.name; // n @@ -66,7 +66,7 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) { // Analog Sensor customization JsonArray analogJson = root.createNestedArray("as"); - for (const AnalogCustomization & sensor : settings.analogCustomizations) { + for (const AnalogCustomization & sensor : customizations.analogCustomizations) { JsonObject sensorJson = analogJson.createNestedObject(); sensorJson["gpio"] = sensor.gpio; // g sensorJson["name"] = sensor.name; // n @@ -78,7 +78,7 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) { // Masked entities customization JsonArray masked_entitiesJson = root.createNestedArray("masked_entities"); - for (const EntityCustomization & entityCustomization : settings.entityCustomizations) { + for (const EntityCustomization & entityCustomization : customizations.entityCustomizations) { JsonObject entityJson = masked_entitiesJson.createNestedObject(); entityJson["product_id"] = entityCustomization.product_id; entityJson["device_id"] = entityCustomization.device_id; @@ -93,24 +93,22 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) { // call on initialization and also when the page is saved via web UI // this loads the data into the internal class -StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) { +StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & customizations) { #ifdef EMSESP_STANDALONE // invoke some fake data for testing - const char * json = "{\"ts\":[],\"as\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom " - "name for heating active\",\"08tapwateractive\"]}]}"; - + const char * json = "{\"ts\":[],\"as\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom " + "name for heating active\",\"08tapwateractive\"]}]}"; StaticJsonDocument<500> doc; deserializeJson(doc, json); root = doc.as(); - Serial.println(COLOR_BRIGHT_MAGENTA); - Serial.print("Using custom file: "); + Serial.print(" Using fake customization file: "); serializeJson(root, Serial); Serial.println(COLOR_RESET); #endif // Temperature Sensor customization - settings.sensorCustomizations.clear(); + customizations.sensorCustomizations.clear(); if (root["ts"].is()) { for (const JsonObject sensorJson : root["ts"].as()) { // create each of the sensor, overwriting any previous settings @@ -118,12 +116,12 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & sensor.id = sensorJson["id"].as(); sensor.name = sensorJson["name"].as(); sensor.offset = sensorJson["offset"]; - settings.sensorCustomizations.push_back(sensor); // add to list + customizations.sensorCustomizations.push_back(sensor); // add to list } } // Analog Sensor customization - settings.analogCustomizations.clear(); + customizations.analogCustomizations.clear(); if (root["as"].is()) { for (const JsonObject analogJson : root["as"].as()) { // create each of the sensor, overwriting any previous settings @@ -134,12 +132,12 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & sensor.factor = analogJson["factor"]; sensor.uom = analogJson["uom"]; sensor.type = analogJson["type"]; - settings.analogCustomizations.push_back(sensor); // add to list + customizations.analogCustomizations.push_back(sensor); // add to list } } // load array of entities id's with masks, building up the object class - settings.entityCustomizations.clear(); + customizations.entityCustomizations.clear(); if (root["masked_entities"].is()) { for (const JsonObject masked_entities : root["masked_entities"].as()) { auto new_entry = EntityCustomization(); @@ -152,7 +150,7 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & } } - settings.entityCustomizations.push_back(new_entry); // save the new object + customizations.entityCustomizations.push_back(new_entry); // save the new object } } @@ -236,7 +234,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) { // takes a list of updated entities with new masks from the web UI // saves it in the customization service // and updates the entity list real-time -void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, JsonVariant & json) { +void WebCustomizationService::customization_entities(AsyncWebServerRequest * request, JsonVariant & json) { bool need_reboot = false; if (json.is()) { // find the device using the unique_id @@ -256,7 +254,7 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J entity_ids.push_back(id_s); need_reboot = true; } else { - emsdevice->setCustomEntity(id_s); + emsdevice->setCustomizationEntity(id_s); } // emsesp::EMSESP::logger().info(id.as()); } @@ -287,7 +285,7 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J } }); // get list of entities that have masks set or a custom fullname - emsdevice->getCustomEntities(entity_ids); + emsdevice->getCustomizationEntities(entity_ids); // Save the list to the customization file EMSESP::webCustomizationService.update( diff --git a/src/web/WebCustomizationService.h b/src/web/WebCustomizationService.h index 85435496c..ecb4b6a50 100644 --- a/src/web/WebCustomizationService.h +++ b/src/web/WebCustomizationService.h @@ -27,7 +27,7 @@ #define DEVICE_ENTITIES_PATH "/rest/deviceEntities" // POST -#define CUSTOM_ENTITIES_PATH "/rest/customEntities" +#define CUSTOMIZATION_ENTITIES_PATH "/rest/customizationEntities" #define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations" namespace emsesp { @@ -71,8 +71,8 @@ class WebCustomization { std::list sensorCustomizations; // for sensor names and offsets std::list analogCustomizations; // for analog sensors std::list entityCustomizations; // for a list of entities that have a special mask set - static void read(WebCustomization & settings, JsonObject & root); - static StateUpdateResult update(JsonObject & root, WebCustomization & settings); + static void read(WebCustomization & customizations, JsonObject & root); + static StateUpdateResult update(JsonObject & root, WebCustomization & customizations); }; class WebCustomizationService : public StatefulService { @@ -94,7 +94,7 @@ class WebCustomizationService : public StatefulService { void device_entities(AsyncWebServerRequest * request); // POST - void custom_entities(AsyncWebServerRequest * request, JsonVariant & json); + void customization_entities(AsyncWebServerRequest * request, JsonVariant & json); void reset_customization(AsyncWebServerRequest * request); // command AsyncCallbackJsonWebHandler _masked_entities_handler; diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 287d8e649..747e6a5cb 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -92,7 +92,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) { } // add any custom entities - if (EMSESP::webEntityService.count_entities()) { + if (EMSESP::webCustomEntityService.count_entities()) { JsonObject obj = devices.createNestedObject(); obj["id"] = 99; // the last unique id obj["tn"] = Helpers::translated_word(FL_(custom_device)); // translated device type name @@ -210,7 +210,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) { #ifndef EMSESP_STANDALONE if (id == 99) { JsonObject output = response->getRoot(); - EMSESP::webEntityService.generate_value_web(output); + EMSESP::webCustomEntityService.generate_value_web(output); response->setLength(); request->send(response); return; diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index b7b166a26..ee00954c6 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -57,12 +57,13 @@ StateUpdateResult WebScheduler::update(JsonObject & root, WebScheduler & webSche #ifdef EMSESP_STANDALONE // invoke some fake data for testing const char * json = - "{[{\"id\":1,\"active\":true,\"flags\":31,\"time\": \"07:30\",\"cmd\": \"hc1/mode\",\"value\": \"day\",\"name\": \"turn on central heating\"}]}"; + "{\"schedule\": [{\"id\":1,\"active\":true,\"flags\":31,\"time\": \"07:30\",\"cmd\": \"hc1mode\",\"value\": \"day\",\"name\": \"turn on " + "central heating\"}]}"; StaticJsonDocument<500> doc; deserializeJson(doc, json); root = doc.as(); Serial.println(COLOR_BRIGHT_MAGENTA); - Serial.print("Using custom file: "); + Serial.print(" Using fake scheduler file: "); serializeJson(root, Serial); Serial.println(COLOR_RESET); #endif From 8bb703fafeed12bb0b313d48584b18036ef88ea0 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 17 Sep 2023 14:26:53 +0200 Subject: [PATCH 4/8] package update --- interface/package.json | 2 +- interface/yarn.lock | 50 +++++++++++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/interface/package.json b/interface/package.json index 8e955889a..4c2c842ba 100644 --- a/interface/package.json +++ b/interface/package.json @@ -50,7 +50,7 @@ "typescript": "^5.2.2" }, "devDependencies": { - "@babel/core": "^7.22.19", + "@babel/core": "^7.22.20", "@preact/preset-vite": "^2.5.0", "@types/babel__core": "^7", "@typescript-eslint/eslint-plugin": "^6.7.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index f11901090..96dd21528 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -79,26 +79,26 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.22.19": - version: 7.22.19 - resolution: "@babel/core@npm:7.22.19" +"@babel/core@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/core@npm:7.22.20" dependencies: "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.22.13 "@babel/generator": ^7.22.15 "@babel/helper-compilation-targets": ^7.22.15 - "@babel/helper-module-transforms": ^7.22.19 + "@babel/helper-module-transforms": ^7.22.20 "@babel/helpers": ^7.22.15 "@babel/parser": ^7.22.16 "@babel/template": ^7.22.15 - "@babel/traverse": ^7.22.19 + "@babel/traverse": ^7.22.20 "@babel/types": ^7.22.19 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.3 semver: ^6.3.1 - checksum: 6eb0971753892a89ef87d13c902f2c2cb6c2f02e43965ba008b503396f5b97734beb6f643a80ef4bd9a6c54d332945114ceb596b7db2e24f23ff9a46a1d47c73 + checksum: cf3fa046a6ec61022ce1dff54c32ecc86031a210e257189617b93872b438fe0793353d3f792ffcaf0a57903f1146f96cb88c3527453054cdb1d48d196413139f languageName: node linkType: hard @@ -161,6 +161,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-environment-visitor@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-environment-visitor@npm:7.22.20" + checksum: e762c2d8f5d423af89bd7ae9abe35bd4836d2eb401af868a63bbb63220c513c783e25ef001019418560b3fdc6d9a6fb67e6c0b650bcdeb3a2ac44b5c3d2bdd94 + languageName: node + linkType: hard + "@babel/helper-environment-visitor@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-environment-visitor@npm:7.22.5" @@ -205,18 +212,18 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.22.19": - version: 7.22.19 - resolution: "@babel/helper-module-transforms@npm:7.22.19" +"@babel/helper-module-transforms@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-module-transforms@npm:7.22.20" dependencies: - "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.20 "@babel/helper-module-imports": ^7.22.15 "@babel/helper-simple-access": ^7.22.5 "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/helper-validator-identifier": ^7.22.19 + "@babel/helper-validator-identifier": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0 - checksum: ffa93521a7c000ef9f3ed933cc3b75b74a1f087f25315e4b51d895d6915ab265dc5f93edbd3059a234237ccebf77a7841e62a45964a8a407071dab1f99a7fd39 + checksum: 5d927ac0a6b69b5bb13a51d9be659471e6b97bc55897f5738a425f9f6c2bb6b440a50e319848407d9543e1747bc951da807cd4e0a6b1b933e790302780ad33eb languageName: node linkType: hard @@ -281,6 +288,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: dcad63db345fb110e032de46c3688384b0008a42a4845180ce7cd62b1a9c0507a1bed727c4d1060ed1a03ae57b4d918570259f81724aaac1a5b776056f37504e + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-validator-identifier@npm:7.22.5" @@ -486,13 +500,13 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.22.19": - version: 7.22.19 - resolution: "@babel/traverse@npm:7.22.19" +"@babel/traverse@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/traverse@npm:7.22.20" dependencies: "@babel/code-frame": ^7.22.13 "@babel/generator": ^7.22.15 - "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.20 "@babel/helper-function-name": ^7.22.5 "@babel/helper-hoist-variables": ^7.22.5 "@babel/helper-split-export-declaration": ^7.22.6 @@ -500,7 +514,7 @@ __metadata: "@babel/types": ^7.22.19 debug: ^4.1.0 globals: ^11.1.0 - checksum: df783071171acec2160b26506742210295cef05f2193daeca7e83c8b6f65b1cbc0933329e8252dc0f102a95d8c3de9715b9f38be2e8985ec4f7e526ccbd99605 + checksum: ad79e056c970def0441a63832518c5dcfac3db749f0b8b7da0ece7742c4ac9555c1d2ced6a42557e79b5ede4f8f1fbb4bd4633cd44b47bd030ea454fd081cc70 languageName: node linkType: hard @@ -1790,7 +1804,7 @@ __metadata: resolution: "EMS-ESP@workspace:." dependencies: "@alova/adapter-xhr": ^1.0.1 - "@babel/core": ^7.22.19 + "@babel/core": ^7.22.20 "@emotion/react": ^11.11.1 "@emotion/styled": ^11.11.0 "@mui/icons-material": ^5.14.9 From 4c8fd45908a18c693bc5ba26fc6e071843d9f918 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 17 Sep 2023 14:27:04 +0200 Subject: [PATCH 5/8] add test for custom entities --- src/test/test.cpp | 19 +++++++++++++++++-- src/test/test.h | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index 0bb5c8754..b28023ec3 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -280,6 +280,21 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const ok = true; } + if (command == "custom_entities") { + shell.printfln("custom entities..."); + run_test("general"); + +#ifdef EMSESP_STANDALONE + AsyncWebServerRequest request; + request.method(HTTP_GET); + request.url("/api/custom"); + request.url("/api/custom/boiler_flowtemp"); + request.url("/api/custom/boiler_flowtemp2"); + EMSESP::webAPIService.webAPIService_get(&request); +#endif + ok = true; + } + if (command == "coldshot") { shell.printfln("Testing coldshot..."); run_test("general"); @@ -734,7 +749,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const if (emsdevice->unique_id() == 1) { // thermostat std::string a = "00hc1/seltemp|new name>5<52"; - emsdevice->setCustomEntity(a); + emsdevice->setCustomizationEntity(a); break; } } @@ -760,7 +775,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice->unique_id() == 1) { // boiler std::string a = "07wwseltemp"; - emsdevice->setCustomEntity(a); + emsdevice->setCustomizationEntity(a); break; } } diff --git a/src/test/test.h b/src/test/test.h index b0c495a8e..24c316250 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -54,7 +54,9 @@ namespace emsesp { // #define EMSESP_DEBUG_DEFAULT "custom" // #define EMSESP_DEBUG_DEFAULT "entity_dump" // #define EMSESP_DEBUG_DEFAULT "memory" -#define EMSESP_DEBUG_DEFAULT "coldshot" +// #define EMSESP_DEBUG_DEFAULT "coldshot" +#define EMSESP_DEBUG_DEFAULT "custom_entities" + class Test { public: From 0ab573225daba58e50bc84f581b4eef97dd22425 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 17 Sep 2023 14:27:15 +0200 Subject: [PATCH 6/8] fix typos --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bbe366b1..6e7c0d6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r ## Added -- Workaround for better Domoticz MQTT intergration? [#904](https://github.com/emsesp/EMS-ESP32/issues/904) +- Workaround for better Domoticz MQTT integration? [#904](https://github.com/emsesp/EMS-ESP32/issues/904) - Show MAC address without connecting to network enhancement [#933](https://github.com/emsesp/EMS-ESP32/issues/933) - Warn user in WebUI of unsaved changes [#911](https://github.com/emsesp/EMS-ESP32/issues/911) - Detect old Tado thermostat, device-id 0x19, no entities @@ -202,7 +202,7 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r - WebUI optimizations, updated look&feel and better performance [#124](https://github.com/emsesp/EMS-ESP32/issues/124) - Auto refresh of WebUI after successful firmware upload [#178](https://github.com/emsesp/EMS-ESP32/issues/178) -- New Customization Service in WebUI. First feature is the ability to enable/disabled Enitites (device values) from EMS devices [#206](https://github.com/emsesp/EMS-ESP32/issues/206) +- New Customization Service in WebUI. First feature is the ability to enable/disabled Entities (device values) from EMS devices [#206](https://github.com/emsesp/EMS-ESP32/issues/206) - Option to disable Telnet Console [#209](https://github.com/emsesp/EMS-ESP32/issues/209) - Added Hide SSID, Max Clients and Preferred Channel to Access Point - Merged in MichaelDvP's changes like Fahrenheit conversion, publish single (for IOBroker) and a few other critical optimizations From a3f05cb08b1aa78fa74e18d3b0770219737b2d75 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 17 Sep 2023 14:27:33 +0200 Subject: [PATCH 7/8] /api/custom show {} if no Custom Entities configured instead of an error #1297 --- src/command.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 0ef48306e..5536f63ee 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -300,7 +300,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char * // see if there is a command registered auto cf = find_command(device_type, device_id, cmd); - // check if its a call to and end-point to a device + // check if its a call to an end-point of a device // this is used to fetch the attributes of the device entity, or call a command directly bool single_command = (!value || !strlen(value)); if (single_command) { @@ -545,7 +545,9 @@ bool Command::device_has_commands(const uint8_t device_type) { } if (device_type == EMSdevice::DeviceType::CUSTOM) { - return (EMSESP::webEntityService.count_entities() != 0); + // if there are no custom entities, don't error but return a message + return true; + // return (EMSESP::webCustomEntityService.count_entities() != 0); } if (device_type == EMSdevice::DeviceType::TEMPERATURESENSOR) { @@ -608,7 +610,7 @@ void Command::show_all(uuid::console::Shell & shell) { show(shell, EMSdevice::DeviceType::SYSTEM, true); // show Custom - if (EMSESP::webEntityService.has_commands()) { + if (EMSESP::webCustomEntityService.has_commands()) { shell.print(COLOR_BOLD_ON); shell.print(COLOR_YELLOW); shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM)); From ca9ac86fded28f458ac39c0285eed36f228c06a2 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 19 Sep 2023 07:52:12 +0200 Subject: [PATCH 8/8] package updates --- interface/package.json | 10 +- interface/yarn.lock | 217 ++++++++++++++++++++++------------------- 2 files changed, 122 insertions(+), 105 deletions(-) diff --git a/interface/package.json b/interface/package.json index 4c2c842ba..017f22884 100644 --- a/interface/package.json +++ b/interface/package.json @@ -23,16 +23,16 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.9", - "@mui/material": "^5.14.9", + "@mui/material": "^5.14.10", "@preact/compat": "^17.1.2", "@prefresh/vite": "^2.4.1", "@table-library/react-table-library": "4.1.7", "@types/lodash-es": "^4.17.9", "@types/node": "^20.6.2", - "@types/react": "^18.2.21", + "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", "@types/react-router-dom": "^5.3.3", - "alova": "^2.11.1", + "alova": "^2.12.0", "async-validator": "^4.2.5", "history": "^5.3.0", "jwt-decode": "^3.1.2", @@ -53,8 +53,8 @@ "@babel/core": "^7.22.20", "@preact/preset-vite": "^2.5.0", "@types/babel__core": "^7", - "@typescript-eslint/eslint-plugin": "^6.7.0", - "@typescript-eslint/parser": "^6.7.0", + "@typescript-eslint/eslint-plugin": "^6.7.2", + "@typescript-eslint/parser": "^6.7.2", "eslint": "^8.49.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.1.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index 96dd21528..01675aea3 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1022,14 +1022,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.15": - version: 5.0.0-beta.15 - resolution: "@mui/base@npm:5.0.0-beta.15" +"@mui/base@npm:5.0.0-beta.16": + version: 5.0.0-beta.16 + resolution: "@mui/base@npm:5.0.0-beta.16" dependencies: "@babel/runtime": ^7.22.15 "@floating-ui/react-dom": ^2.0.2 "@mui/types": ^7.2.4 - "@mui/utils": ^5.14.9 + "@mui/utils": ^5.14.10 "@popperjs/core": ^2.11.8 clsx: ^2.0.0 prop-types: ^15.8.1 @@ -1040,14 +1040,14 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 95f6bc53333635cba0046d74ef73cef1103dfa845d8c6ba461443ea5408739d5c9f300aa5bf0c1e63fc7ad4f6170e7854588557b7491a60c53b29a88710c12ad + checksum: 035cdb9bba59394d2f937d3f17a0a5d5121a269542129cc99f5b82e4e773d5b31dc6b7fbe1fcacf8b744ff7a8ad9640fb30c27e283f89770f802147fd9d50962 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.14.9": - version: 5.14.9 - resolution: "@mui/core-downloads-tracker@npm:5.14.9" - checksum: aaf8575c65d34bae8c97cb7fe612c7d26b2fff6c09a71241008f92883173c6a9ac5b2beb5003b565594e0ce618c1d81083ef4da18c62c50ab909984e17526a33 +"@mui/core-downloads-tracker@npm:^5.14.10": + version: 5.14.10 + resolution: "@mui/core-downloads-tracker@npm:5.14.10" + checksum: 165751152a5fa490cee7d5919030e12a489c4e23ba253ecd14d78dcda07fea49d715ee656976854716f95d37fd89fa68f34e115f73e6bfed872bd1ba153ecd31 languageName: node linkType: hard @@ -1067,16 +1067,16 @@ __metadata: languageName: node linkType: hard -"@mui/material@npm:^5.14.9": - version: 5.14.9 - resolution: "@mui/material@npm:5.14.9" +"@mui/material@npm:^5.14.10": + version: 5.14.10 + resolution: "@mui/material@npm:5.14.10" dependencies: "@babel/runtime": ^7.22.15 - "@mui/base": 5.0.0-beta.15 - "@mui/core-downloads-tracker": ^5.14.9 - "@mui/system": ^5.14.9 + "@mui/base": 5.0.0-beta.16 + "@mui/core-downloads-tracker": ^5.14.10 + "@mui/system": ^5.14.10 "@mui/types": ^7.2.4 - "@mui/utils": ^5.14.9 + "@mui/utils": ^5.14.10 "@types/react-transition-group": ^4.4.6 clsx: ^2.0.0 csstype: ^3.1.2 @@ -1096,16 +1096,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 92366b60600986e5fdbc6f788e7c3f9855da1ab92635a93f81e217126f057fbe095a34b956e56dded3bdaf98fddc2bfad0a32ccd8292a287d8dde80bd604876c + checksum: 82500d343c71ae22f8e9bfe5632cdf71092d15502574f20c42d44c33828f87dbb864be84f31d0dadc0f304d70fc8854581e2b4779b23cd2d753208e497acfc3d languageName: node linkType: hard -"@mui/private-theming@npm:^5.14.9": - version: 5.14.9 - resolution: "@mui/private-theming@npm:5.14.9" +"@mui/private-theming@npm:^5.14.10": + version: 5.14.10 + resolution: "@mui/private-theming@npm:5.14.10" dependencies: "@babel/runtime": ^7.22.15 - "@mui/utils": ^5.14.9 + "@mui/utils": ^5.14.10 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -1113,19 +1113,18 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 30eec37e14d46d763c5c307e8b51b89d93222fda4cf6a82500dce28c65932155cade59e47aaa0c1c6e407ab7acdf1956e438be6a36c4343d36af4c62270f1295 + checksum: 0ef27687f575f09d8167db5dbc6bda0a0e19d603a3d00c8ff9d3f2544e5c55292b01be0317782640e0072bb19916015920c01e693bd36bd28068775a05a54b6d languageName: node linkType: hard -"@mui/styled-engine@npm:^5.14.9": - version: 5.14.9 - resolution: "@mui/styled-engine@npm:5.14.9" +"@mui/styled-engine@npm:^5.14.10": + version: 5.14.10 + resolution: "@mui/styled-engine@npm:5.14.10" dependencies: "@babel/runtime": ^7.22.15 "@emotion/cache": ^11.11.0 csstype: ^3.1.2 prop-types: ^15.8.1 - react: ^18.2.0 peerDependencies: "@emotion/react": ^11.4.1 "@emotion/styled": ^11.3.0 @@ -1135,19 +1134,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 6ca263d1fcbc604898113f5e3d7b7f0a5592a30a0ca4e40d60ddcf8cf300bed6a042aff9140264da99f71a6661a412810a60fe8f28221e33d69fe34b9914e4b4 + checksum: 0f7184abfc81ed7a82c2256d3bab3efdf202d4e761e4cd98e67bafc7fe7d96176a6cac3c54b156fc4e161ca830294356eef28970f584b62c1a4d6ec3d6256dfe languageName: node linkType: hard -"@mui/system@npm:^5.14.9": - version: 5.14.9 - resolution: "@mui/system@npm:5.14.9" +"@mui/system@npm:^5.14.10": + version: 5.14.10 + resolution: "@mui/system@npm:5.14.10" dependencies: "@babel/runtime": ^7.22.15 - "@mui/private-theming": ^5.14.9 - "@mui/styled-engine": ^5.14.9 + "@mui/private-theming": ^5.14.10 + "@mui/styled-engine": ^5.14.10 "@mui/types": ^7.2.4 - "@mui/utils": ^5.14.9 + "@mui/utils": ^5.14.10 clsx: ^2.0.0 csstype: ^3.1.2 prop-types: ^15.8.1 @@ -1163,7 +1162,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: cd74cfcb8f5e3f3344d1791a18aad22df03d966ee1ae1dd590ed291eeb0d474622d48a272695b9570e4eac399e6004291ef83313d4084212e60409361a0913bd + checksum: daf86070f786dbb70b997b0dbe11485634407bb60b18219d2929649e92486f9097c3c17d658ca3cd266d5708b658fc8bead6d6b53d63995c25bf76445d3d4919 languageName: node linkType: hard @@ -1179,21 +1178,21 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.14.9": - version: 5.14.9 - resolution: "@mui/utils@npm:5.14.9" +"@mui/utils@npm:^5.14.10": + version: 5.14.10 + resolution: "@mui/utils@npm:5.14.10" dependencies: "@babel/runtime": ^7.22.15 + "@types/prop-types": ^15.7.5 prop-types: ^15.8.1 react-is: ^18.2.0 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: b78fd9aaf49967a117fcb398198ef7a18eff23a92b6529982bb0fe913a3dd6545371c995bd4b8376eed425e9de36157091c5211a7e6d141429d8651d6e9184af + checksum: fb778e1a5fb97920b9457667d910f6055bb0a22bec26f011b4e269e9646e46f6c4800e00b80feab8f8ec79242afd4c342437671a0389b6ac807e14a32338dd24 languageName: node linkType: hard @@ -1613,6 +1612,13 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:^15.7.5": + version: 15.7.6 + resolution: "@types/prop-types@npm:15.7.6" + checksum: 2871c61f662b91c7366204ae6801bc0a88e1e7e8d48962f7f2143cf0f0f4dbbe9a57978063729d15ffd7fad13bd648cc70ff019b7a3fc8f4b84f72fb259b4dfb + languageName: node + linkType: hard + "@types/react-dom@npm:^18.2.7": version: 18.2.7 resolution: "@types/react-dom@npm:18.2.7" @@ -1652,7 +1658,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.2.21": +"@types/react@npm:*": version: 18.2.21 resolution: "@types/react@npm:18.2.21" dependencies: @@ -1663,6 +1669,17 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^18.2.22": + version: 18.2.22 + resolution: "@types/react@npm:18.2.22" + dependencies: + "@types/prop-types": "*" + "@types/scheduler": "*" + csstype: ^3.0.2 + checksum: ac481c8a85c95cf1eb0a09c3c7e609428f12ff61d57ac0e9c8dd94b6dcfde44306c4f41d98f83e9554ed33a66e605ba35687c0a38d367e7d77dd2bdea9d6145e + languageName: node + linkType: hard + "@types/scheduler@npm:*": version: 0.16.3 resolution: "@types/scheduler@npm:0.16.3" @@ -1677,15 +1694,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.7.0" +"@typescript-eslint/eslint-plugin@npm:^6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/eslint-plugin@npm:6.7.2" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.7.0 - "@typescript-eslint/type-utils": 6.7.0 - "@typescript-eslint/utils": 6.7.0 - "@typescript-eslint/visitor-keys": 6.7.0 + "@typescript-eslint/scope-manager": 6.7.2 + "@typescript-eslint/type-utils": 6.7.2 + "@typescript-eslint/utils": 6.7.2 + "@typescript-eslint/visitor-keys": 6.7.2 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -1698,44 +1715,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f78a8de1311776bb3dd614f4a7d9cb098601ea0ccc1bec2317518794c473a813ccc58262304b999170720c16c280b56b928ba98aaa1c6a2ff9e73b7a7f9a831a + checksum: ce0c1f0cc56cdf0d442439288a8d3530fff224b93840d7bd862da38521865f60516aa6a006d77e48dc91c296915e27c1b9131bff5d7495c9e848280f53e4dd03 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/parser@npm:6.7.0" +"@typescript-eslint/parser@npm:^6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/parser@npm:6.7.2" dependencies: - "@typescript-eslint/scope-manager": 6.7.0 - "@typescript-eslint/types": 6.7.0 - "@typescript-eslint/typescript-estree": 6.7.0 - "@typescript-eslint/visitor-keys": 6.7.0 + "@typescript-eslint/scope-manager": 6.7.2 + "@typescript-eslint/types": 6.7.2 + "@typescript-eslint/typescript-estree": 6.7.2 + "@typescript-eslint/visitor-keys": 6.7.2 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 2b15d9b1624b68ea0e17f401809d1a6e5f212ff922c45a0e63bf9bc584c1a5608a461f1c5f3d781f2060556ec512b7d957d5162848c957b96f54f485e128a93b + checksum: dde49a291d15e4eba0f286de40bd6ebcec4167979220bba5c30ff94a3c5f6f36ce2d04e7df94204a84b8cb99c261252b972500e2c46733a55d8c8c325937eeca languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/scope-manager@npm:6.7.0" +"@typescript-eslint/scope-manager@npm:6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/scope-manager@npm:6.7.2" dependencies: - "@typescript-eslint/types": 6.7.0 - "@typescript-eslint/visitor-keys": 6.7.0 - checksum: c4cfb790c61eec7e1b6309eb6cc7d863b4d3dfc84e844dfee9fe21ddc86e68b4fde1f70ef5f26ce7c0f66b73f410d51c2f80b97dc697b77aef1f54b9fbbd23c4 + "@typescript-eslint/types": 6.7.2 + "@typescript-eslint/visitor-keys": 6.7.2 + checksum: 806cc2c10edb3324763bbedfa922147bf38b114da432c5feb11886f1b7f9f498b014cb1c26fbd9ea18ead3245abe268e29ea120962fd463de0a950ca69f620c4 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/type-utils@npm:6.7.0" +"@typescript-eslint/type-utils@npm:6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/type-utils@npm:6.7.2" dependencies: - "@typescript-eslint/typescript-estree": 6.7.0 - "@typescript-eslint/utils": 6.7.0 + "@typescript-eslint/typescript-estree": 6.7.2 + "@typescript-eslint/utils": 6.7.2 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -1743,23 +1760,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 40eff7625ae7a9d32cf3e413891196ab32ef6472eef563e191fa388b3f717515e43395de34e80c763a9e4e36e71494df19a04ad3d0bb4db1df5e8833c5c6b337 + checksum: 4ca831cbeeb221ed318d9761b1e3652bc55c391029cfc588ff5535b43542fb454684ef62f21f7c27c60dd75daea6c79320c177a501646b78bee5403c67027df3 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/types@npm:6.7.0" - checksum: 7d79d5dafa8003de00721e0c6983dc24bfee249b9d2e072044f3a4ec5d85aa90c7d095531dc081f4da607e2ad8aa67a6f401fa840b5a3b3eea05d8ac6bb6a006 +"@typescript-eslint/types@npm:6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/types@npm:6.7.2" + checksum: d5daf0051609b1bbe5a0d43a130647c23e2951f2443307d3b5dd323a71e3bedd32f3263a4bb5fdfaa8ad8a78c865ba3d5b606695cb27d85c412d2a8931c5d9a6 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.7.0" +"@typescript-eslint/typescript-estree@npm:6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/typescript-estree@npm:6.7.2" dependencies: - "@typescript-eslint/types": 6.7.0 - "@typescript-eslint/visitor-keys": 6.7.0 + "@typescript-eslint/types": 6.7.2 + "@typescript-eslint/visitor-keys": 6.7.2 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1768,34 +1785,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 61a9a6988e706c23796bb2a3dce063c216c78cdca62a54268c54a8ebe784794791fde52cf07204f1c026e4d06dee3efd732138a93bd5e6f6d87bc51c0c9c13ca + checksum: 80205c23807ea0d508189de4326ec18dccfcaf4bccd4304c9fc8b49504083df3d001af16733272487197ffd5d499e6c8d0e0f2eb9d2d61423e163b6d4787a7bb languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/utils@npm:6.7.0" +"@typescript-eslint/utils@npm:6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/utils@npm:6.7.2" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.7.0 - "@typescript-eslint/types": 6.7.0 - "@typescript-eslint/typescript-estree": 6.7.0 + "@typescript-eslint/scope-manager": 6.7.2 + "@typescript-eslint/types": 6.7.2 + "@typescript-eslint/typescript-estree": 6.7.2 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: c8ca9c3c078d7adc2da241046821627c6283a23aece46ee9f6c2464217190efb7838e6a669ca8b194693a6975c2dcbbda45e1376959c30a6be6953ab19d1268d + checksum: c1e5af3efc47bb5bff0d48fc73bf87e951b1393144e4ea072c3eec4346fe425a22c3261ede4ab9c9115bf15ad6c26c7c645522a12163e71d3df910e5005a87ba languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.7.0": - version: 6.7.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.7.0" +"@typescript-eslint/visitor-keys@npm:6.7.2": + version: 6.7.2 + resolution: "@typescript-eslint/visitor-keys@npm:6.7.2" dependencies: - "@typescript-eslint/types": 6.7.0 + "@typescript-eslint/types": 6.7.2 eslint-visitor-keys: ^3.4.1 - checksum: 44405ba105d91f47387346c025bfbbefec111b3d7effcb97e47ac179bbc8717ccb3f129d9fa0545c3f56916706362f1b6f0c2ff2bad73b58cfdf2c71ed8cf982 + checksum: e6b35338a98fcf6719388a2dce7ae476622f6fa37b0d5e3607de260100a72b8cb86e76b73b16a9a3c434e8386e1ea394cd946add1e4ce712d3b8a7fd0e221830 languageName: node linkType: hard @@ -1808,7 +1825,7 @@ __metadata: "@emotion/react": ^11.11.1 "@emotion/styled": ^11.11.0 "@mui/icons-material": ^5.14.9 - "@mui/material": ^5.14.9 + "@mui/material": ^5.14.10 "@preact/compat": ^17.1.2 "@preact/preset-vite": ^2.5.0 "@prefresh/vite": ^2.4.1 @@ -1816,12 +1833,12 @@ __metadata: "@types/babel__core": ^7 "@types/lodash-es": ^4.17.9 "@types/node": ^20.6.2 - "@types/react": ^18.2.21 + "@types/react": ^18.2.22 "@types/react-dom": ^18.2.7 "@types/react-router-dom": ^5.3.3 - "@typescript-eslint/eslint-plugin": ^6.7.0 - "@typescript-eslint/parser": ^6.7.0 - alova: ^2.11.1 + "@typescript-eslint/eslint-plugin": ^6.7.2 + "@typescript-eslint/parser": ^6.7.2 + alova: ^2.12.0 async-validator: ^4.2.5 eslint: ^8.49.0 eslint-config-airbnb: ^19.0.4 @@ -1923,10 +1940,10 @@ __metadata: languageName: node linkType: hard -"alova@npm:^2.11.1": - version: 2.11.1 - resolution: "alova@npm:2.11.1" - checksum: 1ef0cc44985495611728c9b9326d9c40382e45d3e0ba1c5aa87634e58b75f7b66f0b7bdb77fa60e0d57450db91dc31ed0cfe2cbd42dc707811ef3ae97bc3b374 +"alova@npm:^2.12.0": + version: 2.12.0 + resolution: "alova@npm:2.12.0" + checksum: a08f829d9d4ab8ca3bea2bd619a7c0a8a027cc1178096425bd97f74de2c495f8d70a795276976506702a749cb8c170df9436f45f6f4a524d9e20e90bf098099b languageName: node linkType: hard @@ -5302,7 +5319,7 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.2.0, react@npm:latest": +"react@npm:latest": version: 18.2.0 resolution: "react@npm:18.2.0" dependencies: