githubDante / deye-controller

DEYE Hybrid inverters library
MIT License
31 stars 5 forks source link

Documentation: more info on usage of the code #5

Open chinezbrun opened 10 months ago

chinezbrun commented 10 months ago

is a good approach and i will like to use it in my automation but i need more info on the usage of the code.

i.e in example provided the is a syntax like:

register = HoldingRegisters.BMSBatteryCapacity BMSBatteryCapacity is an example but where we can find the rest?

similar for WritableRegisters :)

githubDante commented 10 months ago

All registers are accessible as class properties and are listed even in the REPL on Tab+Tab


>>> from deye_controller.modbus.protocol import HoldingRegisters, WritableRegisters
>>> HoldingRegisters.BMS<Tab><Tab>
HoldingRegisters.BMSBatteryAlarm           HoldingRegisters.BMSBatterySOH             HoldingRegisters.BMSChargedVoltage         HoldingRegisters.BMSMaxChargingCurrent
HoldingRegisters.BMSBatteryCapacity        HoldingRegisters.BMSBatterySymbol          HoldingRegisters.BMSChargingCurrentLimit   HoldingRegisters.BMSMaxDischargeCurrent
HoldingRegisters.BMSBatteryCurrent         HoldingRegisters.BMSBatteryTemp            HoldingRegisters.BMSDischargeCurrentLimit  HoldingRegisters.BMSType
HoldingRegisters.BMSBatteryFaultLocation   HoldingRegisters.BMSBatteryVoltage         HoldingRegisters.BMSDischargedVoltage      

On read the values received from the inverter must be set as a value to the respective register e.g.

>>> HoldingRegisters.BMSBatteryTemp.value = 1410

You can use the group_registers() / map_response() helpers from utils to do that. The actual (human readable) values are returned from a call to the format() method e.g.


>>> HoldingRegisters.BMSBatteryTemp.format()
41.0

For writing the values are set via the set() method e.g.

>>> WritableRegisters.SellModeVolts1.set(51)

and then the actual modbus values which must be sent to the inverter are exposed as a property

>>> WritableRegisters.SellModeVolts1.to_modbus
5100
chinezbrun commented 10 months ago

thanks for your answer. indeed if you ar digging you can find them. the point was how to find info faster. but anyhow i get the point, i understand that you are upload the parameters on PostgreSQL. How? I have MariaDB and and i'm looking to have them there.

githubDante commented 10 months ago

How ... A call to a DB stored procedure (via asyncpg) with the collected data. The data is stored in the following format:

<date> | <inverter serial: numeric> | <metric_1: double precision[]> | <metric_2: double precision[]> | ...

Each index in the metric arrays corresponds to an hour/minute integer and is defined by:

    current_t := now();
    h_idx := extract(hour from current_t);
    m_idx := extract(minute from current_t);

    _idx_ := h_idx * 12 + m_idx / 5;

where the variables are declared as:

    declare h_idx int;
    declare m_idx int;
    declare _idx_ int;
    declare current_t timestamp without time zone;

This gives you 288 records/24h for each metric (column) and everything is stored in a single row, so you have really quick access to the data for the respective day. MariaDB doesn't seem like the right tool for the task as it does not support arrays as far as I know.

chinezbrun commented 10 months ago

thanks! Could your script provide output in JSON format?

githubDante commented 10 months ago

Not currently, but could be added easily (assuming we are talking about deye-read). Any suggestions about the JSON structure ?

chinezbrun commented 10 months ago

i will think about :) thanks you for openness !

githubDante commented 10 months ago

JSON output is supported in version 0.1.3. The output is available in the examples dir

chinezbrun commented 10 months ago

wow. super fast. looks good. sorry that i did not have the chance to provide you a suggestion for JSON structure... but instead of:

 {
  "logger": 2719999999,
  "serial": "2299999999",
  "data": [
  {
      "device_type": {
        "addr": 0,
        "value": "Hybrid3Phase",
        "unit": ""
      }
  }
  ,
    {
      "modbus_address": {
        "addr": 1,
        "value": 1,
        "unit": ""
      }
    }

  ]
}

why not:

{
  "logger": 2719999999,
  "serial": "2299999999",
  "data": [{
      "device_type": {
        "addr": 0,
        "value": "Hybrid3Phase",
        "unit": ""
      }
  ,
      "modbus_address": {
        "addr": 1,
        "value": 1,
        "unit": ""
      }
  }
]
}

and i believe will simplify the future reading of JSON data

githubDante commented 10 months ago

Current implementation allows you to read the output like this:

for item in output['data']:
    for k,v in item.items():
        if v['addr'] in [145, 214]:
            do_something_with(v['value'])

or if filtering by description is required:


for item in output['data']:
    for k,v in item.items():
        if k in ['solar_sell', 'bms_battery_SOC']:
            do_something_with(v['value'])

I don't see a problem with that. A loop over the ['data'] key would be needed anyway.

chinezbrun commented 10 months ago

clear. which is the file path? can be changed?

githubDante commented 10 months ago

Currently the output is written directly to stdout. On Linux it's easy to write it wherever you want by using > <path>/<filename> but probably we are talking for universal method for all platforms.

Expect an --out option in 0.1.4

chinezbrun commented 10 months ago

cool.good job!

githubDante commented 10 months ago

Do you know how to update from git in order to test this d91f755 :)

Just in case: pip install --upgrade git+https://github.com/githubDante/deye-controller.git

chinezbrun commented 10 months ago

done. what's the sintax?

githubDante commented 10 months ago

Sorry. Apparently update directly from git does not update the console scripts. Version 0.1.4 is already on pypi.org

pip install --upgrade deye-controller

and should be OK. The syntax is

deye-read --json --out <filename> <ip_addr> <logger_sn>

chinezbrun commented 9 months ago

Sorry. Apparently update directly from git does not update the console scripts. Version 0.1.4 is already on pypi.org

pip install --upgrade deye-controller

and should be OK. The syntax is

deye-read --json --out <filename> <ip_addr> <logger_sn>

it is working as expected! Thanks!

chinezbrun commented 9 months ago

hello. i can't find the Gen Port data in the JSON file . meaning: voltage, power per phases and total power. registries 661 - 667. this is useful when you have the microinverter coupled.

githubDante commented 9 months ago

Yes, all generator related registers are missing (saves time when there so many others). I'll try to add them in the next few days.

githubDante commented 9 months ago

Generator registers have been added. The documentation is little fishy about these. Let me know if there are any problems with them.

chinezbrun commented 9 months ago

ok. i need some good sunny days to test. do feel the need to open a separate issue on this topic?

chinezbrun commented 6 months ago

I confirm that microinverter output (generator) is displayed correct. Screenshot 2024-01-11 104953