Skip to content

Commit 89029df

Browse files
authored
Merge pull request #2953 from MichaelDvP/dev
customize device brand #2784
2 parents b153364 + 3463b68 commit 89029df

File tree

11 files changed

+306
-244
lines changed

11 files changed

+306
-244
lines changed

CHANGELOG_LATEST.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ For more details go to [emsesp.org](https://emsesp.org/).
77
## Added
88

99
- comfortpoint for BC400 [#2935](https://github.com/emsesp/EMS-ESP32/issues/2935)
10+
- customize device brand [#2784](https://github.com/emsesp/EMS-ESP32/issues/2784)
1011

1112
## Fixed
1213

interface/.typesafe-i18n.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"adapter": "react",
33
"baseLocale": "pl",
4-
"$schema": "https://unpkg.com/typesafe-i18n@5.26.2/schema/typesafe-i18n.json"
4+
"$schema": "https://unpkg.com/typesafe-i18n@5.27.1/schema/typesafe-i18n.json"
55
}

interface/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
"@alova/adapter-xhr": "2.3.1",
2727
"@emotion/react": "^11.14.0",
2828
"@emotion/styled": "^11.14.1",
29-
"@mui/icons-material": "^7.3.7",
30-
"@mui/material": "^7.3.7",
29+
"@mui/icons-material": "^7.3.8",
30+
"@mui/material": "^7.3.8",
3131
"@preact/compat": "^18.3.1",
3232
"@table-library/react-table-library": "4.1.15",
3333
"alova": "3.5.0",
@@ -43,7 +43,7 @@
4343
"react-icons": "^5.5.0",
4444
"react-router": "^7.13.0",
4545
"react-toastify": "^11.0.5",
46-
"typesafe-i18n": "^5.26.2",
46+
"typesafe-i18n": "^5.27.1",
4747
"typescript": "^5.9.3"
4848
},
4949
"devDependencies": {
@@ -52,8 +52,8 @@
5252
"@preact/compat": "^18.3.1",
5353
"@preact/preset-vite": "^2.10.3",
5454
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
55-
"@types/node": "^25.2.2",
56-
"@types/react": "^19.2.13",
55+
"@types/node": "^25.2.3",
56+
"@types/react": "^19.2.14",
5757
"@types/react-dom": "^19.2.3",
5858
"axe-core": "^4.11.1",
5959
"concurrently": "^9.2.1",
@@ -62,10 +62,10 @@
6262
"prettier": "^3.8.1",
6363
"rollup-plugin-visualizer": "^6.0.5",
6464
"terser": "^5.46.0",
65-
"typescript-eslint": "^8.54.0",
65+
"typescript-eslint": "^8.55.0",
6666
"vite": "^7.3.1",
6767
"vite-plugin-imagemin": "^0.6.1",
68-
"vite-tsconfig-paths": "^6.1.0"
68+
"vite-tsconfig-paths": "^6.1.1"
6969
},
70-
"packageManager": "pnpm@10.29.2"
70+
"packageManager": "pnpm@10.29.3"
7171
}

interface/pnpm-lock.yaml

Lines changed: 174 additions & 174 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

interface/src/app/main/Customizations.tsx

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,14 @@ const Customizations = () => {
111111
const [selectedDeviceTypeNameURL, setSelectedDeviceTypeNameURL] =
112112
useState<string>(''); // needed for API URL
113113
const [selectedDeviceName, setSelectedDeviceName] = useState<string>('');
114+
const [selectedDeviceBrand, setSelectedDeviceBrand] = useState<string>('');
114115

115116
const { send: sendResetCustomizations } = useRequest(resetCustomizations(), {
116117
immediate: false
117118
});
118119

119120
const { send: sendDeviceName } = useRequest(
120-
(data: { id: number; name: string }) => writeDeviceName(data),
121+
(data: { id: number; name: string; brand: string }) => writeDeviceName(data),
121122
{
122123
immediate: false
123124
}
@@ -267,6 +268,7 @@ const Customizations = () => {
267268
if (device) {
268269
setSelectedDeviceTypeNameURL(device.url || '');
269270
setSelectedDeviceName(device.n);
271+
setSelectedDeviceBrand(device.b);
270272
}
271273
setNumChanges(0);
272274
setRestartNeeded(false);
@@ -442,7 +444,11 @@ const Customizations = () => {
442444
}, [devices, deviceEntities, selectedDevice, sendCustomizationEntities, LL]);
443445

444446
const renameDevice = useCallback(async () => {
445-
await sendDeviceName({ id: selectedDevice, name: selectedDeviceName })
447+
await sendDeviceName({
448+
id: selectedDevice,
449+
name: selectedDeviceName,
450+
brand: selectedDeviceBrand
451+
})
446452
.then(() => {
447453
toast.success(LL.UPDATED_OF(LL.NAME(1)));
448454
})
@@ -453,7 +459,14 @@ const Customizations = () => {
453459
setRename(false);
454460
await fetchCoreData();
455461
});
456-
}, [selectedDevice, selectedDeviceName, sendDeviceName, LL, fetchCoreData]);
462+
}, [
463+
selectedDevice,
464+
selectedDeviceName,
465+
selectedDeviceBrand,
466+
sendDeviceName,
467+
LL,
468+
fetchCoreData
469+
]);
457470

458471
const renderDeviceList = () => (
459472
<>
@@ -462,15 +475,26 @@ const Customizations = () => {
462475
</Box>
463476
<Box display="flex" flexWrap="wrap" alignItems="center" gap={2}>
464477
{rename ? (
465-
<TextField
466-
name="device"
467-
label={LL.EMS_DEVICE()}
468-
fullWidth
469-
variant="outlined"
470-
value={selectedDeviceName}
471-
onChange={(e) => setSelectedDeviceName(e.target.value)}
472-
margin="normal"
473-
/>
478+
<>
479+
<TextField
480+
name="device"
481+
label={LL.EMS_DEVICE()}
482+
style={{ minWidth: '48%' }}
483+
variant="outlined"
484+
value={selectedDeviceName}
485+
onChange={(e) => setSelectedDeviceName(e.target.value)}
486+
margin="normal"
487+
/>
488+
<TextField
489+
name="brand"
490+
label={LL.BRAND()}
491+
style={{ minWidth: '48%' }}
492+
variant="outlined"
493+
value={selectedDeviceBrand}
494+
onChange={(e) => setSelectedDeviceBrand(e.target.value)}
495+
margin="normal"
496+
/>
497+
</>
474498
) : (
475499
<TextField
476500
name="device"

src/core/emsdevice.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ const char * EMSdevice::tag_to_mqtt(int8_t tag) {
7272
return (DeviceValue::DeviceValueTAG_mqtt[tag > DeviceValue::NUM_TAGS ? 0 : tag]);
7373
}
7474

75+
uint8_t EMSdevice::tag_to_flag(const uint8_t tag) {
76+
if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) {
77+
return CommandFlag::CMD_FLAG_HC;
78+
} else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) {
79+
return CommandFlag::CMD_FLAG_DHW;
80+
} else if (tag >= DeviceValueTAG::TAG_HS1 && tag <= DeviceValueTAG::TAG_HS16) {
81+
return CommandFlag::CMD_FLAG_HS;
82+
} else if (tag >= DeviceValueTAG::TAG_AHS1 && tag <= DeviceValueTAG::TAG_AHS1) {
83+
return CommandFlag::CMD_FLAG_AHS;
84+
} else if (tag >= DeviceValueTAG::TAG_SRC1 && tag <= DeviceValueTAG::TAG_SRC16) {
85+
return CommandFlag::CMD_FLAG_SRC;
86+
}
87+
return 0;
88+
}
89+
7590
// convert UOM to a char string - translating only for hours/minutes/seconds
7691
const char * EMSdevice::uom_to_string(uint8_t uom) {
7792
switch (uom) {
@@ -90,6 +105,9 @@ const char * EMSdevice::uom_to_string(uint8_t uom) {
90105
}
91106

92107
const char * EMSdevice::brand_to_char() {
108+
if (!custom_brand().empty()) {
109+
return custom_brand().c_str();
110+
}
93111
switch (brand_) {
94112
case EMSdevice::Brand::BOSCH:
95113
return F_(bosch);
@@ -316,7 +334,7 @@ std::string EMSdevice::to_string() {
316334
return std::string(name()) + " (DeviceID:" + Helpers::hextoa(device_id_) + ")";
317335
}
318336

319-
if (brand_ == Brand::NO_BRAND) {
337+
if (brand_ == Brand::NO_BRAND && custom_brand().empty()) {
320338
return std::string(name()) + " (DeviceID:" + Helpers::hextoa(device_id_) + ", ProductID:" + Helpers::itoa(product_id_) + ", Version:" + version_ + ")";
321339
}
322340

@@ -332,7 +350,7 @@ std::string EMSdevice::to_string_version() {
332350
// returns out brand + device name
333351
// translated
334352
std::string EMSdevice::to_string_short() {
335-
if (brand_ == Brand::NO_BRAND) {
353+
if (brand_ == Brand::NO_BRAND && custom_brand().empty()) {
336354
return std::string(device_type_2_device_name_translated()) + ": " + name();
337355
}
338356

@@ -650,25 +668,21 @@ void EMSdevice::add_device_value(int8_t tag, // to b
650668

651669
// add a new command if it has a function attached
652670
if (has_cmd) {
653-
uint8_t flags = CommandFlag::ADMIN_ONLY; // executing commands require admin privileges
654-
655-
if (tag >= DeviceValueTAG::TAG_HC1 && tag <= DeviceValueTAG::TAG_HC8) {
656-
flags |= CommandFlag::CMD_FLAG_HC;
657-
} else if (tag >= DeviceValueTAG::TAG_DHW1 && tag <= DeviceValueTAG::TAG_DHW10) {
658-
flags |= CommandFlag::CMD_FLAG_DHW;
659-
} else if (tag >= DeviceValueTAG::TAG_HS1 && tag <= DeviceValueTAG::TAG_HS16) {
660-
flags |= CommandFlag::CMD_FLAG_HS;
661-
} else if (tag >= DeviceValueTAG::TAG_AHS1 && tag <= DeviceValueTAG::TAG_AHS1) {
662-
flags |= CommandFlag::CMD_FLAG_AHS;
663-
} else if (tag >= DeviceValueTAG::TAG_SRC1 && tag <= DeviceValueTAG::TAG_SRC16) {
664-
flags |= CommandFlag::CMD_FLAG_SRC;
665-
}
666-
671+
uint8_t flags = CommandFlag::ADMIN_ONLY | tag_to_flag(tag); // executing commands require admin privileges
667672
// add the command to our library
668673
Command::add(device_type_, device_id_, short_name, f, fullname, flags);
669674
}
670675
}
671676

677+
void EMSdevice::erase_device_values() {
678+
for (auto & dv : devicevalues_) {
679+
if (dv.has_cmd) {
680+
Command::erase_command(device_type_, dv.short_name, tag_to_flag(dv.tag));
681+
}
682+
}
683+
devicevalues_.clear();
684+
}
685+
672686
// single list of options
673687
void EMSdevice::register_device_value(int8_t tag,
674688
void * value_p,

src/core/emsdevice.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class EMSdevice {
5555
static const char * tag_to_mqtt(int8_t tag);
5656
static uint8_t decode_brand(uint8_t value);
5757
static bool export_values(uint8_t device_type, JsonObject output, const int8_t id, const uint8_t output_target);
58+
static uint8_t tag_to_flag(const uint8_t tag);
5859

5960
// non static functions
6061

@@ -124,6 +125,14 @@ class EMSdevice {
124125
return custom_name_;
125126
}
126127

128+
// set custom brand
129+
void custom_brand(std::string const & custom_brand) {
130+
custom_brand_ = custom_brand;
131+
}
132+
133+
std::string custom_brand() const {
134+
return custom_brand_;
135+
}
127136
// set device model
128137
void model(std::string const & model) {
129138
model_ = model;
@@ -282,6 +291,8 @@ class EMSdevice {
282291
int16_t min,
283292
uint32_t max);
284293

294+
void erase_device_values();
295+
285296
void
286297
register_device_value(int8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom, const cmd_function_p f);
287298

@@ -524,12 +535,13 @@ class EMSdevice {
524535
uint8_t device_id_ = 0;
525536
uint8_t product_id_ = 0;
526537
char version_[6];
527-
const char * default_name_; // the fixed name the EMS model taken from the device library
528-
std::string custom_name_ = ""; // custom name
529-
std::string model_ = ""; // model, taken from the 0x01 telegram. see process_deviceName()
530-
uint8_t flags_ = 0;
531-
uint8_t brand_ = Brand::NO_BRAND;
532-
bool active_ = true;
538+
const char * default_name_; // the fixed name the EMS model taken from the device library
539+
std::string custom_name_ = ""; // custom name
540+
std::string custom_brand_ = ""; // custom brand
541+
std::string model_ = ""; // model, taken from the 0x01 telegram. see process_deviceName()
542+
uint8_t flags_ = 0;
543+
uint8_t brand_ = Brand::NO_BRAND;
544+
bool active_ = true;
533545

534546
bool ha_config_done_ = false;
535547
bool has_update_ = false;

src/core/emsesp.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
13101310
if (product_id == 0 || (*it)->product_id() != 0) { // update only with valid product_id
13111311
return true;
13121312
}
1313+
(*it)->erase_device_values();
13131314
emsdevices.erase(it); // erase the old device without product_id and re detect
13141315
break;
13151316
}
@@ -1450,6 +1451,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
14501451
if ((e.device_id == device_id) && (e.product_id == product_id)) {
14511452
LOG_DEBUG("Have customizations for %s with deviceID 0x%02X productID %d", e.custom_name.c_str(), device_id, product_id);
14521453
emsdevices.back()->custom_name(e.custom_name);
1454+
emsdevices.back()->custom_brand(e.custom_brand);
14531455
break;
14541456
}
14551457
}
@@ -1760,7 +1762,7 @@ void EMSESP::start() {
17601762
nvs_.begin("ems-esp", false, "nvs"); // fallback to small nvs
17611763
}
17621764

1763-
LOG_DEBUG("NVS device information: %s", system_.getBBQKeesGatewayDetails().isEmpty() ? "not set" : system_.getBBQKeesGatewayDetails().c_str());
1765+
LOG_DEBUG("Fuse device information: %s", system_.getBBQKeesGatewayDetails().isEmpty() ? "not set" : system_.getBBQKeesGatewayDetails().c_str());
17641766

17651767
webSettingsService.begin(); // load EMS-ESP Application settings
17661768

src/emsesp_version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define EMSESP_APP_VERSION "3.8.2-dev.3"
1+
#define EMSESP_APP_VERSION "3.8.2-dev.4"

0 commit comments

Comments
 (0)