mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
HP inputs #600, custom entity bool display
This commit is contained in:
@@ -226,13 +226,11 @@ const SettingsEntities: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function formatValue(value: any, uom: number) {
|
function formatValue(value: any, uom: number) {
|
||||||
if (value === undefined) {
|
return value === undefined || uom === undefined
|
||||||
return '';
|
? ''
|
||||||
}
|
: typeof value === 'number'
|
||||||
if (uom === 0) {
|
? new Intl.NumberFormat().format(value) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
|
||||||
return new Intl.NumberFormat().format(value);
|
: value;
|
||||||
}
|
|
||||||
return new Intl.NumberFormat().format(value) + ' ' + DeviceValueUOM_s[uom];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showHex(value: string, digit: number) {
|
function showHex(value: string, digit: number) {
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ export interface EntityItem {
|
|||||||
factor: number;
|
factor: number;
|
||||||
uom: number;
|
uom: number;
|
||||||
val_type: number;
|
val_type: number;
|
||||||
value?: number;
|
value?: any;
|
||||||
o_name?: string;
|
o_name?: string;
|
||||||
o_device_id?: string;
|
o_device_id?: string;
|
||||||
o_type_id?: string;
|
o_type_id?: string;
|
||||||
|
|||||||
@@ -1296,31 +1296,25 @@ void Boiler::process_HpInput(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// Boiler(0x08) -> All(0x00), ?(0x0486), data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 (offset 25)
|
// Boiler(0x08) -> All(0x00), ?(0x0486), data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 (offset 25)
|
||||||
// Boiler(0x08) -> All(0x00), ?(0x0486), data: 00 00 (offset 51)
|
// Boiler(0x08) -> All(0x00), ?(0x0486), data: 00 00 (offset 51)
|
||||||
void Boiler::process_HpInConfig(std::shared_ptr<const Telegram> telegram) {
|
void Boiler::process_HpInConfig(std::shared_ptr<const Telegram> telegram) {
|
||||||
char option[12];
|
char option[16];
|
||||||
// inputs 1,2,3 <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv>]
|
// inputs 1,2,3 <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv><prot><pres><mod>]
|
||||||
|
uint8_t index[] = {0, 3, 6, 9, 12, 15, 18, 21, 24, 39, 36, 30, 27};
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
for (uint8_t j = 0; j < 9; j++) {
|
for (uint8_t j = 0; j < 13; j++) {
|
||||||
option[j] = hpInput[i].option[j] - '0';
|
telegram->read_value(option[j], index[j] + i); // offsets 0-26
|
||||||
telegram->read_value(option[j], j * 3 + i); // offsets 0-26
|
option[j] = j < 12 ? option[j] ? '1' : '0' : option[j];
|
||||||
option[j] = option[j] ? '1' : '0';
|
|
||||||
}
|
}
|
||||||
option[9] = hpInput[i].option[9] - '0';
|
Helpers::smallitoa(&option[12], (uint16_t)option[12]);
|
||||||
telegram->read_value(option[9], 39 + i); // add offsets 39-41
|
has_update(hpInput[i].option, option, 16);
|
||||||
option[9] = option[9] ? '1' : '0';
|
|
||||||
option[10] = '\0'; // terminate string
|
|
||||||
has_update(hpInput[i].option, option, 11);
|
|
||||||
}
|
}
|
||||||
// input 4 <inv>[<comp><aux><cool><heat><dhw><pv>]
|
// input 4 <inv>[<comp><aux><cool><heat><dhw><pv><prot><pres><mod>]
|
||||||
for (uint8_t j = 0; j < 6; j++) {
|
uint8_t index4[] = {42, 43, 44, 45, 46, 47, 52, 50, 49, 48};
|
||||||
option[j] = hpInput[3].option[j] - '0';
|
for (uint8_t j = 0; j < 10; j++) {
|
||||||
telegram->read_value(option[j], 42 + j); // offsets 42-47
|
telegram->read_value(option[j], index4[j]); // offsets 42-47
|
||||||
option[j] = option[j] ? '1' : '0';
|
option[j] = j < 10 ? option[j] ? '1' : '0' : option[j];
|
||||||
}
|
}
|
||||||
option[6] = hpInput[3].option[6] - '0';
|
Helpers::smallitoa(&option[9], (uint16_t)option[9]);
|
||||||
telegram->read_value(option[6], 52); // add offsets 52 (pv)
|
has_update(hpInput[3].option, option, 13);
|
||||||
option[6] = option[6] ? '1' : '0';
|
|
||||||
option[7] = '\0'; // terminate string
|
|
||||||
has_update(hpInput[3].option, option, 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Boiler(0x08) -W-> Me(0x0B), HpHeaterConfig(0x0485)
|
// Boiler(0x08) -W-> Me(0x0B), HpHeaterConfig(0x0485)
|
||||||
@@ -2311,44 +2305,41 @@ bool Boiler::set_emergency_ops(const char * value, const int8_t id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Boiler::set_HpInLogic(const char * value, const int8_t id) {
|
bool Boiler::set_HpInLogic(const char * value, const int8_t id) {
|
||||||
if (id == 0 || id > 4) {
|
if (id == 0 || id > 4 || strlen(value) > 15) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool v;
|
bool v;
|
||||||
if (Helpers::value2bool(value, v)) {
|
if (strlen(value) == 1 && Helpers::value2bool(value, v)) {
|
||||||
write_command(0x486, id == 4 ? 42 : id - 1, v ? 1 : 0, 0x486);
|
write_command(0x486, id == 4 ? 42 : id - 1, v ? 1 : 0, 0x486);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (strlen(value) == 10 && id != 4) {
|
char option[] = {"xxxxxxxxxxxxxxx"};
|
||||||
uint8_t v[10];
|
strncpy(option, value, strlen(value)); // copy without termination
|
||||||
for (uint8_t i = 0; i < 10; i++) {
|
// inputs 1,2,3 <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv><prot><pres><mod>]
|
||||||
v[i] = value[i] - '0';
|
if (id < 4) {
|
||||||
if (v[i] > 1) {
|
uint8_t index[] = {0, 3, 6, 9, 12, 15, 18, 21, 24, 39, 36, 30};
|
||||||
return false;
|
for (uint8_t i = 0; i < 12; i++) {
|
||||||
|
if (option[i] == '0' || option[i] == '1') {
|
||||||
|
write_command(0x486, index[i] + id - 1, option[i] - '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < 9; i++) {
|
if (option[12] >= '0' && option[12] <= '9') {
|
||||||
write_command(0x486, i * 3 + id - 1, v[i]);
|
write_command(0x486, 27, (uint8_t)atoi(&option[12]));
|
||||||
}
|
}
|
||||||
write_command(0x486, 39 + id - 1, v[9]);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// input 4
|
|
||||||
if (strlen(value) == 7 && id == 4) {
|
// input 4: <inv>[<comp><aux><cool><heat><dhw><pv><prot><pres><mod>]
|
||||||
uint8_t v[10];
|
uint8_t index4[] = {42, 43, 44, 45, 46, 47, 52, 50, 49};
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 9; i++) {
|
||||||
v[i] = value[i] - '0';
|
if (option[i] == '0' || option[i] == '1') {
|
||||||
if (v[i] > 1) {
|
write_command(0x486, index4[i], option[i] - '0');
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < 7; i++) {
|
|
||||||
write_command(0x486, 42 + i, v[i]);
|
|
||||||
}
|
|
||||||
write_command(0x486, 52, v[7]);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
if (option[9] >= '0' && option[9] <= '9') {
|
||||||
|
write_command(0x486, 48, (uint8_t)atoi(&option[9]));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Boiler::set_maxHeat(const char * value, const int8_t id) {
|
bool Boiler::set_maxHeat(const char * value, const int8_t id) {
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ class Boiler : public EMSdevice {
|
|||||||
// Inputs
|
// Inputs
|
||||||
struct {
|
struct {
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
char option[12]; // logic, block_comp, block_dhw, block_heat, block_cool, overheat_protect, evu_blocktime1,2,3, block_heater, Solar
|
char option[16]; // logic, block_comp, block_dhw, block_heat, block_cool, overheat_protect, evu_blocktime1,2,3, block_heater, Solar, brine lowpressure, brine pump modulation
|
||||||
} hpInput[4];
|
} hpInput[4];
|
||||||
|
|
||||||
// Heater limits
|
// Heater limits
|
||||||
|
|||||||
@@ -199,8 +199,8 @@ MAKE_NOTRANSLATION(tpl_switchtime, "Format: <nn> [ not_set | day hh:mm on|off ]"
|
|||||||
MAKE_NOTRANSLATION(tpl_switchtime1, "Format: <nn> [ not_set | day hh:mm Tn ]")
|
MAKE_NOTRANSLATION(tpl_switchtime1, "Format: <nn> [ not_set | day hh:mm Tn ]")
|
||||||
MAKE_NOTRANSLATION(tpl_holidays, "Format: < dd.mm.yyyy-dd.mm.yyyy >")
|
MAKE_NOTRANSLATION(tpl_holidays, "Format: < dd.mm.yyyy-dd.mm.yyyy >")
|
||||||
MAKE_NOTRANSLATION(tpl_date, "Format: < dd.mm.yyyy >")
|
MAKE_NOTRANSLATION(tpl_date, "Format: < dd.mm.yyyy >")
|
||||||
MAKE_NOTRANSLATION(tpl_input, "Format: <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv>]")
|
MAKE_NOTRANSLATION(tpl_input, "Format: <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv><prot><press><pump%>]")
|
||||||
MAKE_NOTRANSLATION(tpl_input4, "Format: <inv>[<comp><aux><cool><heat><dhw><pv>]")
|
MAKE_NOTRANSLATION(tpl_input4, "Format: <inv>[<comp><aux><cool><heat><dhw><pv><prot><press><pump%>]")
|
||||||
|
|
||||||
#if defined(EMSESP_TEST)
|
#if defined(EMSESP_TEST)
|
||||||
MAKE_NOTRANSLATION(test_cmd, "run a test")
|
MAKE_NOTRANSLATION(test_cmd, "run a test")
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void WebEntity::read(WebEntity & webEntity, JsonObject & root) {
|
|||||||
ei["uom"] = entityItem.uom;
|
ei["uom"] = entityItem.uom;
|
||||||
ei["val_type"] = entityItem.valuetype;
|
ei["val_type"] = entityItem.valuetype;
|
||||||
ei["write"] = entityItem.writeable;
|
ei["write"] = entityItem.writeable;
|
||||||
EMSESP::webEntityService.render_value(ei, entityItem, true);
|
EMSESP::webEntityService.render_value(ei, entityItem, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,13 +139,15 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
|
|||||||
}
|
}
|
||||||
|
|
||||||
// output of a single value
|
// output of a single value
|
||||||
void WebEntityService::render_value(JsonObject & output, EntityItem entity, const bool useVal) {
|
void WebEntityService::render_value(JsonObject & output, EntityItem entity, const bool useVal, const bool web) {
|
||||||
char payload[12];
|
char payload[12];
|
||||||
std::string name = useVal ? "value" : entity.name;
|
std::string name = useVal ? "value" : entity.name;
|
||||||
switch (entity.valuetype) {
|
switch (entity.valuetype) {
|
||||||
case DeviceValueType::BOOL:
|
case DeviceValueType::BOOL:
|
||||||
if ((uint8_t)entity.val != EMS_VALUE_BOOL_NOTSET) {
|
if ((uint8_t)entity.val != EMS_VALUE_BOOL_NOTSET) {
|
||||||
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
if (web) {
|
||||||
|
output[name] = Helpers::render_boolean(payload, (uint8_t)entity.val, true);
|
||||||
|
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||||
output[name] = (uint8_t)entity.val ? true : false;
|
output[name] = (uint8_t)entity.val ? true : false;
|
||||||
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
|
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
|
||||||
output[name] = (uint8_t)entity.val ? 1 : 0;
|
output[name] = (uint8_t)entity.val ? 1 : 0;
|
||||||
@@ -358,7 +360,7 @@ void WebEntityService::generate_value_web(JsonObject & output) {
|
|||||||
switch (entity.valuetype) {
|
switch (entity.valuetype) {
|
||||||
case DeviceValueType::BOOL: {
|
case DeviceValueType::BOOL: {
|
||||||
char s[12];
|
char s[12];
|
||||||
obj["v"] = Helpers::render_boolean(s, (uint8_t)entity.val);
|
obj["v"] = Helpers::render_boolean(s, (uint8_t)entity.val, true);
|
||||||
JsonArray l = obj.createNestedArray("l");
|
JsonArray l = obj.createNestedArray("l");
|
||||||
l.add(Helpers::render_boolean(s, false, true));
|
l.add(Helpers::render_boolean(s, false, true));
|
||||||
l.add(Helpers::render_boolean(s, true, true));
|
l.add(Helpers::render_boolean(s, true, true));
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class WebEntityService : public StatefulService<WebEntity> {
|
|||||||
bool get_value_info(JsonObject & output, const char * cmd);
|
bool get_value_info(JsonObject & output, const char * cmd);
|
||||||
bool get_value(std::shared_ptr<const Telegram> telegram);
|
bool get_value(std::shared_ptr<const Telegram> telegram);
|
||||||
void fetch();
|
void fetch();
|
||||||
void render_value(JsonObject & output, EntityItem entity, const bool useVal = false);
|
void render_value(JsonObject & output, EntityItem entity, const bool useVal = false, const bool web = false);
|
||||||
uint8_t count_entities();
|
uint8_t count_entities();
|
||||||
void generate_value_web(JsonObject & output);
|
void generate_value_web(JsonObject & output);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user