kr0ner / OneESP32ToRuleThemAll

12 stars 2 forks source link

Change property from enum to unordered map & add verbose logging #13

Open croessi opened 1 month ago

croessi commented 1 month ago

I did a lot of experimenting, but in the end I was able to move the definition of registers, names and their types into one single unordered map. One of the biggest adavantages is, that the definition is now only happening in one single file:

    const std::unordered_map<std::string, Property> propertyMap {
        {"kINDEX_NOT_FOUND",{0x0000,et_default}},
        {"kFEHLERMELDUNG",{0x0001,et_default}},
        {"kKESSELSOLLTEMP",{0x0002,et_dec_val}},
        {"kSPEICHERSOLLTEMP",{0x0003,et_dec_val}},
        {"kVORLAUFSOLLTEMP",{0x0004,et_dec_val}},
        {"kRAUMSOLLTEMP_I",{0x0005,et_dec_val}},
        {"kRAUMSOLLTEMP_II",{0x0006,et_dec_val}},
        {"kRAUMSOLLTEMP_III",{0x0007,et_dec_val}},
        {"kRAUMSOLLTEMP_NACHT",{0x0008,et_dec_val}},
        {"kUHRZEIT",{0x0009,et_zeit}},
        {"kDATUM",{0x000a,et_datum}},
        {"kGERAETE_ID",{0x000b,et_dev_id}},

However, If i put all ~3000 registers in the map, OTA flashing behaves weird for me: Although flash is only about 60%, it seems the ESP is not taking the new program, but switches back to his previous flash content. With the ~200 entries in this pull request, everything is fine.

Additionally this pull request add a verbose output, making it easier to do reverse engineering.

kr0ner commented 1 month ago

Hi @croessi. I really appreciate your effort on this :) Can you create a sperate PR for the changes to simplevariant? https://github.com/kr0ner/OneESP32ToRuleThemAll/pull/13/files#diff-301dbb15d5160b0dbbf2ebee578392c0740580231dc3233b95ff3cef1923d623R19-R27

The other approach with the map I must say is not the way I want to go. We already know about the limitations and the undefined behavior when we have many entries. Also referencing properties by their name as strings is error prone and you will find out about typos only during runtime. From memory perspective we don't gain anything, because every instruction referring to a property will require a string to be stored in memory and also looks less clean then just Property::kSomeValue. So I'd propose to go with my enum solution, since it does not require any changes to the business logic, but saves us the third place where we need to add mappings. going this way there is a small overhead when adding new properties, but referencing existing ones is much nicer.

croessi commented 3 weeks ago

I agree with the drawback of an unordered map. However, I want to make it as easy to add new mappings and to minimize the probability of errors (especially if we allow multiple contributers to add and correct mappings). So I gave it some thought and found another way with a literal type for the property:

class PropertyType {
public:
    const char* name;
    uint16_t address;
    Type type;
    ....

and a class holding the properties

class Property {
public:
static constexpr PropertyType kINDEX_NOT_FOUND = PropertyType("kINDEX_NOT_FOUND",0x0000,et_default);
static constexpr PropertyType kFEHLERMELDUNG = PropertyType("kFEHLERMELDUNG",0x0001,et_default);
...

The literal type supports direct initialization as constexpr, allowing to definie new mappings within a single line of code! This should reduce the probability of mapping errors and easen maintainability a lot. I did test it within my setup and works very well. See the other pull request for the full changes.