Exemple #1
0
        /// <summary>
        /// Sends the full data updates.
        /// </summary>
        public static void TransmitFullDataUpdates()
        {
            lock (_sycnRoot)
            {
                SolarEdgeFullData SED = DataFetcher.Instance.SolarEdgeFullData;

                for (int i = _FullUpdateCallbackChannels.Count - 1; i >= 0; i--)
                {
                    if (((ICommunicationObject)_FullUpdateCallbackChannels[i]).State != CommunicationState.Opened)
                    {
                        log.DebugFormat("Detected Non-Open Callback Channel for full data updates: {0}", _FullUpdateCallbackChannels[i].GetHashCode());
                        _FullUpdateCallbackChannels.RemoveAt(i);
                        continue;
                    }

                    try
                    {
                        _FullUpdateCallbackChannels[i].TransmitFullDataUpdate(SED);
                        log.DebugFormat("Pushed full data update on Callback Channel: {0}", _FullUpdateCallbackChannels[i].GetHashCode());
                    }
                    catch (Exception ex)
                    {
                        log.Debug("Service threw exception while communicating on Callback Channel for full data updates: {0}".Build(_FullUpdateCallbackChannels[i].GetHashCode()), ex);
                        _FullUpdateCallbackChannels.RemoveAt(i);
                    }
                }
            }
        }
        private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (locker)
            {
                if (modbusClient != null)
                {
                    updateTimer.Stop();

                    DateTime updateStart = DateTime.Now;

                    bool  updateSucces     = false;
                    int[] inverterResponse = null;
                    int[] meterResponse    = null;;

                    TimeSpan inverterReadDuration = TimeSpan.MinValue;
                    TimeSpan meterReadDuration    = TimeSpan.MinValue;
                    string   ExceptionText        = "";
                    try
                    {
                        if (!ConnectionEstablished)
                        {
                            try
                            {
                                ConnectToModBus();
                                log.Debug($"Modbus connection established for {IPAdress}:{ModBusPort}");
                            }
                            catch (Exception E)
                            {
                                log.Debug($"A exeception occured while establishing Modbos connection to {IPAdress}:{ModBusPort}. {E.Message}", E);
                                throw new Exception($"A exeception occured while establishing Modbos connection to {IPAdress}:{ModBusPort} {E.Message}", E);
                            }
                        }

                        if (ReadInverterData)
                        {
                            try
                            {
                                DateTime StartTime = DateTime.Now;
                                inverterResponse     = modbusClient.ReadHoldingRegisters(inverterStartPos, inverterNumberOfRegisters);
                                inverterReadDuration = DateTime.Now - StartTime;
                                log.Debug($"Inverter data read: {inverterReadDuration.TotalMilliseconds}ms");
                            }
                            catch (Exception E)
                            {
                                log.Debug($"Reading inverter data failed. {E.Message}", E);
                                throw new Exception($"Reading inverter data failed. {E.Message}", E);
                            }

                            if (inverterResponse == null || inverterResponse.All(v => v == 0))
                            {
                                log.Debug("No valid data received from inverter.");
                                throw new Exception("No valid data received from inverter.");
                            }
                        }

                        if (ReadMeterData)
                        {
                            try
                            {
                                DateTime StartTime = DateTime.Now;
                                meterResponse     = modbusClient.ReadHoldingRegisters(meterStartPos, meterNumberOfRegisters);
                                meterReadDuration = DateTime.Now - StartTime;
                                log.Debug($"Meter data read: {meterReadDuration.TotalMilliseconds}ms");
                            }
                            catch (Exception E)
                            {
                                log.Debug($"Reading meter data failed. {E.Message}", E);
                                throw new Exception($"Reading meter data failed. {E.Message}", E);
                            }


                            if (meterResponse == null || meterResponse.All(v => v == 0))
                            {
                                log.Debug("No valid data received from inverter.");
                                throw new Exception("No valid data received from inverter.");
                            }
                        }
                    }
                    catch (Exception E)
                    {
                        ExceptionText = E.Message;
                    }

                    if (!ExceptionText.IsNullOrWhiteSpace())
                    {
                        log.Debug($"Exception occured while establishing the connection or while reading data.\n{ExceptionText}");
                        DisconnectFromModbus();
                    }
                    else
                    {
                        ModbusDataUpdater U = new ModbusDataUpdater();

                        try
                        {
                            switch (DataUpdateMode)
                            {
                            case DataUpdateModeEnum.UpdateExistingObjects:

                                lock (DataLocker)
                                {
                                    if (SolarEdgeFullData == null)
                                    {
                                        SolarEdgeFullData = new SolarEdgeFullData();
                                    }

                                    if (ReadInverterData)
                                    {
                                        U.UpdateData(inverterResponse, inverterStartPos, SolarEdgeFullData);
                                    }
                                    if (ReadMeterData)
                                    {
                                        U.UpdateData(meterResponse, meterStartPos, SolarEdgeFullData);
                                    }

                                    if (_SolarEdgeBaseData == null)
                                    {
                                        SolarEdgeBaseData = new SolarEdgeBaseData();
                                    }
                                    if (ReadInverterData)
                                    {
                                        U.UpdateData(inverterResponse, inverterStartPos, SolarEdgeBaseData);
                                    }
                                    if (ReadMeterData)
                                    {
                                        U.UpdateData(meterResponse, meterStartPos, SolarEdgeBaseData);
                                    }
                                };
                                break;

                            case DataUpdateModeEnum.CreateNewObjects:
                                SolarEdgeFullData FD = new SolarEdgeFullData();
                                if (ReadInverterData)
                                {
                                    U.UpdateData(inverterResponse, inverterStartPos, FD);
                                }
                                if (ReadMeterData)
                                {
                                    U.UpdateData(meterResponse, meterStartPos, FD);
                                }

                                SolarEdgeBaseData BD = new SolarEdgeBaseData();
                                if (ReadInverterData)
                                {
                                    U.UpdateData(inverterResponse, inverterStartPos, BD);
                                }
                                if (ReadMeterData)
                                {
                                    U.UpdateData(meterResponse, meterStartPos, BD);
                                }


                                lock (DataLocker)
                                {
                                    SolarEdgeFullData = FD;
                                    SolarEdgeBaseData = BD;
                                };
                                break;

                            default:
                                log.Error($"Unknown {nameof(DataUpdateMode)} {DataUpdateMode}");
                                throw new Exception($"Unknown {nameof(DataUpdateMode)} {DataUpdateMode}");
                            }



                            successiveFailCount = 0;
                            updateSucces        = true;
                            log.Debug("Data successfully updated");
                        }
                        catch (Exception E)
                        {
                            successiveFailCount++;

                            log.Warn($"Updating data failed. {E.Message}", E);

                            if (successiveFailCount > maxSuccessiveFails)
                            {
                                DisconnectFromModbus();
                                log.Debug($"Disconnected from Modbus on {IPAdress}:{ModBusPort}\n{ExceptionText}. Data update failed more than {maxSuccessiveFails} times.");
                                successiveFailCount = 0;
                            }
                        }
                    }



                    if (updateSucces)
                    {
                        LastDataUpdate = DateTime.Now;

                        SolarEdgeDataIsValid = true;

                        StartDataValidTimeoutTimer();

                        OnSolarEdgeDataUpdated();
                    }
                    else
                    {
                        OnSolarEdgeDataUpdateFailed();
                    }


                    int totalUpdateDurationMs = (int)(DateTime.Now - updateStart).TotalMilliseconds;

                    int sleepDurationMs = (RefreshIntervalMs - totalUpdateDurationMs).Limit(MinIntervalBetweenUpdatesMs.Limit(10, int.MaxValue), int.MaxValue);

                    log.Debug($"Update duration {totalUpdateDurationMs}ms. Will wait for {sleepDurationMs}ms before next update.");

                    updateTimer.Interval = sleepDurationMs;

                    updateTimer.Start();
                }
                else
                {
                    log.Warn($"{nameof(modbusClient)} is null. Most likely Stop has been called.");
                }
            }
        }