Fehler hier >>>>>>>
-platform: modbus_controller
Leerzeichen vergessen.
Hier die automatische Variante!!
Nach langem Probieren habe ich folgende automatische Regelung für den MIC 2000tl-x auf dem Shine-x Stick. Manuelle Regelung ist nicht möglich - wozu auch.
Voraussetzung:
SmartMeter (Hichi ) Leistung in W per MQTT im Homeassistant (o.ä.) welcher dann vom Shine-x abgefragt wird.
Da mein Stromzähler keine Einspeisung zählt und die Verbraucher auf 3 Phasen verteilt sind kann man den tatsächlichen Verbrauch auch nicht wirklich erfassen wenn Solarstom auf eine Phase geliefert wird. Man sollte also vorher den Grundverbrauch kennen um die Nulleinspeisung realisieren zu können. Ich habe 250W Grundlast gemessen, also ca. 12% Leistung am Wechselrichter. Dies ist der Ausgangswert für mich. Zum Verständnis:
Wenn mein Stromzähler 50W Verbrauch anzeigt bedeutet dies bei 12% Leistung daß schon 240 Watt verbraucht wurden und real 290 W gebraucht werden, also 15%. In diesem Fall erhöht sich die Leistung automatisch auf 15% und bleibt dort bis es eine Änderung nach oben oder unten gibt im von mir angebenen Bereich ( siehe yaml ). Natürlich kann der Wechselrichter nie mehr Leistung liefern als er selber oder der Sonnenschein/Sonnenstand kann.
Wer die Einspeisung am Stromzähler auslesen kann, kann diesen Wert als Grundlage für die Berechnung der benötigten Leistung nehmen z.B.
Verbrauch - Einspeisung = Bedarf
Dazu muß man dann noch einiges umschreiben. Die meisten Werte im Lambda dienen nur der Kontrolle der Funktion über das Logfile und sind eigentlich unnötig. Der Wert PowerToGrid wäre eine Überschussrechnung bezogen auf den realen Verbrauch aber da kommt bei mir immer 0. ( irgendwo noch ein Denkfehler )
Es gibt also immer noch etwas zu verbessern aber es funktioniert seit Tagen ohne Probleme mit der Änderung der Leistung im Bezug auf den Verbrauch. Die Änderung der Leistung geschieht sofort ohne Verzögerung!! Aus diesem Grund sollten man den Bereich der Leistungsänderung ( ich habe 50 Watt ) nicht zu klein halten um permantens Regel zu vermeiden. Lieber etwas mehr Solarstrom liefern als zu wenig.
Diese Konfiguration bezieht sich nur auf den Verbrauch mit Grundlast bei Verteilung der Last auf drei Phasen bei UNBEKANNTER Einspeiseleistung. LEDs funktionieren bei mir so nicht über verlängertes USB Kabel.
Achtung. Die Konfiguration ist auf 2000W ausgelegt. Diese Werte müssen angepaßt werden auf die Leistung des Wechselrichters.
Viel Spaß beim probieren und ........ korrigieren.
substitutions:
device_description: Growatt Inverter Regulator
friendly_name: Growatt Inverter Regulator
devicename: "growregulator"
name: "growaregulator"
esphome:
name: $devicename
esp8266:
board: esp07s
# Enable logging
logger:
baud_rate: 0
# Enable Home Assistant API
api:
encryption:
key: " Enter your key "
ota:
password: "????"
wifi:
ssid:
password:
fast_connect: on
use_address: ""
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${name} Fallback Hotspot"
password: "password"
web_server:
port: 80
auth:
username: growatt
password: "1234"
# Use three global variables to store the last three received power values
globals:
- id: power_t0 # curent power value
type: float
restore_value: no
initial_value: '0.0'
- id: GrowattPower
type: float
initial_value: '0.0'
- id: GrowDCPower
type: float
restore_value: no
initial_value: '0.0'
captive_portal:
time:
- platform: homeassistant
id: homeassistant_time
output:
# Blue Led
- id: light_bl
platform: gpio
pin: 16
# Green Led
- id: light_gr
platform: gpio
pin: 0
# Red Led
- id: light_rd
platform: gpio
pin: 2
uart:
id: mod_bus
tx_pin: 1
rx_pin: 3
baud_rate: 115200
modbus:
id: modbus1
uart_id: mod_bus
modbus_controller:
- id: growatt
# the Modbus device addr
address: 0x1
modbus_id: modbus1
setup_priority: -10
sensor:
- platform: modbus_controller
name: "${devicename} DcPower"
address: 5
register_type: "read"
unit_of_measurement: W
device_class: power
icon: mdi:flash
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.1
on_value:
then:
- globals.set:
id: GrowDCPower
value: !lambda 'return float(x);'
- platform: modbus_controller
name: "${devicename} DcVoltage"
address: 3
register_type: "read"
unit_of_measurement: V
device_class: voltage
icon: mdi:flash
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
name: "${devicename} DcInputCurrent"
address: 4
register_type: "read"
unit_of_measurement: A
device_class: current
icon: mdi:flash
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
name: "${devicename} AcFrequency"
address: 37
register_type: "read"
unit_of_measurement: Hz
icon: mdi:flash
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.01
- platform: modbus_controller
name: "${devicename} AcVoltage"
address: 38
register_type: "read"
unit_of_measurement: V
device_class: voltage
icon: mdi:flash
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
name: "${devicename} AcOutputCurrent"
address: 39
register_type: "read"
unit_of_measurement: A
device_class: current
icon: mdi:flash
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
name: "${devicename} AcPower"
address: 40
register_type: "read"
unit_of_measurement: W
device_class: power
icon: mdi:flash
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.1
on_value:
then:
- globals.set:
id: GrowattPower
value: !lambda 'return float(x);'
- platform: modbus_controller
name: "${devicename} EnergyToday"
address: 53
register_type: "read"
unit_of_measurement: kWh
device_class: energy
icon: mdi:flash
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
name: "${devicename} EnergyTotal"
address: 55
register_type: "read"
unit_of_measurement: kWh
state_class: total_increasing
device_class: energy
icon: mdi:flash
value_type: U_DWORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
name: "${devicename} Temperature"
address: 93
register_type: "read"
unit_of_measurement: C
device_class: temperature
icon: mdi:thermometer
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: homeassistant
name: "Total Momentanleistung from Home Assistant"
entity_id: sensor.tasmota_strom_power_curr # <<<<<<<<<<<<<<<<<<< Hier trägst Du den Sensornamen von deinem 'Hichi' Stromzähler ein, Update alle 15s
on_value:
then:
- logger.log:
level: DEBUG
format: 'Power value changed from %d to %d Deziwatt [dW]'
args: ['id(power_t0)', 'int(x*10.0)']
- globals.set:
id: power_t0
value: !lambda 'return int(x*10.0);'
interval:
- interval: 15s
then:
- lambda: !lambda |-
ESP_LOGD("main", "Growatt AC Power: %f ", id(GrowattPower));
static int16_t powerMax = 20000; // 20000 dW = 2000 W (if Growatt MIC 2000TL-X)
static int16_t relOutputPower = 10; // Max output active power (0 - 100 %) // 10 % => ~60 W (if Growatt MIC 600TL-X)
static int16_t calOutputPower = 0;
static int16_t consumePower = 0;
static int16_t GridPower = 0;
static int16_t ToGridPower = 0;
static int16_t PowerSet = 0;
relOutputPower = id(power_t0) / powerMax * 100.0 + 1.0;
calOutputPower = id(power_t0) / powerMax * 100.0;
consumePower = id(power_t0) / 10.0;
PowerSet = relOutputPower / 1000.0 * powerMax;
GridPower = (id(power_t0) - id(GrowattPower)) / 10.0;
if ((id(power_t0) / 10.0) > 199 and (id(power_t0) / 10.0) < 259) relOutputPower = 13;
if ((id(power_t0) / 10.0) > 259 and (id(power_t0) / 10.0) < 299) relOutputPower = 15;
if ((id(power_t0) / 10.0) > 299 and (id(power_t0) / 10.0) < 359) relOutputPower = 18;
if ((id(power_t0) / 10.0) > 359 and (id(power_t0) / 10.0) < 399) relOutputPower = 20;
if ((id(power_t0) / 10.0) > 399 and (id(power_t0) / 10.0) < 459) relOutputPower = 23;
if ((id(power_t0) / 10.0) > 459 and (id(power_t0) / 10.0) < 499) relOutputPower = 25;
if ((id(power_t0) / 10.0) > 499 and (id(power_t0) / 10.0) < 559) relOutputPower = 28;
if ((id(power_t0) / 10.0) > 559 and (id(power_t0) / 10.0) < 599) relOutputPower = 30;
if ((id(power_t0) / 10.0) > 599 and (id(power_t0) / 10.0) < 659) relOutputPower = 33;
if ((id(power_t0) / 10.0) > 659 and (id(power_t0) / 10.0) < 699) relOutputPower = 35;
if ((id(power_t0) / 10.0) > 699 and (id(power_t0) / 10.0) < 759) relOutputPower = 38;
if ((id(power_t0) / 10.0) > 759 and (id(power_t0) / 10.0) < 799) relOutputPower = 40;
if ((id(power_t0) / 10.0) > 799 and (id(power_t0) / 10.0) < 859) relOutputPower = 43;
if ((id(power_t0) / 10.0) > 859 and (id(power_t0) / 10.0) < 899) relOutputPower = 45;
if ((id(power_t0) / 10.0) > 899 and (id(power_t0) / 10.0) < 959) relOutputPower = 48;
if ((id(power_t0) / 10.0) > 959 and (id(power_t0) / 10.0) < 999) relOutputPower = 50;
if ((id(power_t0) / 10.0) > 999 and (id(power_t0) / 10.0) < 1059) relOutputPower = 53;
if ((id(power_t0) / 10.0) > 1059 and (id(power_t0) / 10.0) < 1099) relOutputPower = 55;
if ((id(power_t0) / 10.0) > 1099 and (id(power_t0) / 10.0) < 1159) relOutputPower = 58;
if ((id(power_t0) / 10.0) > 1159 and (id(power_t0) / 10.0) < 1199) relOutputPower = 60;
if ((id(power_t0) / 10.0) > 1199 and (id(power_t0) / 10.0) < 1259) relOutputPower = 63;
if ((id(power_t0) / 10.0) > 1259 and (id(power_t0) / 10.0) < 1299) relOutputPower = 65;
if ((id(power_t0) / 10.0) > 1299 and (id(power_t0) / 10.0) < 1359) relOutputPower = 68;
if ((id(power_t0) / 10.0) > 1359 and (id(power_t0) / 10.0) < 1399) relOutputPower = 70;
if ((id(power_t0) / 10.0) > 1399 and (id(power_t0) / 10.0) < 1459) relOutputPower = 73;
if ((id(power_t0) / 10.0) > 1459 and (id(power_t0) / 10.0) < 1499) relOutputPower = 75;
if ((id(power_t0) / 10.0) > 1499 and (id(power_t0) / 10.0) < 1559) relOutputPower = 78;
if ((id(power_t0) / 10.0) > 1559 and (id(power_t0) / 10.0) < 1599) relOutputPower = 80;
if ((id(power_t0) / 10.0) > 1599 and (id(power_t0) / 10.0) < 1659) relOutputPower = 83;
if ((id(power_t0) / 10.0) > 1659 and (id(power_t0) / 10.0) < 1699) relOutputPower = 85;
if ((id(power_t0) / 10.0) > 1699 and (id(power_t0) / 10.0) < 1759) relOutputPower = 88;
if ((id(power_t0) / 10.0) > 1759 and (id(power_t0) / 10.0) < 1799) relOutputPower = 90;
if ((id(power_t0) / 10.0) > 1799 and (id(power_t0) / 10.0) < 1859) relOutputPower = 93;
if ((id(power_t0) / 10.0) > 1859 and (id(power_t0) / 10.0) < 1899) relOutputPower = 95;
if ((id(power_t0) / 10.0) > 1899 and (id(power_t0) / 10.0) < 1959) relOutputPower = 98;
if ((id(power_t0) / 10.0) > 1959 and (id(power_t0) / 10.0) < 2001) relOutputPower = 100;
if ((id(power_t0) / 10.0) > 2000) / 10.0) relOutputPower = 100;
if ((id(power_t0) / 10.0) < 200 and (id(power_t0) / 10.0) < 49) relOutputPower = 10;
if (relOutputPower > 100) relOutputPower = 100; // Maximum should be allways 100 %
PowerSet = relOutputPower / 1000.0 * powerMax;
ToGridPower = (relOutputPower / 1000.0 * powerMax) - (id(power_t0) / 10.0);
if ( id(GrowattPower) < 1 ) ToGridPower = 0;
ESP_LOGD("main", "Relative Output Power: %d percent", relOutputPower);
ESP_LOGD("main", "Calculated Output Power: %d percent", calOutputPower);
ESP_LOGD("main", "Set Output Power to: %d Watt", PowerSet);
ESP_LOGD("main", "Real Consumed Power: %d Watt", consumePower);
ESP_LOGD("main", "Power from Grid: %d Watt", GridPower);
ESP_LOGD("main", "Power to Grid: %d Watt", ToGridPower);
esphome::modbus_controller::ModbusController *controller = id(growatt);
uint16_t reg = 3; // Register: Max output active power (in %)
modbus_controller::ModbusCommandItem setOutputPower_command = modbus_controller::ModbusCommandItem::create_write_single_command(controller, reg, relOutputPower);
controller->queue_command(setOutputPower_command);