SolarEdge Modbus解析器库

solaredge-modbus的Python项目详细描述


modbus隔离

solaredge_modbus是一个python库,它通过modbus或ModbusTCP从solaredge电源逆变器收集数据。在

安装

要安装,请克隆此项目并使用setuptools进行安装:

python3 setup.py install

或者从PyPi安装包:

pip3 install solaredge_modbus

使用

脚本example.py提供了一个通过ModbusTCP连接并显示来自SolarEdge电源逆变器的所有寄存器的最小示例。在

usage: example.py [-h] [--timeout TIMEOUT] [--unit UNIT] [--json] host port

positional arguments:
  host               ModbusTCP address
  port               ModbusTCP port

optional arguments:
  -h, --help         show this help message and exit
  --timeout TIMEOUT  Connection timeout
  --unit UNIT        Modbus unit
  --json             Output as JSON

输出:

^{pr2}$

传递--json返回:

{
    "c_manufacturer": "SolarEdge",
    'c_model': 'SE3500H-RW000BNN4',
    'c_version': '0004.0009.0030',
    'c_serialnumber': '123ABC12',
    'c_deviceaddress': 1,
    'c_sunspec_did': 101,
    'current': 895,
    'p1_current': 895,
    'p2_current': False,
    'p3_current': False,
    'current_scale': -2,
    'p1_voltage': 2403,
    'p2_voltage': False,
    'p3_voltage': False,
    'p1n_voltage': False,
    'p2n_voltage': False,
    'p3n_voltage': False,
    'voltage_scale': -1,
    'frequency': 50003,
    'frequency_scale': -3,
    'power_ac': 21413,
    'power_ac_scale': -1, 
    'power_apparent': 21479,
    'power_apparent_scale': -1,
    'power_reactive': 16859,
    'power_reactive_scale': -2,
    'power_factor': 9969,
    'power_factor_scale': -2,
    'energy_total': 3466757,
    'energy_total_scale': 0,
    'current_dc': 5678,
    'current_dc_scale': -3,
    'voltage_dc': 3826,
    'voltage_dc_scale': -1,
    'power_dc': 21726,
    'power_dc_scale': -1,
    'temperature': 4979,
    'temperature_scale': -2,
    'status': 4,
    'vendor_status': 0
}

注意,如果kWh电表或电池连接到您的逆变器,这些也将显示在JSON输出中。在

第二个脚本example_influxdb.py提供了一个InfluxDB writer示例。它通过ModbusTCP连接到一个逆变器,并每秒将逆变器、电池和仪表值写入InfluxDB。在

usage: example_influxdb.py [-h] [--timeout TIMEOUT] [--unit UNIT] [--interval INTERVAL] [--influx_host INFLUX_HOST] [--influx_port INFLUX_PORT] [--influx_db INFLUX_DB]
                           [--influx_user INFLUX_USER] [--influx_pass INFLUX_PASS]
                           host port

positional arguments:
  host                  ModbusTCP address
  port                  ModbusTCP port

optional arguments:
  -h, --help            show this help message and exit
  --timeout TIMEOUT     Connection timeout
  --unit UNIT           Modbus unit
  --interval INTERVAL   Update interval
  --influx_host INFLUX_HOST
                        InfluxDB host
  --influx_port INFLUX_PORT
                        InfluxDB port
  --influx_db INFLUX_DB
                        InfluxDB database
  --influx_user INFLUX_USER
                        InfluxDB username
  --influx_pass INFLUX_PASS
                        InfluxDB password

示例

如果您希望使用ModbusTCP,以下参数是相关的:

host = IP or DNS name of your ModbusTCP device, required
port = listening port of the ModbusTCP device, required
unit = Modbus device id, default=1, optional

如果使用串行Modbus连接,则可以指定:

device = path to serial device, e.g. /dev/ttyUSB0, required
baud = baud rate of your device, defaults to product default, optional
unit = Modbus unit id, defaults to 1, optional

连接到逆变器:

    >>> import solaredge_modbus

    # Inverter over ModbusTCP
    >>> inverter = solaredge_modbus.Inverter(host="10.0.0.123", port=1502)

    # Inverter over Modbus RTU
    >>> inverter = solaredge_modbus.Inverter(device="/dev/ttyUSB0", baud=115200)

测试连接,记住一次只允许一个连接:

    >>> inverter.connect()
    True

    >>> inverter.connected()
    True

虽然在读取寄存器之前没有必要显式地调用connect(),但是应该在调用connected()来测试连接之前这样做。完成后,可以通过调用disconnect()关闭连接。在

打印类会生成基本的设备参数:

    >>> inverter
    Inverter(10.0.0.123:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1)

按名称读取单个输入寄存器:

    >>> inverter.read("current")
    {
        'current': 895
    }

使用read_all()读取所有输入寄存器:

    >>> inverter.read_all()
    {
        'c_manufacturer': 'SolarEdge',
        'c_model': 'SE3500H-RW000BNN4',
        'c_version': '0004.0009.0030',
        'c_serialnumber': '123ABC12',
        'c_deviceaddress': 1,
        'c_sunspec_did': 101,
        'current': 895,
        'p1_current': 895,
        'p2_current': False,
        'p3_current': False,
        'current_scale': -2,
        'p1_voltage': 2403,
        'p2_voltage': False,
        'p3_voltage': False,
        'p1n_voltage': False,
        'p2n_voltage': False,
        'p3n_voltage': False,
        'voltage_scale': -1,
        'power_ac': 21413,
        'power_ac_scale': -1, 
        'frequency': 50003,
        'frequency_scale': -3,
        'power_apparent': 21479,
        'power_apparent_scale': -1,
        'power_reactive': 16859,
        'power_reactive_scale': -2,
        'power_factor': 9969,
        'power_factor_scale': -2,
        'energy_total': 3466757,
        'energy_total_scale': 0,
        'current_dc': 5678,
        'current_dc_scale': -3,
        'voltage_dc': 3826,
        'voltage_dc_scale': -1,
        'power_dc': 21726,
        'power_dc_scale': -1,
        'temperature': 4979,
        'temperature_scale': -2,
        'status': 4,
        'vendor_status': 0
    }

如果需要有关特定寄存器的更多信息,请查找单位或枚举,例如:

    >>> inverter.registers["current"]
        # address, length, type, datatype, valuetype, name, unit, batching
        (
            40071, 
            1, 
            <registerType.HOLDING: 2>, 
            <registerDataType.UINT16: 3>, 
            <class 'int'>, 
            'Current', 
            'A', 
            2
        )

    >>> inverter.registers["status"]
        # address, length, type, datatype, valuetype, name, unit, batching
        (
            40107, 
            1, 
            <registerType.HOLDING: 2>, 
            <registerDataType.UINT16: 3>, 
            <class 'int'>, 
            'Status', 
            ['Undefined', 'Off', 'Sleeping', 'Grid Monitoring', 'Producing', 'Producing (Throttled)', 'Shutting Down', 'Fault', 'Standby'], 
            2
        )

仪表和电池

SolarEdge支持各种kWh电表和电池,并通过变频器上的一组预定义寄存器来公开它们的寄存器。根据SolarEdge SunSpec实现,支持的寄存器数量是硬编码的,为3米和2节电池。可以查询它们的寄存器:

    >>> inverter.meters()
    {
        'Meter1': Meter1(10.0.0.123:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1)
    }

    >>> meter1 = inverter.meters()["Meter1"]
    >>> meter1
    Meter1(10.0.0.123:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1)

    >>> meter1.read_all()
    {
        'c_manufacturer': 'SolarEdge',
        'c_model': 'PRO380-Mod',
        'c_option': 'Export+Import',
        'c_version': '2.19',
        'c_serialnumber': '12312332',
        'c_deviceaddress': 1,
        'c_sunspec_did': 203,
        'current': -13,
        ...
    }

或类似的电池:

    >>> inverter.batteries()
    {
        'Battery1': Battery(10.0.0.123:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1)
    }

    >>> battery1 = inverter.batteries()["Battery1"]
    >>> battery1
    Battery1(10.0.0.123:1502, connectionType.TCP: timeout=1, retries=3, unit=0x1)

    >>> battery1.read_all()
    {
        ...
    }

对逆变器对象调用meters()batteries()是实例化其对象的推荐方法。这样,就可以检查可用设备、寄存器偏移和pymodbus连接的共享。如果要独立创建仪表或电池对象,请执行以下操作:

    # Meter #1 via the existing inverter connection
    >>> meter1 = solaredge_modbus.Meter(parent=inverter, offset=0)

    # Meter #2 over ModbusTCP, without a parent connection
    >>> meter2 = solaredge_modbus.Meter(host="10.0.0.123", port=1502, offset=1)

    # Battery #1 via the existing inverter connection
    >>> battery1 = solaredge_modbus.Battery(parent=inverter, offset=0)

    # Battery #1 over ModbusTCP, without a parent connection
    >>> battery1 = solaredge_modbus.Battery(host="10.0.0.123", port=1502, offset=1)

在这样做的时候有两点需要考虑。您需要手动传递parentoffset参数,它们负责共享现有的Modbus连接,并设置正确的寄存器地址。第一台设备使用offset0,第二台使用1,第三台使用2。如果没有传递父inverter对象,则需要提供与inverter对象所需的连接参数相同的连接参数。请记住,第二个ModbusTCP或Modbus RTU连接将在另一个逆变器、仪表或电池对象使用时失败。在

注意:由于我无法访问兼容的电度表或电池,因此此实现没有经过彻底测试。如果您对此功能有问题,请打开GitHub问题。在

贡献

捐款是非常受欢迎的。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
tomcat Java条带错误   java OPENTSDB fsck修复程序不更正重复点   java JavaFX在控制器内切换自身的可见性   java maven surefire插件未并行执行运行程序   读取导致Freemarker模板引擎中TemplateException的Java对象   无法使Java库与我的Android应用程序一起工作   安卓 java。lang.IllegalStateException游标   使用Java检索XML文件中的XSL URL和名称   java如何从文本文件集合中提取特定值   电子邮件java mail gmail   java为什么finalize()只被垃圾收集器调用一次?   java方法findViewById(int)对于Json类型是未定义的。蛇形   java在安卓中尝试从brother打印机打印位图时遇到以下异常   java在颤振中支持Kotlin的优势   java从后面编写文本   java制作列表。第一个列表可以有相同的数字,第二个将是价格,尝试制作第三个列表,如果它们是相同的数字,它将添加价格