|
|
|
""""
|
|
|
|
ModBus control routines
|
|
|
|
Copyright (C) 2023 M.T. Konstapel
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import minimalmodbus
|
|
|
|
import serial
|
|
|
|
from retrying import retry
|
|
|
|
#from epevermodbus.extract_bits import extract_bits
|
|
|
|
|
|
|
|
|
|
|
|
class EpeverChargeController(minimalmodbus.Instrument):
|
|
|
|
"""Instrument class for Epever Charge Controllers.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
* portname (str): port name
|
|
|
|
* slaveaddress (int): slave address in the range 1 to 247
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, portname, slaveaddress):
|
|
|
|
minimalmodbus.Instrument.__init__(self, portname, slaveaddress)
|
|
|
|
self.serial.baudrate = 9600
|
|
|
|
self.serial.bytesize = 8
|
|
|
|
self.serial.parity = serial.PARITY_NONE
|
|
|
|
self.serial.stopbits = 1
|
|
|
|
self.serial.timeout = 1
|
|
|
|
self.mode = minimalmodbus.MODE_RTU
|
|
|
|
self.clear_buffers_before_each_transaction = True
|
|
|
|
|
|
|
|
@retry(wait_fixed=200, stop_max_attempt_number=5)
|
|
|
|
def retriable_read_register(
|
|
|
|
self, registeraddress, number_of_decimals, functioncode
|
|
|
|
):
|
|
|
|
return self.read_register(
|
|
|
|
registeraddress, number_of_decimals, functioncode, False
|
|
|
|
)
|
|
|
|
|
|
|
|
@retry(wait_fixed=200, stop_max_attempt_number=5)
|
|
|
|
def retriable_read_bit(self, registeraddress, functioncode):
|
|
|
|
return self.read_bit(registeraddress, functioncode)
|
|
|
|
|
|
|
|
#Address range 0x3000
|
|
|
|
def get_id(self):
|
|
|
|
"""PV array rated voltage"""
|
|
|
|
return self.retriable_read_register(0, 0, 4)
|
|
|
|
|
|
|
|
def get_wind_direction(self):
|
|
|
|
"""PV array rated current"""
|
|
|
|
return self.retriable_read_register(1, 0, 4)
|
|
|
|
|
|
|
|
def get_wind_speedl(self):
|
|
|
|
"""PV array rated power (low 16 bits)"""
|
|
|
|
return self.retriable_read_register(2, 2, 4)
|
|
|
|
|
|
|
|
def get_wind_gust(self):
|
|
|
|
"""PV array rated power (high 16 bits)"""
|
|
|
|
return self.retriable_read_register(3, 2, 4)
|
|
|
|
|
|
|
|
def get_temperature(self):
|
|
|
|
"""Rated Battery's voltage"""
|
|
|
|
return self.retriable_read_register(4, 2, 4)
|
|
|
|
|
|
|
|
def get_rain(self):
|
|
|
|
"""Rated charging current to battery"""
|
|
|
|
return self.retriable_read_register(5, 2, 4)
|
|
|
|
|
|
|
|
def get_rain_last24(self):
|
|
|
|
"""Rated charging power to battery (low 16 bits)"""
|
|
|
|
return self.retriable_read_register(6, 2, 4)
|
|
|
|
|
|
|
|
def get_rain_since_midnight(self):
|
|
|
|
"""Charging equipment rated output power (high 16 bits)"""
|
|
|
|
return self.retriable_read_register(7, 0, 4)
|
|
|
|
|
|
|
|
def get_humidity(self):
|
|
|
|
"""Charging mode: 0x0001 = PWM"""
|
|
|
|
return self.retriable_read_register(8, 2, 4)
|
|
|
|
|
|
|
|
def get_pressure(self):
|
|
|
|
"""Charging mode: 0x0001 = PWM"""
|
|
|
|
return self.retriable_read_register(9, 1, 4)
|