public void UpdateModule(IPlc PLC, ref long ReqTime, Action <int, dynamic> Callback) { int runs = 0; while (true) { Thread.Sleep(5000); List <BsonDocument> req = new List <BsonDocument>(); try { req.Add(BsonDocument.Parse("{ time : " + ReqTime + ", ClientId : '" + PLC.ClientDetails["id"].ToString() + "', Site : '" + PLC.ClientDetails["Site"].ToString() + "',_ts : " + (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds + "}")); Database.MultiInstert("Monitor", "RequestTime", req); } catch { } runs++; if (runs == 20) { List <BsonDocument> temp = UpdateDatastreams(PLC, Database); foreach (BsonDocument Stream in temp) { Stream["oldTime"] = 0; } Callback(1, temp); runs = 0; } } }
public PlcDaemon(Datenstruktur datenstruktur, Action <Datenstruktur, bool> cbRangieren) { Plc = new KeineSps(); _datenstruktur = datenstruktur; _callbackRangieren = cbRangieren; try { _spsS7_1200 = JsonConvert.DeserializeObject <IpAdressenSiemens>(File.ReadAllText("IpAdressenSiemens.json")); } catch (Exception ex) { MessageBox.Show("Datei nicht gefunden: IpAdressenSiemens.json" + " --> " + ex); } try { _spsCx9020 = JsonConvert.DeserializeObject <IpAdressenBeckhoff>(File.ReadAllText("IpAdressenBeckhoff.json")); } catch (Exception ex) { MessageBox.Show("Datei nicht gefunden: IpAdressenBeckhoff.json" + " --> " + ex); } System.Threading.Tasks.Task.Run(PlcDaemonTask); }
public void OneTimeSetUp() { IPlc plc = Substitute.For <IPlc>(); ILoggerFactory loggerFactory = Substitute.For <ILoggerFactory>(); this.isEndValueReadEventCallback = false; this.isEndValueReadEventStatusCallback = false; this.isFromStartValueToEndValueReadEventCallback = false; this.isNotStartValueReadEventCallback = false; this.isValueReadChangedEventCallback = false; this.plcMonitorImp = new PlcMonitorImp(plc, loggerFactory); this.address = new DataAddress { Name = "Adddress", Type = DataAddressType.Int, Value = "E0_300", Offset = 0 }; plc.Initialize(); plc.Read <int>(address).Returns( new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 1 }, new int[] { 3 }, new int[] { 3 }, new int[] { 3 }, new int[] { 3 }, new int[] { 3 }); }
/// <summary> /// 创建Plc /// </summary> /// <param name="plcProtocolName">协议名称</param> /// <param name="tcpClientComPortConfigInfo">TcpClient端口配置信息</param> /// <param name="readTimeoutSeconds">读取超时</param> /// <param name="loggerFactory">日志工厂</param> /// <returns>Plc对象</returns> public static IPlc Create(PlcProtocolName plcProtocolName, TcpClientComPortConfigInfo tcpClientComPortConfigInfo, int readTimeoutSeconds = 3, ILoggerFactory loggerFactory = null) { IPlc result = null; IComPort comPort = new TcpClientComPort(tcpClientComPortConfigInfo, loggerFactory); if (plcProtocolName == PlcProtocolName.PlcOmronFinsTcp) { result = new PlcOmronFins(comPort, readTimeoutSeconds); } if (plcProtocolName == PlcProtocolName.PlcKeyenceUpperLink) { result = new PlcKeyenceUpperLink(comPort, readTimeoutSeconds); } if (plcProtocolName == PlcProtocolName.PlcMelsecMcBinary) { result = new PlcMelsecMcBinary(tcpClientComPortConfigInfo.RemoteIPAddress, (ushort)tcpClientComPortConfigInfo.RemotePort); } if (plcProtocolName == PlcProtocolName.PlcManualSimulator) { result = new PlcManualSimulator(); } return(result); }
internal EventWaitHandle SpawnVplc(PlcType plcType, WorkQueue plcEvents, string path) { this.PlcEvents = plcEvents; ManualResetEvent vplcIsReady = new ManualResetEvent(false); Thread thread = new Thread(() => { try { this.S7PLC = new ClientPlc(plcType); this.SubscribeToVplcEvents(); this.S7PLC.PowerOn(path); } catch (Exception ex) { if (this.S7PLC == null) { return; } this.S7PLC.PowerOff(); } finally { vplcIsReady.Set(); } }) { Name = "Vplc Startup" }; thread.SetApartmentState(ApartmentState.STA); thread.Start(); return(vplcIsReady); }
protected override Result Action() { Result re; try { //int Address = Convert.ToInt32(GetPropValue("地址")); string plcId = GetPropValue("PLC").ToString(); IPlc PLC = Hardware.Instance.plc(plcId); object value = GetPropValue("写入值"); re = (Result)typeof(IPlc).GetMethod("Write", new Type[] { typeof(int), value.GetType() }) .Invoke(PLC, new object[] { GetPropValue("地址"), value }); if (re.IsSuccess) { re.Message = plcId + " Write " + GetPropValue("写入类型").ToString() + " Address:" + GetPropValue("地址").ToString() + "; Value:" + Newtonsoft.Json.JsonConvert.SerializeObject(GetPropValue("写入值")); Log.Debug(re.Message); } else { Log.Run(LogLevel.Error, re.Message); } return(re); } catch (Exception e) { UiHelper.ShowError(e.Message); return(new Result(e.Message, (int)ErrorCode.fatalError)); } }
/// <summary> /// Validates the write result of the <paramref name="plcItems"/> by reading and comparing their <see cref="IPlcItem.Value"/> with the target value. /// </summary> /// <param name="plc"> The extended <see cref="IPlcItem"/> instance. </param> /// <param name="plcItems"> The <see cref="IPlcItem"/>s whose write result should be validated. </param> /// <param name="cancellationToken"> An optional <see cref="CancellationToken"/> for cancelling the write operation. </param> /// <returns> An awaitable <see cref="Task"/> yielding <c>True</c> on success, otherwise <c>False</c>. </returns> /// <exception cref="ReadOrWritePlcException"> Thrown if an exception occurred while writing or while validating. </exception> private static async Task <bool> ValidateWriteResultAsync(this IPlc plc, ICollection <IPlcItem> plcItems, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // Create clones of the items, for later comparison of the target against the actual value. var clonedItems = plcItems .Select ( plcItem => { var clonedItem = plcItem.Clone(); clonedItem.Value.SetAllBitsTo(false); return(clonedItem); } ) .ToArray() ; await plc.ReadItemsAsync(clonedItems, cancellationToken); var targetValues = plcItems.Select(plcItem => plcItem.Value); var actualValues = clonedItems.Select(clonedItem => clonedItem.Value); return(targetValues.SequenceEqual(actualValues)); }
public static void ReferenzenUebergeben(AutoTesterWindow autoTesterWindow, Datenstruktur datenstruktur, Stopwatch silkStopwatch, IPlc plc) { AutoTesterWindow = autoTesterWindow; Datenstruktur = datenstruktur; SilkStopwatch = silkStopwatch; Plc = plc; }
public VariableViewModel CreateVariable(IPlc plc) { return(plc switch { S7Plc s7plc => new S7VariableViewModel(s7plc), ModbusPlc modbusPlc => new ModbusVariableViewModel(modbusPlc), _ => throw new NotImplementedException() });
public void OneTimeSetUp() { plc = Substitute.For <IPlc>(); plcAdapter = new PlcAdapter() { Plc = plc }; }
static Globals() { Log = ChoreoLogger.GetLogging(); VM = new ViewModel(); Storage.LoadAll(); Plc = PlcFactory.New(); VM.Init(); }
/// <summary> /// Constructor /// </summary> /// <param name="plc"> The plc object that is used to forward all calls to the <see cref="IPlc"/> interface to. </param> /// <param name="plcItemMonitorConfigurations"> <see cref="PlcItemMonitorConfigurations"/> for specifying special polling frequencies for some <see cref="IPlcItem"/>s. </param> public PollingMonitorablePlc(IPlc plc, PlcItemMonitorConfigurations plcItemMonitorConfigurations) { // Save parameters. _decoratedPlc = plc; // Initialize fields. _plcMonitor = new PollingPlcMonitor(plc, plcItemMonitorConfigurations); }
public PlcMonitorWork(IPlc plc, ILoggerFactory loggerFactory) { this.Plc = plc; this.loggerFactory = loggerFactory; this.eventInfoes = new List <EventInfo <TValue> >(); this.tasks = new ConcurrentQueue <TaskInfo>(); this.tokenSource = new CancellationTokenSource(); }
static Globals() { Log = ChoreoLogger.GetLogging(); VM = new ViewModel(); Storage.LoadAll(); Plc = PlcFactory.New(); Plc.SymbolsUpdated += Plc_SymbolsUpdated; }
public TestAutomat(Datenstruktur datenstruktur, Action <Datenstruktur> cbPlcWindow, BeschriftungPlc.BeschriftungenPlc beschriftungenPlc, IPlc plc) { BeschriftungenPlc = beschriftungenPlc; _datenstruktur = datenstruktur; _callbackPlcWindow = cbPlcWindow; _plc = plc; PlotInitialisieren(); }
/// <summary> /// Constructor /// </summary> /// <param name="plc"> <see cref="IPlc"/> instance used to poll for changes in the monitored <see cref="IPlcItem"/>s. </param> /// <param name="plcItemMonitorConfigurations"> <see cref="PlcItemMonitorConfigurations"/> for specifying special polling frequencies for some <see cref="IPlcItem"/>s. </param> public PollingPlcMonitor(IPlc plc, PlcItemMonitorConfigurations plcItemMonitorConfigurations) { // Save parameters. _plc = plc; _plcItemMonitorConfigurations = plcItemMonitorConfigurations ?? new PlcItemMonitorConfigurations(); // Initialize fields. _lock = new object(); _plcItemHandlers = new Dictionary <int, PlcItemMonitorHandler>(); }
private static async Task <TReturn> ReadDataAndAcknowlodge <TReturn>(IPlc plc, Func <IPlc, Task <TReturn> > readData, string ackTriggerAddress) { try { return(await ReadData(plc, readData)); } finally { await plc.SetValue(ackTriggerAddress, true); } }
public static IDisposable GetTypedS7Notification(this IPlc plc, Type type, string address, AdsClient beckhoff, ISymbol symbol, TimeSpan notificationCycle, TimeSpan regularTransmissionCycle) { if (type == typeof(byte[])) { return(plc.CreateNotification <byte[]>(address, TransmissionMode.Cyclic, regularTransmissionCycle) .Do(value => Log.Logger.Debug($"Writing {address} to {symbol.InstancePath} {ByteToString(value)}")) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); } var typecode = Type.GetTypeCode(type); switch (typecode) { case TypeCode.Boolean: return(plc.CreateNotification <bool>(address, TransmissionMode.OnChange, notificationCycle) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Char: return(plc.CreateNotification <byte>(address, TransmissionMode.OnChange, notificationCycle) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); case TypeCode.Int16: case TypeCode.UInt16: return(plc.CreateNotification <short>(address, TransmissionMode.OnChange, notificationCycle) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); case TypeCode.Int32: case TypeCode.UInt32: return(plc.CreateNotification <int>(address, TransmissionMode.OnChange, notificationCycle) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); case TypeCode.Int64: case TypeCode.UInt64: return(plc.CreateNotification <long>(address, TransmissionMode.OnChange, notificationCycle) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); case TypeCode.Single: return(plc.CreateNotification <float>(address, TransmissionMode.OnChange, notificationCycle) .SelectMany(value => beckhoff.Write(symbol, value)) .Subscribe()); default: throw new ArgumentException($"Unsupported Type {type.Name}"); } }
private static async Task <Unit> Write <T>(this IPlc plc, string address, T value) { try { await plc.SetValue(address, value); } catch (Exception e) { Log.Logger.Error(e, $"Error while writing plc value {value} into {address}"); } return(Unit.Default); }
/// <summary> /// Writes the <paramref name="plcItems"/> to the plc in the order defined by the implementation of <paramref name="plcItems"/>. /// </summary> /// <param name="plc"> The extended <see cref="IPlcItem"/> instance. </param> /// <param name="plcItems"> The <see cref="IPlcItem"/>s to write. </param> /// <param name="continueOnError"> Flag if writing should commence even if one item fails. Default is false. </param> /// <param name="throwOnError"> Flag if an <see cref="WritePlcException"/> should be thrown if one or all items (depends on <paramref name="continueOnError"/>) fail. </param> /// <param name="cancellationToken"> An optional <see cref="CancellationToken"/> for cancelling the write operation. </param> /// <returns> An awaitable task yielding <c>True</c> on success, otherwise <c>False</c>. </returns> /// <exception cref="WritePlcException"> Thrown if an exception occurred while writing and <paramref name="throwOnError"/> is true. </exception> public static async Task <bool> WriteItemsInOrderAsync(this IPlc plc, ICollection <IPlcItem> plcItems, bool continueOnError = false, bool throwOnError = false, CancellationToken cancellationToken = default) { var validItems = new List <IPlcItem>(plcItems.Count); var failedItems = new List <(IPlcItem FailedItem, string ErrorMessage)>(); foreach (var plcItem in plcItems) { var success = true; try { success = await plc.WriteItemAsync(plcItem, cancellationToken); } catch (WritePlcException) { success = false; } if (success) { validItems.Add(plcItem); } else { failedItems.Add((plcItem, "Ordered writing failed because the write-result of this item returned false.")); if (continueOnError) { continue; } else if (throwOnError) { throw new WritePlcException(validItems, failedItems); } else { return(false); } } } if (!failedItems.Any()) { return(true); } else if (throwOnError) { throw new WritePlcException(validItems, failedItems); } else { return(false); } }
private static VariableViewModel MapFromStorage(IPlc plc, Variable variable) { return(variable switch { S7Variable s7var => new S7VariableViewModel((S7Plc)plc, variable.Name, s7var.Address, variable.TypeCode, variable.Length, MapFromStorage(variable.State)), ModbusVariable modbusVar => new ModbusVariableViewModel((ModbusPlc)plc, variable.Name, modbusVar.ObjectType, modbusVar.Address, variable.TypeCode, variable.Length, MapFromStorage(variable.State)), _ => throw new Exception("Unsupported variable type") });
/// <summary> /// Writes the <paramref name="plcItems"/> to the plc and afterwards reads and compares the written data for validation. /// </summary> /// <param name="plc"> The extended <see cref="IPlcItem"/> instance. </param> /// <param name="plcItems"> The <see cref="IPlcItem"/>s to write. </param> /// <param name="cancellationToken"> An optional <see cref="CancellationToken"/> for cancelling the write operation. </param> /// <returns> An awaitable task yielding <c>True</c> on success, otherwise <c>False</c>. </returns> /// <exception cref="ReadOrWritePlcException"> Thrown if an exception occurred while writing or while validating. </exception> public static async Task <bool> WriteItemsWithValidationAsync(this IPlc plc, ICollection <IPlcItem> plcItems, CancellationToken cancellationToken = default) { var success = await plc.WriteItemsAsync(plcItems, cancellationToken); // If the write failed somehow, then validation can be skipped even if it is requested. if (!success) { return(false); } // Validate the write result. return(await plc.ValidateWriteResultAsync(plcItems, cancellationToken)); }
public PlcBarcodeReader(string name, IPlc plc, DataAddress address, string regex = null) : base(name) { this.plc = plc; this.address = address; this.regex = new Regex(regex ?? string.Empty); this.connectionStateChangedEventManager = new ConnectionStateChangedEventManager(name); this.plc.ConnectionStateChanged += (s, e) => { connectionStateChangedEventManager.OnConnectionStateChanged(ConnectionStateChanged, s, e); }; }
private List <TaskInfo> ProduceTaskAction(IPlc plc, List <EventInfo <TValue> > eventInfoes) { var result = new List <TaskInfo>(); List <Tuple <DataAddress, TValue> > values = ScanAddress(plc, eventInfoes); eventInfoes.ForEach(eventInfo => { eventInfo.CurrentValue = values.Single(e => e.Item1.Equals((eventInfo.Event as EventBase).PlcAddress)).Item2; result.AddRange(ProduceTask(eventInfo)); }); return(result); }
public EmergencyStopMonitor(ScadaEngine engine, long updateTimeMsec = 2000) { this._engine = engine; _timer = new Timer(updateTimeMsec); _timer.Elapsed += Update; _plc = _engine.ClusterConfig.Plcs["MainPlc"] as IPlc; this.IsEnabled = false; if (_plc == null) { throw new ArgumentException("Could not retrieve a Plc from ClusterConfig"); } _allHardware = _engine.ClusterConfig.GetAllHardware(); }
private void PlcDaemonTask() { Ping pingBeckhoff = new Ping(); Ping pingSiemens = new Ping(); while (true) { switch (_status) { case PlcDaemonStatus.SpsPingen: try { var replyBeckhoff = pingBeckhoff.Send(_spsCx9020.IpAdresse); var replySiemens = pingBeckhoff.Send(_spsS7_1200.Adress); if (replyBeckhoff.Status == IPStatus.Success) { _status = PlcDaemonStatus.SpsBeckhoff; } if (replySiemens.Status == IPStatus.Success) { _status = PlcDaemonStatus.SpsSiemens; } } catch (Exception ex) { MessageBox.Show("Problem beim pingen:" + " --> " + ex); } break; case PlcDaemonStatus.SpsBeckhoff: Plc = new Cx9020(_spsCx9020, _datenstruktur, _callbackRangieren); _status = PlcDaemonStatus.SpsAktiv; break; case PlcDaemonStatus.SpsSiemens: Plc = new S71200(_spsS7_1200, _datenstruktur, _callbackRangieren); _status = PlcDaemonStatus.SpsAktiv; break; case PlcDaemonStatus.SpsAktiv: break; } Thread.Sleep(10); } // ReSharper disable once FunctionNeverReturns }
public List <BsonDocument> UpdateDatastreams(IPlc PLC, IDatabase Database) { List <BsonDocument> Temp = Database.GetCollection("Config", "DataStreams", PLC.ClientDetails["id"].ToString(), "ConnectionId"); Temp = Temp.Where(Doc => BsonResolver.Resolve(Doc["Active"])).Distinct().ToList(); List <string> Sets = Database.GetCollections("Data"); foreach (BsonDocument Stream in Temp) { if (!Sets.Contains(BsonResolver.Resolve(Stream["Collection"]))) { Database.CreateCollection(BsonResolver.Resolve(Stream["Collection"]) + "_" + BsonResolver.Resolve(Stream["id"]), "Data"); } } return(Temp); }
private List <Tuple <DataAddress, TValue> > ScanAddress(IPlc plc, List <EventInfo <TValue> > eventInfoes) { var result = new List <Tuple <DataAddress, TValue> >(); SortResult sortResult = InMemoryCache.GetOrAdd <SortResult>(eventInfoes.GetHashCode().ToString(), key => { var r = new SortResult(); var distinctPlcAddresses = eventInfoes.Select(e => (e.Event as EventBase).PlcAddress).Distinct(); r.AddressNotSegment.Addresses = distinctPlcAddresses.ToList(); if (!PlcMonitorImp.IsPlcManualSimulator) { r = PlcAddressSortHelper.Sort <TValue>(distinctPlcAddresses); } return(r); }); sortResult.AddressSegments.ForEach(addressSegment => { var startAddress = addressSegment.StartAddress; List <TValue> values; startAddress.Offset = addressSegment.AllAddressesByDes.Count - 1; values = plc.Read <TValue>(startAddress).ToList(); for (var index = 0; index < values.Count(); index++) { result.Add(new Tuple <DataAddress, TValue>(addressSegment.AllAddressesByDes[index], values[index])); } }); sortResult.AddressNotSegment.Addresses.ForEach(address => { var value = plc.ReadSingle <TValue>(address); result.Add(new Tuple <DataAddress, TValue>(address, value)); }); return(result); }
private void GetPLCsToConnect() { PLCConnections = Database.GetCollection("Config", "Connections", config.GatewayId, "Site"); Database.CreateCollection("Monitor", "RequestTime", 30000000); foreach (BsonDocument PLCDoc in PLCConnections) { IPlc PLC = PlcHandler.getClient(PLCDoc["PLCType"].ToString()); PLC.ClientDetails = PLCDoc; PLC.Connect(); Thread ClientThread = new Thread(() => { RunConnection(PLC, Database); }); ClientThread.Name = PLC.ClientDetails["Name"].ToString(); ClientThread.Start(); } }
private void RunConnection(IPlc PLC, IDatabase Database) { long ReqTime = 10; List <BsonDocument> Datastreams = UpdateDatastreams(PLC, Database); List <BsonDocument> Tempstreams = UpdateDatastreams(PLC, Database); Action <int, dynamic> Callback = new Action <int, dynamic>((Code, opts) => { switch (Code) { case 0: Datastreams = Tempstreams; break; case 1: Tempstreams = opts; break; default: break; } }); Thread ReadThread = new Thread(() => { ReadModule(ref Datastreams, ref ReqTime, Callback, PLC); }); ReadThread.Name = PLC.ClientDetails["Name"].ToString() + " - ReadThread"; Thread UpdateThread = new Thread(() => { UpdateModule(PLC, ref ReqTime, Callback); }); UpdateThread.Name = PLC.ClientDetails["Name"].ToString() + " - UpdateThread"; UpdateThread.Start(); ReadThread.Start(); }
public Loader(ClusterConfig config) : base(config) { _actionMap = new Dictionary<LoaderAction, Action> { { LoaderAction.LoadToConveyor, () => LoadToConveyorAsync() }, { LoaderAction.LoadToPalletiser, () => LoadToPalletiserAsync() } }; _loaderRobot = config.Robots[typeof(LoaderRobot)] as LoaderRobot; _traySensor = config.Plcs["MainPlc"] as IPlc; _traySwitchMap = CreateTraySwitchMap(); if (_loaderRobot == null) { throw new ArgumentException("Could not retrieve a LoaderRobot from ClusterConfig"); } if (_traySensor == null) { throw new ArgumentException("Could not retrieve a Plc from ClusterConfig"); } }
/// <summary> /// Constructor /// </summary> /// <param name="plc"> <see cref="IPlc"/> instance used to poll for changes in the monitored <see cref="IPlcItem"/>s. </param> /// <param name="plcItem"> The first <see cref="IPlcItem"/> to monitor. </param> /// <param name="pollingFrequency"> The frequency at which to poll for changes. </param> public PlcItemMonitorHandler(IPlc plc, IPlcItem plcItem, TimeSpan pollingFrequency) { // Save parameters. _plc = plc; _pollingFrequency = pollingFrequency; // Initialize fields. _lock = new object(); //_cancellationLock = new object(); // Create a placeholder plc item that is used to update the value. _placeholderItem = plcItem.Clone($"PLACEHOLDER_{plcItem.GetHashCode()}"); // Add the passed plc item as first one to the internal collection. _plcItems = new List <IPlcItem>() { plcItem }; // Start monitoring. this.Start(); }
public LogPlc(IPlc plc) { _plc = plc; }