コード例 #1
0
        /// <summary>
        /// Writes the slice of the current data.
        /// </summary>
        public void WriteCurrentData(DeviceSlice deviceSlice)
        {
            if (deviceSlice == null)
            {
                throw new ArgumentNullException(nameof(deviceSlice));
            }

            if (varByDevice != null && varByDevice.TryGetValue(deviceSlice.DeviceNum, out DeviceVars deviceVars))
            {
                lock (dataLock)
                {
                    int dataIndex = 0;

                    foreach (DeviceTag deviceTag in deviceSlice.DeviceTags)
                    {
                        if (deviceVars.TryGetValue(deviceTag.Code, out VarItem varItem))
                        {
                            SetVariable(varItem, deviceSlice.CnlData, dataIndex, deviceSlice.Timestamp);
                        }

                        dataIndex += deviceTag.DataLength;
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Converts the device slice to a general purpose slice.
        /// </summary>
        private bool ConvertSlice(DeviceSlice srcSlice, out Slice destSlice)
        {
            try
            {
                int        srcDataLength  = srcSlice.CnlData.Length;
                int        destDataLength = 0;
                List <int> cnlNums        = new List <int>(srcDataLength);

                foreach (DeviceTag deviceTag in srcSlice.DeviceTags)
                {
                    if (deviceTag.InCnl != null)
                    {
                        cnlNums.Add(deviceTag.InCnl.CnlNum);
                        destDataLength += deviceTag.DataLength;
                    }
                }

                if (destDataLength == 0)
                {
                    destSlice = null;
                    return(false);
                }
                else if (destDataLength == srcDataLength)
                {
                    destSlice = new Slice(srcSlice.Timestamp, cnlNums.ToArray(), srcSlice.CnlData);
                    return(true);
                }
                else
                {
                    CnlData[] destCnlData = new CnlData[destDataLength];
                    int       dataIndex   = 0;

                    foreach (DeviceTag deviceTag in srcSlice.DeviceTags)
                    {
                        if (deviceTag.InCnl != null)
                        {
                            // TODO: bug, deviceTag.DataIndex is inapropriate here
                            int tagDataLength = deviceTag.DataLength;
                            Array.Copy(srcSlice.CnlData, deviceTag.DataIndex, destCnlData, dataIndex, tagDataLength);
                            dataIndex += tagDataLength;
                        }
                    }

                    destSlice = new Slice(srcSlice.Timestamp, cnlNums.ToArray(), destCnlData);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                log.WriteException(ex, CommPhrases.DataSourceMessage, Code, string.Format(Locale.IsRussian ?
                                                                                          "Ошибка при конвертировании среза от устройства {0}" :
                                                                                          "Error converting slice from the device {0}", srcSlice.DeviceNum));
                destSlice = null;
                return(false);
            }
        }
コード例 #3
0
 /// <summary>
 /// Calls the FailedToSendCallback method of the device slice.
 /// </summary>
 private void CallFailedToSend(DeviceSlice deviceSlice)
 {
     try
     {
         deviceSlice.FailedToSendCallback?.Invoke(deviceSlice, Code);
     }
     catch (Exception ex)
     {
         log.WriteError(ex, CommPhrases.DataSourceMessage, Code, Locale.IsRussian ?
                        "Ошибка при вызове метода среза FailedToSendCallback" :
                        "Error calling the FailedToSendCallback method of the slice");
     }
 }
コード例 #4
0
        /// <summary>
        /// Publishes the device slice.
        /// </summary>
        private bool PublishDeviceSlice(DeviceSlice deviceSlice)
        {
            try
            {
                if (topicByDevice.TryGetValue(deviceSlice.DeviceNum, out DeviceTopics deviceTopics))
                {
                    int dataIndex = 0;

                    foreach (DeviceTag deviceTag in deviceSlice.DeviceTags)
                    {
                        if (!string.IsNullOrEmpty(deviceTag.Code) &&
                            deviceTopics.TryGetValue(deviceTag.Code, out string topic))
                        {
                            string payloadStr = BuildPayload(deviceTag, deviceSlice.CnlData, dataIndex);
                            MqttApplicationMessage message = new()
                            {
                                Topic   = topic,
                                Payload = Encoding.UTF8.GetBytes(payloadStr),
                                QualityOfServiceLevel = (MqttQualityOfServiceLevel)dsOptions.PublishOptions.QosLevel,
                                Retain = dsOptions.PublishOptions.Retain
                            };

                            if (dsOptions.PublishOptions.DetailedLog)
                            {
                                dsLog.WriteAction("{0} {1} = {2}", CommPhrases.SendNotation, topic, payloadStr);
                            }

                            MqttClientPublishResult result = mqttClientHelper.Publish(message);

                            if (result.ReasonCode != MqttClientPublishReasonCode.Success)
                            {
                                dsLog.WriteError(CommPhrases.ErrorPrefix + result.ReasonCode);
                                return(false);
                            }
                        }

                        dataIndex += deviceTag.DataLength;
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                dsLog.WriteError(ex, Locale.IsRussian ?
                                 "Ошибка при публикации данных" :
                                 "Error publishing data");
                return(false);
            }
        }
コード例 #5
0
        /// <summary>
        /// Sends the telecontrol command.
        /// </summary>
        public override void SendCommand(TeleCommand cmd)
        {
            base.SendCommand(cmd);

            if (cmd.CmdCode == TagCode.DO || cmd.CmdNum == 4)
            {
                double relayVal = cmd.CmdVal > 0 ? 1 : 0;
                Log.WriteLine(Locale.IsRussian ?
                              "Установить состояние реле в {0}" :
                              "Set the relay state to {0}", relayVal);
                DeviceData.Set(TagCode.DO, relayVal);
            }
            else if (cmd.CmdCode == TagCode.AO || cmd.CmdNum == 5)
            {
                Log.WriteLine(Locale.IsRussian ?
                              "Установить аналоговый выход в {0}" :
                              "Set the analog output to {0}", cmd.CmdVal);
                DeviceData.Set(TagCode.AO, cmd.CmdVal);
            }
            else if (cmd.CmdCode == "Hist")
            {
                // demonstrate how to create a historical data slice
                DateTime    now         = DateTime.UtcNow;
                DeviceSlice deviceSlice = new DeviceSlice(
                    new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc),
                    1, 1);
                deviceSlice.DeviceTags[0] = DeviceTags[TagCode.Sin];
                deviceSlice.CnlData[0]    = new CnlData(cmd.CmdVal, CnlStatusID.Defined);
                deviceSlice.Descr         = "Demo slice";
                DeviceData.EnqueueSlice(deviceSlice);
            }
            else if (cmd.CmdCode == "Event")
            {
                // demonstrate how to create an event
                DeviceData.EnqueueEvent(new DeviceEvent(DeviceTags[TagCode.Sin])
                {
                    Timestamp = DateTime.UtcNow,
                    CnlVal    = cmd.CmdVal,
                    CnlStat   = CnlStatusID.Defined,
                    Descr     = "Demo event"
                });
            }
            else
            {
                LastRequestOK = false;
                Log.WriteLine(CommPhrases.InvalidCommand);
            }

            FinishCommand();
        }
コード例 #6
0
 /// <summary>
 /// Calls the WriteHistoricalData method of the data sources.
 /// </summary>
 public void WriteHistoricalData(DeviceSlice deviceSlice)
 {
     foreach (DataSourceLogic dataSourceLogic in dataSources)
     {
         try
         {
             if (dataSourceLogic.IsReady)
             {
                 dataSourceLogic.WriteHistoricalData(deviceSlice);
             }
         }
         catch (Exception ex)
         {
             log.WriteException(ex, CommPhrases.ErrorInDataSource,
                                nameof(WriteHistoricalData), dataSourceLogic.Code);
         }
     }
 }
コード例 #7
0
        /// <summary>
        /// Writes the slice of the current data.
        /// </summary>
        public override void WriteCurrentData(DeviceSlice deviceSlice)
        {
            if (CheckDeviceFilter(deviceSlice.DeviceNum))
            {
                lock (curDataQueue)
                {
                    // remove current data from the beginning of the queue
                    while (curDataQueue.Count >= maxQueueSize)
                    {
                        curDataQueue.Dequeue();
                        curDataSkipped++;
                    }

                    // append current data
                    curDataQueue.Enqueue(new QueueItem <DeviceSlice>(deviceSlice.Timestamp, deviceSlice));
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Writes the slice of the current data.
        /// </summary>
        public override void WriteCurrentData(DeviceSlice deviceSlice)
        {
            if (CheckDeviceFilter(deviceSlice.DeviceNum))
            {
                lock (curDataQueue)
                {
                    // remove data if capacity is not enough
                    while (curDataQueue.Count >= maxQueueSize)
                    {
                        curDataQueue.Dequeue();
                        curDataSkipped++;
                    }

                    // append current data
                    curDataQueue.Enqueue(new QueueItem <DeviceSlice>(deviceSlice.Timestamp, deviceSlice));
                }
            }
        }
コード例 #9
0
ファイル: CommLine.cs プロジェクト: RapidScada/scada-v6
        /// <summary>
        /// Transfers data from the device to the server.
        /// </summary>
        private void TransferDeviceData(DeviceLogic deviceLogic, bool allData)
        {
            // current data
            DeviceSlice currentSlice = deviceLogic.GetCurrentData(allData);

            if (!currentSlice.IsEmpty)
            {
                coreLogic.EnqueueCurrentData(currentSlice);
            }

            // historical data
            while (deviceLogic.DeviceData.DequeueSlice(out DeviceSlice historicalSlice))
            {
                coreLogic.EnqueueHistoricalData(historicalSlice);
            }

            // events
            while (deviceLogic.DeviceData.DequeueEvent(out DeviceEvent deviceEvent))
            {
                coreLogic.EnqueueEvent(deviceEvent);
            }
        }
コード例 #10
0
        /// <summary>
        /// Writes the slice of historical data.
        /// </summary>
        public override void WriteHistoricalData(DeviceSlice deviceSlice)
        {
            if (CheckDeviceFilter(deviceSlice.DeviceNum))
            {
                lock (histDataQueue)
                {
                    if (histDataQueue.Count < maxQueueSize)
                    {
                        histDataQueue.Enqueue(new QueueItem <DeviceSlice>(DateTime.UtcNow, deviceSlice));
                    }
                    else
                    {
                        log.WriteError(CommPhrases.DataSourceMessage, Code, string.Format(Locale.IsRussian ?
                                                                                          "Невозможно добавить исторические данные в очередь. Максимальный размер очереди {0} превышен" :
                                                                                          "Unable to enqueue historical data. The maximum size of the queue {0} is exceeded",
                                                                                          maxQueueSize));

                        histDataSkipped++;
                        CallFailedToSend(deviceSlice);
                    }
                }
            }
        }
コード例 #11
0
 /// <summary>
 /// Writes the slice of historical data.
 /// </summary>
 public virtual void WriteHistoricalData(DeviceSlice deviceSlice)
 {
 }
コード例 #12
0
 /// <summary>
 /// Writes the slice of the current data.
 /// </summary>
 public virtual void WriteCurrentData(DeviceSlice deviceSlice)
 {
 }
コード例 #13
0
        /// <summary>
        /// Converts the device slice to a general purpose slice.
        /// </summary>
        private bool ConvertSlice(DeviceSlice srcSlice, out Slice destSlice)
        {
            try
            {
                int        srcDataLength  = srcSlice.CnlData.Length;
                int        destDataLength = 0;
                List <int> cnlNums        = new List <int>(srcDataLength);

                foreach (DeviceTag deviceTag in srcSlice.DeviceTags)
                {
                    if (deviceTag == null)
                    {
                        throw new ScadaException(Locale.IsRussian ?
                                                 "Неопределенные теги в срезе не допускаются." :
                                                 "Undefined tags are not allowed in a slice.");
                    }

                    if (deviceTag.Cnl != null)
                    {
                        int tagDataLength = deviceTag.DataLength;

                        for (int i = 0; i < tagDataLength; i++)
                        {
                            cnlNums.Add(deviceTag.Cnl.CnlNum + i);
                        }

                        destDataLength += tagDataLength;
                    }
                }

                if (destDataLength == 0)
                {
                    destSlice = null;
                    return(false);
                }
                else if (destDataLength == srcDataLength)
                {
                    destSlice = new Slice(srcSlice.Timestamp, cnlNums.ToArray(), srcSlice.CnlData);
                    return(true);
                }
                else
                {
                    CnlData[] destCnlData   = new CnlData[destDataLength];
                    int       srcDataIndex  = 0;
                    int       destDataIndex = 0;

                    foreach (DeviceTag deviceTag in srcSlice.DeviceTags)
                    {
                        int tagDataLength = deviceTag.DataLength;

                        if (deviceTag.Cnl != null)
                        {
                            Array.Copy(srcSlice.CnlData, srcDataIndex, destCnlData, destDataIndex, tagDataLength);
                            destDataIndex += tagDataLength;
                        }

                        srcDataIndex += tagDataLength;
                    }

                    destSlice = new Slice(srcSlice.Timestamp, cnlNums.ToArray(), destCnlData);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                log.WriteError(ex, CommPhrases.DataSourceMessage, Code, string.Format(Locale.IsRussian ?
                                                                                      "Ошибка при конвертировании среза от устройства {0}" :
                                                                                      "Error converting slice from the device {0}", srcSlice.DeviceNum));
                destSlice = null;
                return(false);
            }
        }
コード例 #14
0
 /// <summary>
 /// Writes the slice of the current data.
 /// </summary>
 public override void WriteCurrentData(DeviceSlice deviceSlice)
 {
     opcServer?.NodeManager?.WriteCurrentData(deviceSlice);
 }