-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdelta-solivia-8266.yaml
404 lines (356 loc) · 13.8 KB
/
delta-solivia-8266.yaml
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# *****************************************************************
# * ESPHome Custom Component Modbus sniffer for *
# * Delta Solvia Inverter 3.0 EU G4 TR *
# * installed with Solivia Gateway M1 D2. *
# *****************************************************************
#
# Remember to copy the Custom Component solivia.h file to the ESPHome folder in
# Home Assistant !!
#
# This config doesn't send any commands to the inverter !!
# Instead it relies on the gateways constant request for data (appx. 1 package pr. second).
#
# If you don't have a gateway, the package request can instead easily be send from
# ESPHome using uart.write and eg. triggered via the ESPHome Time component.
#
# Example:
# time:
# - platform: homeassistant
# id: esptime
# - platform: sntp
# on_time:
# # Request package every 10 seconds from inverter at slave address: 0x01
# - seconds: /10
# then:
# - uart.write: [0x02, 0x05, 0x01, 0x02, 0x60, 0x01, 0x85, 0xFC, 0x03]
#
#
# NOTE !!
#
# My inverter, unlike most examples found on the net, returns a 255 bytes response.
# Most common inverter response length is 150 bytes (0x96) or 157 (0x9D).
# So almost all commands/registers don't match other examples on the net.
# Package structure is also somewhat different.
#
# A list of all Delta Solivia inverters registers and the communication protocol is published
# and can be found here: https://forums.ni.com/ni/attachments/ni/170/1007166/1/Public%20RS485%20Protocol%201V2.pdf
#
# Using above list, it will be easy to tweak my configuration to fit your inverter variant.
#
# it-koncept has tweaked this config and revised the registers to get a working solution
# for his 3 x Delta Solivia 3.0/3.3 EU G3 inverters: https://github.com/it-koncept/Solvia-Inverter-G3
#
# Tested on both ESP8266 with software & hardware UART and ESP32 with hardware UART only.
# I experience minor ESPHome <--> Home Assistant connection issues using the ESP8266 software UART.
# So I've revised my production config to use the hardware UART pins instead. This is rock solid.
# But remember to turn off debug communication on the UART pins.
#
# My config:
# Inverter part no.: EOE46010287
# Single string input PV1: 3500W
# Single phase output: L1
# Slave address: 0x01
# Baud rate: 19200
# Install country: Denmark
#
# Gateway request: 02:05:01:02:60:01:85:FC:03
# Inverter response: 02:06:01:FF:60:01 + 255 data bytes (incl. CRC bytes) + ETX byte
#
# Actually the response doesn't match the protocol, as the CRC bytes and trailing
# ETX byte should be excluded from data length identifier (0xff)
# Here, strangely enough, the CRC is included, but not the ETX ?
#
# A few of the 'public known' commands have been tested. Most unfortunately did fail.
# Haven't really spend much time on testing further commands, as all the data
# i need is in gateway package.
# But commmand for eg. inverters serial no. is working ok on my inverter.
# - uart.write: [0x02, 0x05, 0x01, 0x02, 0x00, 0x01, 0xAD, 0xFC, 0x03] will response
# correctly with serial no.
#############################################
# Substitutions section contains all the #
# user/device specific configurable details #
#############################################
substitutions:
devicename: delta-solivia-8266
friendly_name: Solivia
device_description: Delta Solivia Modbus node
platform: ESP8266
board: d1_mini
wifi: !secret wifi_ssid_tp
password: !secret wifi_password_tp
ip: !secret static_ip_solivia
gateway: !secret gateway
ha_api_key: !secret api_key
ap_password: !secret wifi_ap_password
ota_password: !secret solivia_ota_password
uart_tx: "1" # GPIO1 = D10 - TX pin for hardware UART on ESP8266
uart_rx: "3" # GPIO3 = D9 - TX pin for hardware UART on ESP8266
# uart_tx: "5" # GPIO5 = D1 - Typical TX pin for software UART on ESP8266
# uart_rx: "4" # GPIO4 = D2 - Typical RX pin for software UART on ESP8266
# uart_tx: "17" # GPIO17 = D27 - Default TX pin for hardware UART#2 on ESP32 modules
# uart_rx: "16" # GPIO16 = D25 - Default RX pin for hardware UART#2 on ESP32 modules
###############################################
# Main YAML block #
# You should not need to edit below this line #
###############################################
esphome:
name: ${devicename}
friendly_name: ${friendly_name}
comment: ${device_description}
platform: ${platform}
board: ${board}
includes:
- solivia.h
uart:
id: mod_bus
tx_pin: ${uart_tx}
rx_pin: ${uart_rx}
# Increase buffer size as total package we're sniffing is 262 bytes in total
# Inverter reply: 6 bytes + Data: 255 bytes + ETX: 1 byte = 262 bytes
rx_buffer_size: 1024
baud_rate: 19200
parity: NONE
stop_bits: 1
#debug: # Activate if you need to investigate package details in the log
# Enable logging
# Set baud rate to 0 if you're using hardware UART, in order to disable logging via UART pins
logger:
baud_rate: 0
# level: VERBOSE
# Enable Home Assistant API
api:
encryption:
key: ${ha_api_key}
ota:
password: ${ota_password}
wifi:
ssid: ${wifi}
password: ${password}
manual_ip:
static_ip: ${ip}
gateway: ${gateway}
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case WiFi connection fails
ap:
ssid: ${friendly_name} Fallback Hotspot
password: ${ap_password}
captive_portal:
# Remove hash signs and activate, if you don't have a Solivia gataway.
# With this you emulate the gateways request for data response from the inverter
# With settings below, the requests are send every 10 seconds.
#
#time:
# - platform: homeassistant
# id: esptime
# - platform: sntp
# on_time:
# # Request package every 10 seconds from inverter at slave address: 0x01
# - seconds: /10
# then:
# - uart.write: [0x02, 0x05, 0x01, 0x02, 0x60, 0x01, 0x85, 0xFC, 0x03]
binary_sensor:
- platform: status
name: "Node status"
- platform: template
name: "Night status"
icon: mdi:toggle-switch-outline
# Check bit 2 for night status
lambda: |-
if (((int(id(solar_status_1).state)) >> (2)) & 1) return 1; else return 0;
# Example on how to return a text string instead of the binary inverter night status
#text_sensor:
# - platform: template
# name: "Solivia night status"
# # Check bit 2 for night status
# lambda: |-
# if (((int(id(solar_status_1).state)) >> (2)) & 1) return (std::string)"Inverter idle"; else return (std::string)"Inverter active";
sensor:
# Uptime sensor / WiFi strength in db and percentage
- platform: uptime
name: "Uptime sensor"
- platform: wifi_signal
id: solivia_wifi_strength_db
name: "WiFi strength db"
update_interval: 60s
entity_category: "diagnostic"
- platform: copy # Reports the WiFi signal strength in %
source_id: solivia_wifi_strength_db
name: "WiFi strength pct."
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "%"
entity_category: "diagnostic"
- platform: custom
lambda: |-
auto delta = new solivia(id(mod_bus));
App.register_component(delta);
return {delta->ac_power, delta->d_yield, delta->dc_a, delta->dc_v, delta->ac_a, delta->ac_v, delta->freq, delta->temp_amb, delta->temp_hs, delta->t_yield, delta->dc_power, delta->iso_plus, delta->iso_minus, delta->ac_react, delta->status_1, delta->status_2};
sensors:
- name: "Solar AC power"
icon: mdi:solar-power
unit_of_measurement: W
accuracy_decimals: 0
# Frequent update, as sensor is used to calculate consumption with iem3155 sensor.total_active_power
filters:
- throttle: 10s
- name: "Solar daily yield"
id: solar_daily_yield
icon: mdi:solar-power-variant
device_class: energy
# Set state_class in order for HA to use sensor in the Energy component
state_class: total_increasing
unit_of_measurement: Wh
accuracy_decimals: 0
filters:
- throttle: 60s
- name: "Solar DC current"
icon: mdi:current-dc
unit_of_measurement: A
accuracy_decimals: 1
filters:
- throttle: 60s
- multiply: 0.1
- name: "Solar DC voltage"
icon: mdi:current-dc
unit_of_measurement: V
accuracy_decimals: 0
filters:
- throttle: 60s
- name: "Solar AC current"
icon: mdi:current-ac
unit_of_measurement: A
accuracy_decimals: 1
filters:
- throttle: 60s
- multiply: 0.1
- name: "Solar AC voltage"
icon: mdi:current-ac
unit_of_measurement: V
accuracy_decimals: 0
filters:
- throttle: 60s
- name: "Solar frequency"
icon: mdi:sine-wave
unit_of_measurement: Hz
accuracy_decimals: 2
filters:
- throttle: 60s
- multiply: 0.01
- name: "Solar ambient temperature"
device_class: temperature
unit_of_measurement: °C
filters:
- throttle: 60s
- name: "Solar heatsink temperature"
device_class: temperature
unit_of_measurement: °C
filters:
- throttle: 60s
- name: "Solar total yield"
device_class: energy
icon: mdi:lightning-bolt-circle
unit_of_measurement: kWh
accuracy_decimals: 0
filters:
- throttle: 60s
- multiply: 0.001
- name: "Solar DC power"
icon: mdi:lightning-bolt
unit_of_measurement: W
accuracy_decimals: 0
filters:
- throttle: 60s
- name: "Solar ISO +"
icon: mdi:omega
unit_of_measurement: kΩ
filters:
- throttle: 60s
- name: "Solar ISO -"
icon: mdi:omega
unit_of_measurement: kΩ
filters:
- throttle: 60s
- name: "Solar AC reactive power"
icon: mdi:lightning-bolt
unit_of_measurement: VAR
filters:
- throttle: 60s
- name: "Solar Status 1 (bit 0-7)"
#internal: true
id: solar_status_1
icon: mdi:checkbox-marked-circle-outline
filters:
- throttle: 60s
- name: "Solar Status 2 (bit 8-15)"
#internal: true
id: solar_status_2
icon: mdi:checkbox-marked-circle-outline
filters:
- throttle: 60s
# Complete 'live' package example - captured [2022-08-08 10:32:54 GMT+1]:
# Request: 02:05:01:02:60:01:85:FC:03
# Response: 02:06:01:FF:60:01
# Package data:
# 0x00 45:4F:45:34:36:30:31:30:32:38:37:31:31:33:32:38
# 0x10 37:30:38:31:33:30:31:30:30:33:33:39:38:31:33:30
# 0x20 31:30:38:01:02:1A:00:00:00:00:23:34:00:00:00:00
# 0x30 23:34:00:00:00:00:00:00:00:00:00:00:23:34:00:00
# 0x40 00:00:00:00:00:00:00:00:01:00:03:96:01:9A:00:16
# 0x50 00:00:00:00:00:00:00:00:00:00:00:00:00:23:00:EC
# 0x60 13:88:03:64:FF:4E:00:00:00:00:00:00:00:00:00:00
# 0x70 00:00:00:00:00:00:00:00:00:00:08:98:07:D0:00:33
# 0x80 00:33:00:00:00:00:02:14:3E:3E:00:26:48:A6:00:00
# 0x90 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
# 0xA0 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
# 0xB0 00:00:00:00:08:F7:00:00:01:16:00:00:00:00:00:00
# 0xC0 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
# 0xD0 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
# 0xE0 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
# 0xF0 00:00:00:00:00:00:00:00:00:00:00:00:00:34:A4:03
# Register address:
# 0x00 - 0x0A: SAP part no. EOE46010287 45:4F:45:34:36:30:31:30:32:38:37
# 0x0B - 0x1C: SAP serial no. 113287081301003398 31:31:33:32:38:37:30:38:31:33:30:31:30:30:33:33:39:38
# 0x1D - 0x20: SAP date code 1301 31:33:30:31
# 0x21 - 0x22: SAP revision 08 30:38
# 0x23 - 0x25: SW rev. System controller 1.02.26 01:02:1A
# 0x29 - 0x2B: SW rev. ENS controller 0.35.52 00:23:34
# 0x2F - 0x31: SW Rev. DC controller 0.35.52 00:23:34
# 0x3B - 0x3D: SW Rev. AC controller 0.35.52 00:23:34
# 0x47 - 0x49: SW revision reserved 0.1.0 00:01:00
# 0x4A - 0x4B: DC Power PV1 W 918 03:96
# 0x4C - 0x4D: DC voltage PV1 V 410 01:9A
# 0x4E - 0x4F: DC current PV1 (2,2 A) 22 00:16
# 0x5C - 0x5D: AC current L1 (3,5 A) 35 00:23
# 0x5E - 0x5F: AC voltage L1 V 236 00:EC
# 0x60 - 0x61: AC frequency (50,00 Hz) 5000 13:88
# 0x62 - 0x63: AC Power L1 W 868 03:64
# 0x64 - 0x65: AC Reactive Power L1 VAR -178 FF:4E
# 0x7A - 0x7B: ISO+ resistance kΩ 2200 08:98
# 0x7C - 0x7D: ISO- resistance kΩ 2000 07:D0
# 0x7E - 0x7F: Temperature ambient °C 50 00:33
# 0x80 - 0x81: Temperature heatsink °C 50 00:33
# 0x86 - 0x89: Total yield (34881,086 kWh) 34881086 02:14:3E:3E
# 0x8A - 0x8D: Uptime total in minutes 2508966 00:26:48:A6
# 0x91 - 0x91: Status 1 - bit 0 to 7 0 00
# 0x94 - 0x94: Status 2 - bit 8 to 15 0 00
# 0xB4 - 0xB5: Daily power yield Wh 2295 08:F7
# 0xB8 - 0xB9: Uptime today in minutes 278 01:16
# 0x91: Inverter status register 1 (4 bytes - 32 bits in total):
# bit 00 = 1 -> Self test ongoing
# bit 01 = 1 -> Firmware update
# bit 02 = 1 -> Night mode Check for Night mode
# bit 03 = 1 -> L1 Voltage failure Check for L1 Voltage failure
# bit 04 = 1 -> L2 Voltage failure
# bit 05 = 1 -> L3 Voltage failure
# bit 06 = 1 -> L1 Frequency failure
# bit 07 = 1 -> L2 Frequency failure
# When inverter is active bit#02 is cleared. When inactive bit#02 is set.
# 0x94: Inverter status register 2 (4 bytes - 32 bits in total):
# bit 08 = 1 -> PV3 Iso startup failure
# bit 09 = 1 -> PV3 Iso running failure
# bit 10 = 1 -> PV3+ grounding failure
# bit 11 = 1 -> PV3- grounding failure
# bit 12 = 1 -> PV1 voltage too low failure Check for PV1 voltage too low failure
# bit 13 = 1 -> PV2 voltage too low failure
# bit 14 = 1 -> PV3 voltage too low failure
# bit 15 = 1 -> Internal failure