117 lines
5.0 KiB
Python
117 lines
5.0 KiB
Python
from flask import Flask, jsonify, render_template
|
|
from pysolarmanv5 import PySolarmanV5
|
|
import config
|
|
|
|
app = Flask(__name__)
|
|
|
|
def get_inverter_data():
|
|
"""
|
|
Connects to the inverter and reads voltage registers.
|
|
Returns a dictionary with the data.
|
|
"""
|
|
try:
|
|
inverter = PySolarmanV5(
|
|
config.INVERTER_IP,
|
|
config.INVERTER_SERIAL,
|
|
port=config.INVERTER_PORT,
|
|
mb_slave_id=config.INVERTER_SLAVE_ID,
|
|
verbose=False
|
|
)
|
|
|
|
# Reading blocks:
|
|
# Block 1: 150 - 216 (67 registers) - Voltages, Currents, Battery, PV, Control
|
|
# Block 2: 600 - 627 (28 registers) - BMS Data
|
|
# Block 3: 245 (1 register) - Max Grid Output
|
|
# Block 4: 292 - 293 (2 registers) - Peak Shaving
|
|
# Block 5: 314 - 325 (12 registers) - Advanced Limits
|
|
|
|
block1 = inverter.read_holding_registers(register_addr=150, quantity=67)
|
|
block2 = inverter.read_holding_registers(register_addr=600, quantity=28)
|
|
block3 = inverter.read_holding_registers(register_addr=245, quantity=1)
|
|
block4 = inverter.read_holding_registers(register_addr=292, quantity=2)
|
|
block5 = inverter.read_holding_registers(register_addr=314, quantity=12)
|
|
|
|
def to_signed(val):
|
|
return val if val < 32768 else val - 65536
|
|
|
|
data = {}
|
|
|
|
# Block 1 Parsing (150-216)
|
|
data["input_voltage"] = round(block1[0] * 0.1, 1) # 150
|
|
data["output_voltage"] = round(block1[4] * 0.1, 1) # 154
|
|
data["load_voltage"] = round(block1[7] * 0.1, 1) # 157
|
|
|
|
data["grid_current"] = round(to_signed(block1[10]) * 0.01, 2) # 160
|
|
data["grid_clamp_current"] = round(to_signed(block1[12]) * 0.01, 2) # 162
|
|
data["output_current"] = round(to_signed(block1[14]) * 0.01, 2) # 164
|
|
|
|
data["load_current"] = round(to_signed(block1[29]) * 0.01, 2) # 179
|
|
|
|
data["batt_temp"] = round(to_signed(block1[32]) * 0.1, 1) # 182
|
|
data["batt_voltage"] = round(block1[33] * 0.01, 2) # 183
|
|
data["batt_soc"] = block1[34] # 184
|
|
data["batt_charge_status"] = block1[35] # 185
|
|
data["pv1_power"] = block1[36] # 186
|
|
data["pv2_power"] = block1[37] # 187
|
|
|
|
data["batt_power"] = to_signed(block1[40]) # 190
|
|
data["batt_current"] = round(to_signed(block1[41]) * 0.01, 2) # 191
|
|
|
|
data["grid_relay_status"] = block1[44] # 194
|
|
data["gen_relay_status"] = block1[45] # 195
|
|
|
|
data["max_charge_current"] = block1[60] # 210
|
|
data["max_discharge_current"] = block1[61] # 211
|
|
data["batt_charge_efficiency"] = block1[66] # 216
|
|
|
|
# Block 2 Parsing (BMS 600-627)
|
|
data["bms1_soc"] = block2[3] # 603
|
|
data["bms1_charge_voltage"] = round(block2[6] * 0.01, 2) # 606
|
|
data["bms1_charge_current"] = round(block2[7] * 0.1, 1) # 607
|
|
|
|
data["bms2_soc"] = block2[17] # 617
|
|
data["bms2_charge_voltage"] = round(block2[20] * 0.01, 2) # 620
|
|
data["bms2_charge_current"] = round(block2[21] * 0.1, 1) # 621
|
|
|
|
# Block 3 Parsing (245)
|
|
data["max_grid_output_power"] = block3[0] # 245
|
|
|
|
# Block 4 Parsing (292-293)
|
|
data["gen_peak_shaving_power"] = block4[0] # 292
|
|
data["grid_peak_shaving_power"] = block4[1] # 293
|
|
|
|
# Block 5 Parsing (314-325)
|
|
data["discharge_voltage"] = round(block5[0] * 0.01, 2) # 314
|
|
data["charge_current_limit"] = block5[1] # 315
|
|
data["discharge_current_limit"] = block5[2] # 316
|
|
data["real_time_capacity"] = block5[3] # 317
|
|
data["real_time_voltage"] = round(block5[4] * 0.01, 2) # 318
|
|
# 319 skipped
|
|
data["max_charge_current_limit"] = block5[6] # 320
|
|
data["max_discharge_current_limit"] = block5[7] # 321
|
|
# 322-324 skipped
|
|
data["lithium_battery_type"] = block5[11] # 325
|
|
|
|
inverter.disconnect()
|
|
|
|
data["status"] = "success"
|
|
return data
|
|
|
|
except Exception as e:
|
|
return {
|
|
"status": "error",
|
|
"message": str(e)
|
|
}
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return render_template('index.html')
|
|
|
|
@app.route('/api/data')
|
|
def api_data():
|
|
data = get_inverter_data()
|
|
return jsonify(data)
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True, host='0.0.0.0')
|