I have 3 solaredge inverters that do not accept the calls, i use automations with a trigger, then use the beautiful flow of node red to still achieve what i want the call to be but then its activated over automation.
Hereβs what chatGPT says about it:
Yes, there are known issues when using node-red-contrib-modbus with SolarEdge inverters. Some users have reported challenges, such as timeouts, communication errors, or incompatibilities, when trying to control or read data from SolarEdge inverters via Modbus TCP using Node-RED. Below are common issues and potential solutions or workarounds:
Common Issues:
Connection Timeouts: The Modbus connection may time out if SolarEdge inverters are busy processing data or if the polling rate is too fast.
Unit ID Confusion: SolarEdge inverters use Unit ID 1 by default for Modbus communication. Setting the wrong Unit ID can prevent the commands from reaching the inverter.
Modbus Register Address Offsets: Some Modbus clients add an offset to register addresses, so a register like 62852 might need to be referenced as 62851 or 62853, depending on the implementation.
Poll Rate Issues: Polling too frequently can overwhelm the inverterβs Modbus communication stack, leading to dropped connections.
Working Configuration for Node-RED:
To avoid issues with node-red-contrib-modbus and SolarEdge inverters, follow these guidelines when controlling the batteryβs charge and discharge power registers (62852 for charging and 62853 for discharging):
1. Modbus Timeout and Retries:
Client Timeout: Set a relatively high timeout in the Modbus client (e.g., 5000 ms) to give the SolarEdge inverter enough time to respond.
Reconnect Timeout: Set the reconnect timeout to around 2000 ms if a connection is dropped.
Retries: Set retries to 3 or 5 to ensure commands are sent even when thereβs transient communication failure.
2. Modbus Write Configuration:
Data Type: Use the Holding Register type, as SolarEdge expects this for control commands.
Register Addressing: Directly target registers 62852 and 62853. Make sure your Modbus client does not add an offset. If it does, adjust the addresses accordingly (e.g., try 62851 or 62853 if you encounter errors).
3. Modbus Polling Frequency:
For reading data, ensure that the polling frequency is set to something moderate, like every 5 or 10 seconds, rather than continuous fast polling. For writing (charge/discharge commands), ensure that you donβt send commands too frequently to avoid overwhelming the inverter.
4. Avoid Overwriting Control Registers:
Some SolarEdge models may have conflicts when you attempt to write to both charge and discharge power registers simultaneously. Ensure youβre only writing to one register at a time (e.g., either to charge or discharge, but not both).
Example Node-RED Flow for Charge/Discharge Control:
Payload: The payload is sent in an array format where the power is expressed in watts. For example, a charge rate of 2 kW will be sent as [2000].
Further Considerations:
Make sure to validate the behavior of your inverter and battery system when writing to these registers. SolarEdge firmware updates or changes to battery management may impact the functionality of these registers.
Test carefully to avoid setting conflicting values (e.g., trying to charge and discharge at the same time).
By following these configuration tips and best practices, you should be able to control the charging and discharging of your BYD battery via the SolarEdge inverter with minimal issues using Node-RED.
Actually the one you mention doesnβt require any stats, rather the ones you use to create it need stats.
It depends if you use machine learning (as much as possible but you have to check effectiveness yourself) or day ahead, BTW 24h minimum.
Hello,
I am currently trying to get the mlforecaster working. The normal MPC optimisation works fine but when I try to run the model fit function one of two things happens:
when setting days to retrieve to 3:
2024-10-04 18:26:55,003 - web_server - INFO - Passed runtime parameters: {'days_to_retrieve': 3, 'var_model': 'sensor.power_load_no_var_loads', 'num_lags': 48}
2024-10-04 18:26:55,003 - web_server - INFO - >> Setting input data dict
2024-10-04 18:26:55,003 - web_server - INFO - Setting up needed data
2024-10-04 18:26:55,007 - web_server - INFO - Retrieve hass get data method initiated...
2024-10-04 18:26:56,854 - web_server - INFO - >> Performing a machine learning forecast model fit...
2024-10-04 18:26:56,855 - web_server - INFO - Performing a forecast model fit for load_forecast
2024-10-04 18:26:56,859 - web_server - INFO - Training a KNeighborsRegressor model
2024-10-04 18:26:56,866 - web_server - ERROR - Exception on /action/forecast-model-fit [POST]
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1473, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 882, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 880, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 865, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/web_server.py", line 179, in action_call
df_fit_pred, _, mlf = forecast_model_fit(input_data_dict, app.logger)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/command_line.py", line 498, in forecast_model_fit
df_pred, df_pred_backtest = mlf.fit(
^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/machine_learning_forecaster.py", line 153, in fit
self.forecaster.fit(y=self.data_train[self.var_model],
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 606, in fit
data = self.regressor.predict(X_train),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/sklearn/neighbors/_regression.py", line 242, in predict
neigh_ind = self.kneighbors(X, return_distance=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/sklearn/neighbors/_base.py", line 835, in kneighbors
raise ValueError(
ValueError: Expected n_neighbors <= n_samples_fit, but n_neighbors = 5, n_samples_fit = 1, n_samples = 1
when setting the days to 30:
2024-10-04 18:27:34,930 - web_server - INFO - Passed runtime parameters: {'days_to_retrieve': 30, 'var_model': 'sensor.power_load_no_var_loads', 'num_lags': 48}
2024-10-04 18:27:34,930 - web_server - INFO - >> Setting input data dict
2024-10-04 18:27:34,930 - web_server - INFO - Setting up needed data
2024-10-04 18:27:34,932 - web_server - INFO - Retrieve hass get data method initiated...
2024-10-04 18:27:34,940 - web_server - ERROR - The retrieved JSON is empty, A sensor:sensor.power_load_no_var_loads may have 0 days of history, passed sensor may not be correct, or days to retrieve is set too heigh
the sensor sensor.power_load_no_var_loads has data going back ~300 days so there must be enough data there. Maybe there are some very small gaps in the data because of reboots during updates.
The sensor also works great when doing MPC optimisations. I pass the data into the runtime like @rcruikshank is suggesting in node Red.
Does anyone know what I am missing? Thanks in advance
What happens when you try to retrieve 1 or 2 days only? Same error?
If your recorder is correctly set then this may be similar to some issues some us faced from time to time with βnot availableβ data.
Missing data because of reboot should not be a problem, if I correctly remember David implemented some interpolation.
To start with I suggest you to set 1 day and in one day try again, so you already have a partial answer to the possible cause of the problem.
when I set the days to one or 2 I get the following error:
2024-10-04 18:44:16,978 - web_server - INFO - Passed runtime parameters: {'days_to_retrieve': 2, 'var_model': 'sensor.power_load_no_var_loads', 'num_lags': 48}
2024-10-04 18:44:16,979 - web_server - INFO - >> Setting input data dict
2024-10-04 18:44:16,979 - web_server - INFO - Setting up needed data
2024-10-04 18:44:16,983 - web_server - INFO - Retrieve hass get data method initiated...
2024-10-04 18:44:18,286 - web_server - INFO - >> Performing a machine learning forecast model fit...
2024-10-04 18:44:18,286 - web_server - INFO - Performing a forecast model fit for load_forecast
2024-10-04 18:44:18,292 - web_server - INFO - Training a KNeighborsRegressor model
2024-10-04 18:44:18,294 - web_server - ERROR - Exception on /action/forecast-model-fit [POST]
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1473, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 882, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 880, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 865, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/web_server.py", line 179, in action_call
df_fit_pred, _, mlf = forecast_model_fit(input_data_dict, app.logger)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/command_line.py", line 498, in forecast_model_fit
df_pred, df_pred_backtest = mlf.fit(
^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/machine_learning_forecaster.py", line 153, in fit
self.forecaster.fit(y=self.data_train[self.var_model],
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 578, in fit
X_train, y_train = self.create_train_X_y(y=y, exog=exog)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 457, in create_train_X_y
X_train, y_train = self._create_lags(y=y_values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 364, in _create_lags
raise ValueError(
ValueError: The maximum lag (48) must be less than the length of the series (2).
The data is working for MPC optimisation. But that one would probably only need the last day (?)
Any elaboration approach (MPC or day ahead) need future load data (letβs say 24h for simplicity).
Naive approach uses past 24h and assumes the same will occur tomorrow, ML uses past X days to train a model and then simulate the load for the next 24h.
I assume you set this so MPC knows which data to use (naive vs. ML).
In general these errors are quite tricky to identify, my suggestion is to set model fit to 1 day and check again in one day. We may bump hour head on the wall now and still not be able to fix the problem. If in one day the issue is still there itβs something else, maybe on the data you pass or in the command.
In particular this makes me think there is no data enough at this moment:
The maximum lag (48) must be less than the length of the series (2).
ok. Iβll wait and look at this line tomorrow maybe something changes. Its just a bit sad to loose the 300 days of data. But if that one day works, maybe it is possible to continously fine tune to get a result quicker (?)
Thanks for the help again
just one additional discovery when setting days to 1 and lags to 20. Then the data is 0? That is strange:
2024-10-04 19:08:26,801 - web_server - INFO - Passed runtime parameters: {'days_to_retrieve': 1, 'var_model': 'sensor.power_load_no_var_loads', 'num_lags': 20}
2024-10-04 19:08:26,801 - web_server - INFO - >> Setting input data dict
2024-10-04 19:08:26,801 - web_server - INFO - Setting up needed data
2024-10-04 19:08:26,806 - web_server - INFO - Retrieve hass get data method initiated...
2024-10-04 19:08:27,449 - web_server - INFO - >> Performing a machine learning forecast model fit...
2024-10-04 19:08:27,449 - web_server - INFO - Performing a forecast model fit for load_forecast
2024-10-04 19:08:27,454 - web_server - INFO - Training a KNeighborsRegressor model
2024-10-04 19:08:27,456 - web_server - ERROR - Exception on /action/forecast-model-fit [POST]
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1473, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 882, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 880, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 865, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/web_server.py", line 179, in action_call
df_fit_pred, _, mlf = forecast_model_fit(input_data_dict, app.logger)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/command_line.py", line 498, in forecast_model_fit
df_pred, df_pred_backtest = mlf.fit(
^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/emhass/machine_learning_forecaster.py", line 153, in fit
self.forecaster.fit(y=self.data_train[self.var_model],
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 578, in fit
X_train, y_train = self.create_train_X_y(y=y, exog=exog)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 457, in create_train_X_y
X_train, y_train = self._create_lags(y=y_values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/skforecast/ForecasterAutoreg/ForecasterAutoreg.py", line 364, in _create_lags
raise ValueError(
ValueError: The maximum lag (20) must be less than the length of the series (0).
I know. Letβs see. But donβt think that with that 300 days you will get a perfect prediction. For example I tried with 4 weeks and I canβt get anything good enough, most probably itβs related to the predictability of the load signal, so I preferred to go back to naive. Some of us use ML others naive, it depends on the outcome.
Yes, you can continuously improve the model, but every day you will have to increase the number of days that are retrieved.
Anyway in my experience naive is good enough to start.
Im struggling to find why the system wouldnt prioritise a full charge in the batteries prior to export limiting.
Surely this can be adjusted? I think its very silly as the weather can change and it should be prioritised as most days the batteries can miss a full charge with a storm rolling in and solcast not picking up on it.
Itβs a bit related to the way EMHASS works, with a final target SOC, I think.
One possibility is to work with a 24h rolling window, so basically you are always postponing the battery target SOC and focus on the short-mid term.
Another option is to take control only when EMHASS suggests to charge from the grid (when PV is zero) and for the rest of the time let the battery work autonomously. But in such case the impact on how deferrable loads work should be assessed.
A third option I didnβt check is to have a longer forecast, in such case the target soc would occur in 48h and so - maybe - the batteries are pushed to higher charge values for the next 24h.
Does anyone use their in emhass for electric underfloor heating in a bathroom. I will work on that around the clock but maybe fluctuate with the temperature up and down depending on your price
If so, how would one proceed?