Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parent Inverter Modbus TCP not working #64

Open
rmnsrrs opened this issue Dec 9, 2022 · 8 comments
Open

Parent Inverter Modbus TCP not working #64

rmnsrrs opened this issue Dec 9, 2022 · 8 comments

Comments

@rmnsrrs
Copy link

rmnsrrs commented Dec 9, 2022

I am trying to query a system with 2 inverters.
If I run the example script with each unit (1 & 2) then it is working.
However the following code does not work and query twice the inverter 1.
I notice that if I change the order in the list I then get twice the inverter 2.
In other word I get the 1st inverter in the list twice and never the 2nd one.
If that normal behavior ? How should I use parent parameter ?
Thanks

#!/usr/bin/env python3
import argparse
import json

import solaredge_modbus

class solarEdge_extractor(object):
    def __init__(self, host, port):
        self.inverters = [solaredge_modbus.Inverter(
            host=host,
            port=port,
            unit=1
        )]
        self.inverters.append(solaredge_modbus.Inverter(
            parent=self.inverters[0],
            unit=2
        ))

    def get_data(self):
        values = {}
        values["inverters"] = {}
        values["meters"] = {}
        values["batteries"] = {}
        for i,c_i in enumerate(self.inverters):
            print(c_i.read("current"))
            values["inverters"][i] = c_i.read_all()

            meters = c_i.meters()
            batteries = c_i.batteries()
            values["meters"][i] = {}
            for meter, params in meters.items():
                meter_values = params.read_all()
                values["meters"][i][meter] = meter_values

            values["batteries"][i] = {}
            for battery, params in batteries.items():
                battery_values = params.read_all()
                values["batteries"][i][battery] = battery_values

        return json.dumps(values, indent=4)

if __name__ == "__main__":
    argparser = argparse.ArgumentParser()
    argparser.add_argument("host", type=str, help="Modbus TCP address")
    argparser.add_argument("port", type=int, help="Modbus TCP port")
    args = argparser.parse_args()
    se = solarEdge_extractor(args.host, args.port)
    print(se.get_data())
@nmakel
Copy link
Owner

nmakel commented Dec 9, 2022

Looks like this should work. Have you grabbed the latest version from github? A commit from 10 days ago, which isn't in the pypi release yet, should have fixed this.

Edit: this is the commit in question.

@rmnsrrs
Copy link
Author

rmnsrrs commented Dec 9, 2022

You were correct, It did fix the issue. However the meter is now empty. While it worked perfectly before. It detects "Meter1" but return an empty dict. Any chance you would know why ?

@nmakel
Copy link
Owner

nmakel commented Dec 9, 2022

Would you mind trying it explicitly, through the intepreter for example, to rule out any funny business with your looping and dict assignments?

  • Create the first inverter object
  • Read meters from first and print their values
  • Create second inverter object with first as parent
  • Read meters from second and print their values
  • Read meters from the first inverter again

@rmnsrrs
Copy link
Author

rmnsrrs commented Dec 9, 2022

Yes sorry, it was not clear. But I am always testing with the example given on the git.
When calling unit 2, I can see the meter is "Meter1" but meter_values is an empty dict {} (cf below)
Also I reverted back to the pipy version and the meter is working fine again.
It seems that there is bug introduced in between the pipy version and the latest github

    for meter, params in meters.items():
        meter_values = params.read_all()
        values["meters"][meter] = meter_values
        print(meter_values)

@nmakel
Copy link
Owner

nmakel commented Dec 9, 2022

I understand. But what I'm asking you is to run through all of the steps one by one. This way we can see where and when things go wrong. Perhaps somewhere a unit is not being passed correctly, but by only looking at the code I'm not seeing it. Debug output, printing results from every function, printing every object (inverter, meter), would be useful.

@rmnsrrs
Copy link
Author

rmnsrrs commented Dec 9, 2022

I can confirm after several tests that this is only due do adding these lines:

         if unit:
            self.unit = unit
        else:
            self.unit = parent.unit

Problem: Meter is not read correctly. and return empty dict. Thus by looking in places where unit is used for meter, we should find out the problem.

Note : In my case the Meter is on unit=2

Regarding the previous steps:

  • Create the first inverter object
  • Read meters from first and print their values
    ==> Reading the meter, return Meter1 but its content is an empty dict

@jgyates
Copy link

jgyates commented Sep 10, 2023

I am having a similar issue. the problem is that in the above lines:

     if unit:
        self.unit = unit
    else:
        self.unit = parent.unit

If unit is anything other than 1 then it is false. Here is the output form the python console:

    >>> import solaredge_modbus
    >>> inv1 = solaredge_modbus.Inverter(host = "192.168.1.51", port=1502, unit =1, timeout=3)
    >>> print(inv1)
    Inverter(192.168.1.51:1502, connectionType.TCP: timeout=3, retries=3, unit=0x1)
    >>> inv2 = solaredge_modbus.Inverter(parent=inv1, unit = 2)
    >>> print(inv2)
    Inverter(192.168.1.51:1502, connectionType.TCP: timeout=3, retries=3, unit=0x1)
    >>> inv2.unit == True
    True
    >>> 2 == True
    False
    >>> 1 == True
    True

This makes the 2nd inverter inaccessible if trying to access two inverters (via a parent) in the same program. It works with example.py if you pass a unit of 2 as there is no parent in that case.

@jgyates
Copy link

jgyates commented Sep 10, 2023

If you change the lines:

 if unit:
        self.unit = unit
    else:
        self.unit = parent.unit

to

 if unit != parent.unit:
        self.unit = unit
    else:
        self.unit = parent.unit

it corrects the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants