First commit
This commit is contained in:
134
weather_station_modbus.py
Normal file
134
weather_station_modbus.py
Normal file
@@ -0,0 +1,134 @@
|
||||
""""
|
||||
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 WeatherStation(minimalmodbus.Instrument):
|
||||
"""Instrument class for Epever Charge Controllers.
|
||||
|
||||
Args:
|
||||
* portname (str): port name
|
||||
* slaveaddress (int): slave address in the range 1 to 247
|
||||
|
||||
"""
|
||||
|
||||
@retry(wait_fixed=10000, stop_max_attempt_number=5)
|
||||
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
|
||||
self.wx_data = []
|
||||
|
||||
@retry(wait_fixed=200, stop_max_attempt_number=5)
|
||||
def retriable_read_register(
|
||||
self, registeraddress, number_of_decimals, functioncode, signed=False
|
||||
):
|
||||
return self.read_register(
|
||||
registeraddress, number_of_decimals, functioncode, signed
|
||||
)
|
||||
|
||||
@retry(wait_fixed=200, stop_max_attempt_number=5)
|
||||
def retriable_read_bit(self, registeraddress, functioncode):
|
||||
return self.read_bit(registeraddress, functioncode)
|
||||
|
||||
@retry(wait_fixed=200, stop_max_attempt_number=5)
|
||||
def retriable_write_bit(self, registeraddress, data, functioncode):
|
||||
return self.write_bit(registeraddress, data, 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, 1, 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, True)
|
||||
|
||||
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)
|
||||
|
||||
def get_temperature_backup(self):
|
||||
"""Charging mode: 0x0001 = PWM"""
|
||||
return self.retriable_read_register(13, 2, 4,True)
|
||||
|
||||
def get_status_bits(self):
|
||||
"""Charging mode: 0x0001 = PWM"""
|
||||
return self.retriable_read_register(14, 0, 4)
|
||||
|
||||
def enable_heater(self):
|
||||
self.retriable_write_bit(0, 1, 5)
|
||||
|
||||
def disable_heater(self):
|
||||
self.retriable_write_bit(0, 0, 5)
|
||||
|
||||
def get_weather_data(self):
|
||||
try:
|
||||
self.wx_data={}
|
||||
self.wx_data['ID'] = self.get_id()
|
||||
self.wx_data['Wind direction'] = self.get_wind_direction()
|
||||
self.wx_data['Wind speed'] = self.get_wind_speedl()
|
||||
self.wx_data['Wind gust'] = self.get_wind_gust()
|
||||
self.wx_data['Rain last hour'] = self.get_rain()
|
||||
self.wx_data['Rain last 24 hours'] = self.get_rain_last24()
|
||||
self.wx_data['Temperature'] = self.get_temperature()
|
||||
self.wx_data['Humidity'] = self.get_humidity()
|
||||
self.wx_data['Pressure'] = self.get_pressure()
|
||||
self.wx_data['Temp backup'] = self.get_temperature_backup()
|
||||
self.wx_data['Status bits'] = self.get_status_bits()
|
||||
|
||||
return 1
|
||||
except:
|
||||
return 0
|
Reference in New Issue
Block a user