-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathsolis-4g.py
130 lines (95 loc) · 3.93 KB
/
solis-4g.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import minimalmodbus
import socket
import serial
### PROGRAM FLOW:
### - Collect Data from Solis-4G inverter
### - Convert to individual bytes
### - Construct 2 messages
### - KWH Totals only sent when inverter is running, so they are not reset to zero
### - All other 'live' data set to zero when inverter shuts down
### - Send Packets to EMONHUB
###
### EmonHub Node IDs:
### - NodeID 3: All time energy KWH / Today KWH (not sent overnight)
### - NodeID 4: Live Data Readings - Zeros sent overnight
### COLLECT DATA FROM SOLIS-4G INVERTER ###
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1) # port name, slave address
instrument.serial.baudrate = 9600 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.2 # seconds
success = False # Intialise Success/Failure Flag to ensure full data is only uploaded if all data is received.
try:
Realtime_ACW = instrument.read_long(3004, functioncode=4, signed=False) #Read AC Watts as Unsigned 32-Bit
Realtime_DCV = instrument.read_register(3021, numberOfDecimals=0, functioncode=4, signed=False) #Read DC Volts as Unsigned 16-Bit
Realtime_DCI = instrument.read_register(3022, numberOfDecimals=0, functioncode=4, signed=False) #Read DC Current as Unsigned 16-Bit
Realtime_ACV = instrument.read_register(3035, numberOfDecimals=0, functioncode=4, signed=False) #Read AC Volts as Unsigned 16-Bit
Realtime_ACI = instrument.read_register(3038, numberOfDecimals=0, functioncode=4, signed=False) #Read AC Current as Unsigned 16-Bit
Realtime_ACF = instrument.read_register(3042, numberOfDecimals=0, functioncode=4, signed=False) #Read AC Frequency as Unsigned 16-Bit
Inverter_C = instrument.read_register(3041, numberOfDecimals=0, functioncode=4, signed=True) #Read Inverter Temperature as Signed 16-Bit
AlltimeEnergy_KW = instrument.read_long(3008, functioncode=4, signed=False) # Read All Time Energy (KWH Total) as Unsigned 32-Bit
Today_KW = instrument.read_register(3014, numberOfDecimals=0, functioncode=4, signed=False) # Read Today Energy (KWH Total) as 16-Bit
##Convert Data to Bytes
A1 = Realtime_ACW % 256
A2 = (Realtime_ACW >> 8) % 256
A3 = (Realtime_ACW >> 16) % 256
A4 = (Realtime_ACW >> 24) % 256
B1 = AlltimeEnergy_KW % 256
B2 = (AlltimeEnergy_KW >> 8) % 256
B3 = (AlltimeEnergy_KW >> 16) % 256
B4 = (AlltimeEnergy_KW >> 24) % 256
C1 = Today_KW % 256
C2 = (Today_KW >> 8) % 256
D1 = Realtime_DCV % 256
D2 = (Realtime_DCV >> 8) % 256
E1 = Realtime_DCI % 256
E2 = (Realtime_DCI >> 8) % 256
F1 = Inverter_C % 256
F2 = (Inverter_C >> 8) % 256
G1 = Realtime_ACF % 256
G2 = (Realtime_ACF >> 8) % 256
H1 = Realtime_ACV % 256
H2 = (Realtime_ACV >> 8) % 256
I1 = Realtime_ACI % 256
I2 = (Realtime_ACI >> 8) % 256
##Flag to stream all data to EmonHub
success = True
except:
##EXCEPTION WILL OCCUR WHEN INVERTER SHUTS DOWN WHEN PANELS ARE OFF
A1 = 0
A2 = 0
A3 = 0
A4 = 0
## Not sent when inverter turns off
## B1 = 0
## B2 = 0
## B3 = 0
## B4 = 0
## C1 = 0
## C2 = 0
## END NOT SENT WHEN INVERTER TURNS OFF
D1 = 0
D2 = 0
E1 = 0
E2 = 0
F1 = 0
F2 = 0
G1 = 0
G2 = 0
H1 = 0
H2 = 0
I1 = 0
I2 = 0
##Flag to stream restricted data to EmonHub
success = False
### END COLLECT DATA FROM SOLIS-4G INVERTER ###
### STREAM RESULT TO EMONHUB ###
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Initialise Socket
s.connect(('localhost', 8080)) #Connect to Local EmonHub
## NOT SENT WHEN INVERTER TURNS OFF
if success == True:
s.sendall('03 ' + str(B1) + ' ' + str(B2) + ' ' + str(B3) + ' ' + str(B4) + ' ' + str(C1) + ' ' + str(C2) + '\r\n')
s.sendall('04 ' + str(A1) + ' ' + str(A2) + ' ' + str(A3) + ' ' + str(A4) + ' ' + str(D1) + ' ' + str(D2) + ' ' + str(E1) + ' ' + str(E2) + ' ' + str(F1) + ' ' + str(F2) + ' ' + str(G1) + ' ' + str(G2) + ' ' + str(H1) + ' ' + str(H2) + ' ' + str(I1) + ' ' + str(I2) + '\r\n')
s.close()
### END SEND TO EMON HUB #