mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
mqtt/commands for scheduler
This commit is contained in:
@@ -14,8 +14,6 @@ const de: Translation = {
|
|||||||
SU_PASSWORD: 'su Passwort',
|
SU_PASSWORD: 'su Passwort',
|
||||||
DASHBOARD: 'Kontrollzentrum',
|
DASHBOARD: 'Kontrollzentrum',
|
||||||
SETTINGS_OF: '{0} Einstellungen',
|
SETTINGS_OF: '{0} Einstellungen',
|
||||||
APPLY_CHANGES: 'Apply Changes ({0})', // TODO translate
|
|
||||||
UPDATE: 'Update', // TODO translate
|
|
||||||
HELP_OF: '{0} Hilfe',
|
HELP_OF: '{0} Hilfe',
|
||||||
LOGGED_IN: 'Eingeloggt als {name}',
|
LOGGED_IN: 'Eingeloggt als {name}',
|
||||||
PLEASE_SIGNIN: 'Bitte einloggen, um fortzufahren',
|
PLEASE_SIGNIN: 'Bitte einloggen, um fortzufahren',
|
||||||
@@ -32,11 +30,11 @@ const de: Translation = {
|
|||||||
REFRESH: 'Aktualisieren',
|
REFRESH: 'Aktualisieren',
|
||||||
EXPORT: 'Exportieren',
|
EXPORT: 'Exportieren',
|
||||||
DEVICE_DETAILS: 'Geräte Details',
|
DEVICE_DETAILS: 'Geräte Details',
|
||||||
BRAND: 'Marke',
|
|
||||||
ID_OF: '{0} ID',
|
ID_OF: '{0} ID',
|
||||||
DEVICE: 'Geräte',
|
DEVICE: 'Geräte',
|
||||||
PRODUCT: 'Produkt',
|
PRODUCT: 'Produkt',
|
||||||
VERSION: 'Version',
|
VERSION: 'Version',
|
||||||
|
BRAND: 'Marke',
|
||||||
ENTITY_NAME: 'Entitätsname',
|
ENTITY_NAME: 'Entitätsname',
|
||||||
VALUE: '{{Wert|wert}}',
|
VALUE: '{{Wert|wert}}',
|
||||||
SHOW_FAV: 'nur Favoriten anzeigen',
|
SHOW_FAV: 'nur Favoriten anzeigen',
|
||||||
@@ -48,6 +46,8 @@ const de: Translation = {
|
|||||||
CANCEL: 'Abbrechen',
|
CANCEL: 'Abbrechen',
|
||||||
RESET: 'Zurücksetzen',
|
RESET: 'Zurücksetzen',
|
||||||
SEND: 'Senden',
|
SEND: 'Senden',
|
||||||
|
APPLY_CHANGES: 'Apply Changes ({0})', // TODO translate
|
||||||
|
UPDATE: 'Update', // TODO translate
|
||||||
REMOVE: 'Entfernen',
|
REMOVE: 'Entfernen',
|
||||||
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
|
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
|
||||||
PROBLEM_LOADING: 'Problem beim Laden',
|
PROBLEM_LOADING: 'Problem beim Laden',
|
||||||
@@ -208,7 +208,7 @@ const de: Translation = {
|
|||||||
COMPACT: 'Kompakte Darstellung',
|
COMPACT: 'Kompakte Darstellung',
|
||||||
ENABLE_OTA: 'OTA Updates verwenden',
|
ENABLE_OTA: 'OTA Updates verwenden',
|
||||||
DOWNLOAD_CUSTOMIZATION_TEXT: 'Herunterladen der individuellen Entitätsanpassungen',
|
DOWNLOAD_CUSTOMIZATION_TEXT: 'Herunterladen der individuellen Entitätsanpassungen',
|
||||||
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate
|
DOWNLOAD_SCHEDULE_TEXT: 'Herunterladen geplanter Befehle',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensitive Einstellungen enthalten',
|
DOWNLOAD_SETTINGS_TEXT: 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensitive Einstellungen enthalten',
|
||||||
UPLOAD_TEXT: 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen',
|
UPLOAD_TEXT: 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen',
|
||||||
UPLOADING: 'Hochladen',
|
UPLOADING: 'Hochladen',
|
||||||
@@ -305,20 +305,20 @@ const de: Translation = {
|
|||||||
ENTITY: 'Entität',
|
ENTITY: 'Entität',
|
||||||
MIN: 'min',
|
MIN: 'min',
|
||||||
MAX: 'max',
|
MAX: 'max',
|
||||||
BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate
|
BLOCK_NAVIGATE_1: 'Sie haben ungesicherte Änderungen',
|
||||||
BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate
|
BLOCK_NAVIGATE_2: 'Beim verlassen der Seite verlieren Sie ungesicherte Einstellungen. Wollen Sie die Seite wirklich verlassen?',
|
||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Bleiben',
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Verlassen',
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Planer',
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP', // TODO translate
|
SCHEDULER_HELP_1: 'Fügen Sie eigene, geplante Befehle zur Automatisierung hinzu. Vergeben Sie einen Entitätsnamen um die Aktivierung über API/Mqtt zu steuern',
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Zeitplan',
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Zeit',
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer',
|
||||||
WEEKLY: 'Weekly', // TODO translate
|
WEEKLY: 'Wöchentlich',
|
||||||
SCHEDULE_SAVED: 'Schedule updated', // TODO translate
|
SCHEDULE_SAVED: 'Plan gespeichert',
|
||||||
SCHEDULE_TIMER_1: 'on startup', // TODO translate
|
SCHEDULE_TIMER_1: 'beim Start',
|
||||||
SCHEDULE_TIMER_2: 'every minute', // TODO translate
|
SCHEDULE_TIMER_2: 'jede Minute',
|
||||||
SCHEDULE_TIMER_3: 'every hour' // TODO translate
|
SCHEDULE_TIMER_3: 'jede Stunde'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default de;
|
export default de;
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const en: Translation = {
|
|||||||
STAY: 'Stay',
|
STAY: 'Stay',
|
||||||
LEAVE: 'Leave',
|
LEAVE: 'Leave',
|
||||||
SCHEDULER: 'Scheduler',
|
SCHEDULER: 'Scheduler',
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP',
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt',
|
||||||
SCHEDULE: 'Schedule',
|
SCHEDULE: 'Schedule',
|
||||||
TIME: 'Time',
|
TIME: 'Time',
|
||||||
TIMER: 'Timer',
|
TIMER: 'Timer',
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const fr: Translation = {
|
|||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Stay', // TODO translate
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Leave', // TODO translate
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler', // TODO translate
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP', // TODO translate
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt', // TODO translate
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Schedule', // TODO translate
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Time', // TODO translate
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer', // TODO translate
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const nl: Translation = {
|
|||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Stay', // TODO translate
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Leave', // TODO translate
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler', // TODO translate
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP', // TODO translate
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt', // TODO translate
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Schedule', // TODO translate
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Time', // TODO translate
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer', // TODO translate
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const no: Translation = {
|
|||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Stay', // TODO translate
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Leave', // TODO translate
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler', // TODO translate
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP', // TODO translate
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt', // TODO translate
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Schedule', // TODO translate
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Time', // TODO translate
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer', // TODO translate
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const pl: BaseTranslation = {
|
|||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Stay', // TODO translate
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Leave', // TODO translate
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler', // TODO translate
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP', // TODO translate
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt', // TODO translate
|
||||||
SCHEDULE: 'Schedule', // TODO translate SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Schedule', // TODO translate SCHEDULE: 'Schedule', // TODO translate
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Time', // TODO translate
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer', // TODO translate
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const sv: Translation = {
|
|||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Stay', // TODO translate
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Leave', // TODO translate
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler', // TODO translate
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP', // TODO translate
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt', // TODO translate
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Schedule', // TODO translate
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Time', // TODO translate
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer', // TODO translate
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const tr: Translation = {
|
|||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Stay', // TODO translate
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Leave', // TODO translate
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler', // TODO translate
|
||||||
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP.', // TODO translate
|
SCHEDULER_HELP_1: 'Add custom scheduled commands to automate EMS-ESP. Add entity name to control activation by api/mqtt', // TODO translate
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Schedule', // TODO translate
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Time', // TODO translate
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Timer', // TODO translate
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ const SettingsScheduler: FC = () => {
|
|||||||
)}
|
)}
|
||||||
<TextField
|
<TextField
|
||||||
name="description"
|
name="description"
|
||||||
label={LL.DESCRIPTION()}
|
label={LL.ENTITY_NAME()}
|
||||||
value={scheduleItem.description}
|
value={scheduleItem.description}
|
||||||
fullWidth
|
fullWidth
|
||||||
margin="normal"
|
margin="normal"
|
||||||
|
|||||||
@@ -128,7 +128,8 @@ void AnalogSensor::reload() {
|
|||||||
[&](const char * value, const int8_t id) { return command_setvalue(value, sensor.gpio); },
|
[&](const char * value, const int8_t id) { return command_setvalue(value, sensor.gpio); },
|
||||||
sensor.type == AnalogType::COUNTER ? FL_(counter)
|
sensor.type == AnalogType::COUNTER ? FL_(counter)
|
||||||
: sensor.type == AnalogType::DIGITAL_OUT ? FL_(digital_out)
|
: sensor.type == AnalogType::DIGITAL_OUT ? FL_(digital_out)
|
||||||
: FL_(pwm));
|
: FL_(pwm),
|
||||||
|
CommandFlag::ADMIN_ONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -145,6 +145,33 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
data = input["value"];
|
data = input["value"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if data is entity like device/hc/name/value
|
||||||
|
if (data.is<const char *>()) {
|
||||||
|
const char * d = data.as<const char *>();
|
||||||
|
if (strlen(d)) {
|
||||||
|
char * device_end = strchr(d, '/');
|
||||||
|
if (device_end != nullptr) {
|
||||||
|
char device_s[15] = {'\0'};
|
||||||
|
const char * device_p = device_s;
|
||||||
|
const char * data_p = nullptr;
|
||||||
|
strlcpy(device_s, d, device_end - d + 1);
|
||||||
|
data_p = device_end + 1;
|
||||||
|
int8_t id_d = -1;
|
||||||
|
data_p = parse_command_string(data_p, id_d);
|
||||||
|
char data_s[50];
|
||||||
|
strcpy(data_s, data_p);
|
||||||
|
strcat(data_s, "/value");
|
||||||
|
uint8_t device_type = EMSdevice::device_name_2_device_type(device_p);
|
||||||
|
if (CommandRet::OK == Command::call(device_type, data_s, "", true, id_d, output)) {
|
||||||
|
if (output.containsKey("api_data")) {
|
||||||
|
data = output["api_data"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// call the command based on the type
|
// call the command based on the type
|
||||||
uint8_t return_code = CommandRet::ERROR;
|
uint8_t return_code = CommandRet::ERROR;
|
||||||
if (data.is<const char *>()) {
|
if (data.is<const char *>()) {
|
||||||
@@ -204,11 +231,13 @@ const char * Command::parse_command_string(const char * command, int8_t & id) {
|
|||||||
id = command[2] - '0';
|
id = command[2] - '0';
|
||||||
command += 3;
|
command += 3;
|
||||||
} else if (!strncmp(lowerCmd, "wwc", 3) && command[3] == '1' && command[4] == '0') {
|
} else if (!strncmp(lowerCmd, "wwc", 3) && command[3] == '1' && command[4] == '0') {
|
||||||
id = DeviceValueTAG::TAG_WWC10 - DeviceValueTAG::TAG_HC1 + 1; //18; } else if (!strncmp(lowerCmd, "wwc", 3) && command[3] >= '1' && command[3] <= '9') {
|
id = DeviceValueTAG::TAG_WWC10 - DeviceValueTAG::TAG_HC1 + 1; //18;
|
||||||
id = command[3] - '0' + 8;
|
command += 5;
|
||||||
|
} else if (!strncmp(lowerCmd, "wwc", 3) && command[3] >= '1' && command[3] <= '9') {
|
||||||
|
id = command[3] - '1' + DeviceValueTAG::TAG_WWC1 - DeviceValueTAG::TAG_HC1 + 1; //9;
|
||||||
command += 4;
|
command += 4;
|
||||||
} else if (!strncmp(lowerCmd, "id", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '9') {
|
} else if (!strncmp(lowerCmd, "id", 2) && command[2] == '1' && command[3] >= '0' && command[3] <= '9') {
|
||||||
id = command[3] - '1' + DeviceValueTAG::TAG_WWC1 - DeviceValueTAG::TAG_HC1 + 1; //9;
|
id = command[3] - '0' + 10;
|
||||||
command += 4;
|
command += 4;
|
||||||
} else if (!strncmp(lowerCmd, "id", 2) && command[2] >= '1' && command[2] <= '9') {
|
} else if (!strncmp(lowerCmd, "id", 2) && command[2] >= '1' && command[2] <= '9') {
|
||||||
id = command[2] - '0';
|
id = command[2] - '0';
|
||||||
@@ -499,6 +528,10 @@ bool Command::device_has_commands(const uint8_t device_type) {
|
|||||||
return true; // we always have System
|
return true; // we always have System
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device_type == EMSdevice::DeviceType::SCHEDULER) {
|
||||||
|
return EMSESP::webSchedulerService.has_commands();
|
||||||
|
}
|
||||||
|
|
||||||
if (device_type == EMSdevice::DeviceType::DALLASSENSOR) {
|
if (device_type == EMSdevice::DeviceType::DALLASSENSOR) {
|
||||||
return (EMSESP::dallassensor_.have_sensors());
|
return (EMSESP::dallassensor_.have_sensors());
|
||||||
}
|
}
|
||||||
@@ -555,6 +588,13 @@ void Command::show_all(uuid::console::Shell & shell) {
|
|||||||
shell.print(COLOR_RESET);
|
shell.print(COLOR_RESET);
|
||||||
show(shell, EMSdevice::DeviceType::SYSTEM, true);
|
show(shell, EMSdevice::DeviceType::SYSTEM, true);
|
||||||
|
|
||||||
|
// show scheduler
|
||||||
|
shell.print(COLOR_BOLD_ON);
|
||||||
|
shell.print(COLOR_YELLOW);
|
||||||
|
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
|
||||||
|
shell.print(COLOR_RESET);
|
||||||
|
show(shell, EMSdevice::DeviceType::SCHEDULER, true);
|
||||||
|
|
||||||
// show sensors
|
// show sensors
|
||||||
if (EMSESP::dallassensor_.have_sensors()) {
|
if (EMSESP::dallassensor_.have_sensors()) {
|
||||||
shell.print(COLOR_BOLD_ON);
|
shell.print(COLOR_BOLD_ON);
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
|||||||
switch (device_type) {
|
switch (device_type) {
|
||||||
case DeviceType::SYSTEM:
|
case DeviceType::SYSTEM:
|
||||||
return F_(system);
|
return F_(system);
|
||||||
|
case DeviceType::SCHEDULER:
|
||||||
|
return F_(scheduler);
|
||||||
case DeviceType::BOILER:
|
case DeviceType::BOILER:
|
||||||
return F_(boiler);
|
return F_(boiler);
|
||||||
case DeviceType::THERMOSTAT:
|
case DeviceType::THERMOSTAT:
|
||||||
@@ -194,6 +196,9 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
|
|||||||
if (!strcmp(lowtopic, F_(system))) {
|
if (!strcmp(lowtopic, F_(system))) {
|
||||||
return DeviceType::SYSTEM;
|
return DeviceType::SYSTEM;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(lowtopic, F_(scheduler))) {
|
||||||
|
return DeviceType::SCHEDULER;
|
||||||
|
}
|
||||||
if (!strcmp(lowtopic, F_(heatpump))) {
|
if (!strcmp(lowtopic, F_(heatpump))) {
|
||||||
return DeviceType::HEATPUMP;
|
return DeviceType::HEATPUMP;
|
||||||
}
|
}
|
||||||
@@ -225,10 +230,6 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
|
|||||||
return DeviceType::HEATSOURCE;
|
return DeviceType::HEATSOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(lowtopic, F_(heatsource))) {
|
|
||||||
return DeviceType::HEATSOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DeviceType::UNKNOWN;
|
return DeviceType::UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,10 +551,6 @@ void EMSdevice::add_device_value(uint8_t tag, // to b
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the device entity
|
// add the device entity
|
||||||
devicevalues_.emplace_back(
|
devicevalues_.emplace_back(
|
||||||
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
|
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ class EMSdevice {
|
|||||||
SYSTEM = 0, // this is us (EMS-ESP)
|
SYSTEM = 0, // this is us (EMS-ESP)
|
||||||
DALLASSENSOR, // for internal dallas sensors
|
DALLASSENSOR, // for internal dallas sensors
|
||||||
ANALOGSENSOR, // for internal analog sensors
|
ANALOGSENSOR, // for internal analog sensors
|
||||||
|
SCHEDULER,
|
||||||
BOILER,
|
BOILER,
|
||||||
THERMOSTAT,
|
THERMOSTAT,
|
||||||
MIXER,
|
MIXER,
|
||||||
|
|||||||
@@ -479,6 +479,7 @@ void EMSESP::publish_all(bool force) {
|
|||||||
publish_device_values(EMSdevice::DeviceType::SOLAR);
|
publish_device_values(EMSdevice::DeviceType::SOLAR);
|
||||||
publish_device_values(EMSdevice::DeviceType::MIXER);
|
publish_device_values(EMSdevice::DeviceType::MIXER);
|
||||||
publish_other_values(); // switch and heat pump, ...
|
publish_other_values(); // switch and heat pump, ...
|
||||||
|
webSchedulerService.publish();
|
||||||
publish_sensor_values(true); // includes dallas and analog sensors
|
publish_sensor_values(true); // includes dallas and analog sensors
|
||||||
system_.send_heartbeat();
|
system_.send_heartbeat();
|
||||||
}
|
}
|
||||||
@@ -510,6 +511,7 @@ void EMSESP::publish_all_loop() {
|
|||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
publish_other_values(); // switch and heat pump
|
publish_other_values(); // switch and heat pump
|
||||||
|
webSchedulerService.publish(true);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
publish_sensor_values(true, true);
|
publish_sensor_values(true, true);
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ MAKE_WORD(dallassensor)
|
|||||||
MAKE_WORD(alert)
|
MAKE_WORD(alert)
|
||||||
MAKE_WORD(pump)
|
MAKE_WORD(pump)
|
||||||
MAKE_WORD(heatsource)
|
MAKE_WORD(heatsource)
|
||||||
|
MAKE_WORD(scheduler)
|
||||||
|
|
||||||
// brands
|
// brands
|
||||||
MAKE_WORD_CUSTOM(bosch, "Bosch")
|
MAKE_WORD_CUSTOM(bosch, "Bosch")
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ MAKE_TRANSLATION(restart_cmd, "restart EMS-ESP", "Neustart", "", "", "", "", "",
|
|||||||
MAKE_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "", "", "", "", "", "Gelen telegramları ")
|
MAKE_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "", "", "", "", "", "Gelen telegramları ")
|
||||||
MAKE_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "", "", "", "", "", "Hepsini MQTTye gönder")
|
MAKE_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "", "", "", "", "", "Hepsini MQTTye gönder")
|
||||||
MAKE_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "", "", "", "", "", "Sistem Durumunu Göster")
|
MAKE_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "", "", "", "", "", "Sistem Durumunu Göster")
|
||||||
|
MAKE_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "", "", "", "", "", "")
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
MAKE_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS")
|
MAKE_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS")
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ void Mqtt::loop() {
|
|||||||
if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) {
|
if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) {
|
||||||
last_publish_other_ = (currentMillis / publish_time_other_) * publish_time_other_;
|
last_publish_other_ = (currentMillis / publish_time_other_) * publish_time_other_;
|
||||||
EMSESP::publish_other_values(); // switch and heatpump
|
EMSESP::publish_other_values(); // switch and heatpump
|
||||||
|
EMSESP::webSchedulerService.publish();
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (publish_time_sensor_ && (currentMillis - last_publish_sensor_ > publish_time_sensor_)) {
|
if (publish_time_sensor_ && (currentMillis - last_publish_sensor_ > publish_time_sensor_)) {
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ StateUpdateResult WebScheduler::update(JsonObject & root, WebScheduler & webSche
|
|||||||
Serial.println(COLOR_RESET);
|
Serial.println(COLOR_RESET);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (ScheduleItem & scheduleItem : webScheduler.scheduleItems) {
|
||||||
|
Command::erase_command(EMSdevice::DeviceType::SCHEDULER, scheduleItem.description.c_str());
|
||||||
|
}
|
||||||
webScheduler.scheduleItems.clear();
|
webScheduler.scheduleItems.clear();
|
||||||
|
|
||||||
if (root["schedule"].is<JsonArray>()) {
|
if (root["schedule"].is<JsonArray>()) {
|
||||||
@@ -84,11 +87,146 @@ StateUpdateResult WebScheduler::update(JsonObject & root, WebScheduler & webSche
|
|||||||
si.retry_cnt = 0xFF; // no starup retries
|
si.retry_cnt = 0xFF; // no starup retries
|
||||||
|
|
||||||
webScheduler.scheduleItems.push_back(si); // add to list
|
webScheduler.scheduleItems.push_back(si); // add to list
|
||||||
|
if (!webScheduler.scheduleItems.back().description.empty()) {
|
||||||
|
Command::add(
|
||||||
|
EMSdevice::DeviceType::SCHEDULER,
|
||||||
|
webScheduler.scheduleItems.back().description.c_str(),
|
||||||
|
[webScheduler](const char * value, const int8_t id) {
|
||||||
|
return EMSESP::webSchedulerService.command_setvalue(value, webScheduler.scheduleItems.back().description);
|
||||||
|
},
|
||||||
|
FL_(schedule_cmd),
|
||||||
|
CommandFlag::ADMIN_ONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
EMSESP::webSchedulerService.publish(true);
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set active by api command
|
||||||
|
bool WebSchedulerService::command_setvalue(const char * value, const std::string name) {
|
||||||
|
bool v;
|
||||||
|
if (!Helpers::value2bool(value, v)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) { scheduleItems = &webScheduler.scheduleItems; });
|
||||||
|
for (ScheduleItem & scheduleItem : *scheduleItems) {
|
||||||
|
if (scheduleItem.description == name) {
|
||||||
|
if (scheduleItem.active == v) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
scheduleItem.active = v;
|
||||||
|
publish_single(name.c_str(), v);
|
||||||
|
if (EMSESP::mqtt_.get_publish_onchange(0)) {
|
||||||
|
publish();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSchedulerService::publish_single(const char * name, const bool state) {
|
||||||
|
if (!Mqtt::publish_single() || name == nullptr || name[0] == '\0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
|
if (Mqtt::publish_single2cmd()) {
|
||||||
|
snprintf(topic, sizeof(topic), "%s/%s", F_(scheduler), name);
|
||||||
|
} else {
|
||||||
|
snprintf(topic, sizeof(topic), "%s%s/%s", F_(scheduler), "_data", name);
|
||||||
|
}
|
||||||
|
char payload[12];
|
||||||
|
Mqtt::queue_publish(topic, Helpers::render_boolean(payload, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
// publish to Mqtt
|
||||||
|
void WebSchedulerService::publish(const bool force) {
|
||||||
|
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) { scheduleItems = &webScheduler.scheduleItems; });
|
||||||
|
if (scheduleItems->size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Mqtt::publish_single() && force) {
|
||||||
|
for (const ScheduleItem & scheduleItem : *scheduleItems) {
|
||||||
|
publish_single(scheduleItem.description.c_str(), scheduleItem.active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE);
|
||||||
|
for (const ScheduleItem & scheduleItem : *scheduleItems) {
|
||||||
|
if (!scheduleItem.description.empty() && !doc.containsKey(scheduleItem.description)) {
|
||||||
|
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||||
|
doc[scheduleItem.description] = scheduleItem.active;
|
||||||
|
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
|
||||||
|
doc[scheduleItem.description] = scheduleItem.active ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
char result[12];
|
||||||
|
doc[scheduleItem.description] = Helpers::render_boolean(result, scheduleItem.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create HA config
|
||||||
|
if (Mqtt::ha_enabled() && force) {
|
||||||
|
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
|
||||||
|
char stat_t[50];
|
||||||
|
snprintf(stat_t, sizeof(stat_t), "%s/scheduler_data", Mqtt::base().c_str());
|
||||||
|
config["stat_t"] = stat_t;
|
||||||
|
|
||||||
|
char val_obj[50];
|
||||||
|
char val_cond[65];
|
||||||
|
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", scheduleItem.description.c_str());
|
||||||
|
snprintf(val_cond, sizeof(val_cond), "%s is defined", val_obj);
|
||||||
|
config["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + "}}";
|
||||||
|
|
||||||
|
char uniq_s[70];
|
||||||
|
snprintf(uniq_s, sizeof(uniq_s), "scheduler_%s", scheduleItem.description.c_str());
|
||||||
|
|
||||||
|
config["obj_id"] = uniq_s;
|
||||||
|
config["uniq_id"] = uniq_s; // same as object_id
|
||||||
|
config["name"] = scheduleItem.description.c_str();
|
||||||
|
|
||||||
|
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
|
char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
|
snprintf(topic, sizeof(topic), "switch/%s/scheduler_%s/config", Mqtt::basename().c_str(), scheduleItem.description.c_str());
|
||||||
|
snprintf(command_topic, sizeof(command_topic), "%s/scheduler/%s", Mqtt::basename().c_str(), scheduleItem.description.c_str());
|
||||||
|
config["cmd_t"] = command_topic;
|
||||||
|
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||||
|
config["pl_on"] = true;
|
||||||
|
config["pl_off"] = false;
|
||||||
|
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
|
||||||
|
config["pl_on"] = 1;
|
||||||
|
config["pl_off"] = 0;
|
||||||
|
} else {
|
||||||
|
char result[12];
|
||||||
|
config["pl_on"] = Helpers::render_boolean(result, true);
|
||||||
|
config["pl_off"] = Helpers::render_boolean(result, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject dev = config.createNestedObject("dev");
|
||||||
|
JsonArray ids = dev.createNestedArray("ids");
|
||||||
|
ids.add("ems-esp");
|
||||||
|
|
||||||
|
// add "availability" section
|
||||||
|
Mqtt::add_avty_to_doc(stat_t, config.as<JsonObject>(), val_cond);
|
||||||
|
Mqtt::queue_ha(topic, config.as<JsonObject>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mqtt::queue_publish("scheduler_data", doc.as<JsonObject>());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebSchedulerService::has_commands() {
|
||||||
|
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) { scheduleItems = &webScheduler.scheduleItems; });
|
||||||
|
if (scheduleItems->size() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const ScheduleItem & scheduleItem : *scheduleItems) {
|
||||||
|
if (!scheduleItem.description.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// execute scheduled command
|
// execute scheduled command
|
||||||
bool WebSchedulerService::command(const char * cmd, const char * data) {
|
bool WebSchedulerService::command(const char * cmd, const char * data) {
|
||||||
StaticJsonDocument<EMSESP_JSON_SIZE_SMALL> doc_input;
|
StaticJsonDocument<EMSESP_JSON_SIZE_SMALL> doc_input;
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
|
|||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void loop();
|
void loop();
|
||||||
|
void publish_single(const char * name, const bool state);
|
||||||
|
void publish(const bool force = false);
|
||||||
|
bool has_commands();
|
||||||
|
bool command_setvalue(const char * value, const std::string name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool command(const char * cmd, const char * data);
|
bool command(const char * cmd, const char * data);
|
||||||
|
|||||||
Reference in New Issue
Block a user