/// <summary> /// Create a Subscription to watch data changes /// </summary> /// <returns></returns> public static Subscription CreateSubscription(this PlcDataMapper papper, ChangeDetectionStrategy changeDetectionStrategy = ChangeDetectionStrategy.Polling) { var sub = new Subscription(papper, changeDetectionStrategy); papper.AddSubscription(sub); return(sub); }
/// <summary> /// Return address data of the given variable /// </summary> /// <param name="mapping">name of the mapping</param> /// <param name="variable">name of the variable</param> /// <returns></returns> public static PlcItemAddress GetAddressOf(this PlcDataMapper papper, IPlcReference var) { if (papper.EntriesByName.TryGetValue(var.Mapping, out var entry)) { if (entry is Entry e) { e.UpdateInternalState(new List <string>() { var.Variable }); } if (entry.Variables.TryGetValue(var.Variable, out var varibleEntry)) { return(new PlcItemAddress( entry.PlcObject.Selector, varibleEntry.Item2.ElemenType, new PlcSize { Bytes = varibleEntry.Item1 + varibleEntry.Item2.ByteOffset, Bits = varibleEntry.Item2.BitOffset }, varibleEntry.Item2.Size )); } } ExceptionThrowHelper.ThrowInvalidVariableException($"{var.Mapping}.{var.Variable}"); return(default);
/// <summary> /// Open connection to plc /// </summary> private void OpenConnection() { using (var guard = new WriterGuard(_connectionLock)) { _client.Connect(_connectionString); //If papper was null or pdu size of the client is smaller then the last detected if (_client.IsConnected && (_papper == null || _papper.PduSize > _client.PduSize)) { var pduSize = _client.PduSize; using (var papperGuard = new WriterGuard(_papperLock)) { ClosePapperIfExits(); _papper = new PlcDataMapper(pduSize); _papper.OnRead += OnRead; _papper.OnWrite += OnWrite; foreach (var type in _rumtimeCompiler.GetTypes() .Where(type => type.GetTypeInfo() .GetCustomAttribute <MappingAttribute>() != null)) { _papper.AddMapping(type); } } } } }
private static void PerformDataChange(PlcDataMapper papper) { var mapping = "DB_Safety"; Console.WriteLine(); Console.WriteLine($"Start PerformDataChange"); Console.ForegroundColor = ConsoleColor.Red; var writeData = new Dictionary <string, object> { { "SafeMotion.Slots[15].SlotId", 3 }, { "SafeMotion.Slots[15].HmiId", 4 }, { "SafeMotion.Slots[15].Commands.TakeoverPermitted", !_toggle ? true : false }, }; _toggle = !_toggle; var are = new AutoResetEvent(false); void callback(object s, PlcNotificationEventArgs e) { foreach (var item in e) { Console.WriteLine($"DataChanged detected: {item.Address} = {item.Value}"); } are.Set(); } var items = writeData.Keys.Select(variable => PlcWatchReference.FromAddress($"{mapping}.{variable}", 100)).ToArray(); var subscription = papper.SubscribeDataChanges(callback, items); //waiting for initialize if (!are.WaitOne(10000)) { Console.WriteLine($"Error-> change!!!!!"); } foreach (var item in writeData) { Console.WriteLine($"Write:{item.Key} = {item.Value}"); } var result = papper.WriteAsync(PlcWriteReference.FromRoot("DB_Safety", writeData.ToArray()).ToArray()).GetAwaiter().GetResult(); //waiting for write update if (!are.WaitOne(10000)) { Console.WriteLine($"Error-> change!!!!!"); } //test if data change only occurred if data changed if (are.WaitOne(5000)) { Console.WriteLine($"Error-> no change!!!!!"); } subscription.Dispose(); Console.ResetColor(); Console.WriteLine($"Finished PerformDataChange"); }
public Entry(PlcDataMapper mapper, PlcObject plcObject, int readDataBlockSize, int validationTimeInMs) { _mapper = mapper ?? ExceptionThrowHelper.ThrowArgumentNullException <PlcDataMapper>(nameof(mapper)); PlcObject = plcObject ?? ExceptionThrowHelper.ThrowArgumentNullException <PlcObject>(nameof(plcObject)); ReadDataBlockSize = readDataBlockSize; ValidationTimeMs = validationTimeInMs; Variables = new Dictionary <string, Tuple <int, PlcObject> >(); Name = plcObject.Name; }
/// <summary> /// Subscribe to changes of variables /// </summary> /// <param name="mapper">Reference to plc data mapper</param> /// <param name="callback">Callback method</param> /// <param name="items">items to watch</param> /// <param name="changeDetectionStrategy">setup the strategy to detect changes. <see cref="ChangeDetectionStrategy"/>. This setting depends on the access library.</param> /// <returns></returns> public static Subscription SubscribeDataChanges(this PlcDataMapper mapper, OnChangeEventHandler callback, int interval, IEnumerable <PlcWatchReference> items, ChangeDetectionStrategy changeDetectionStrategy = ChangeDetectionStrategy.Polling) { var subscription = new Subscription(mapper, changeDetectionStrategy, items, interval); RunWatchTask(subscription, callback); return(subscription); }
private static void PerformReadFull(PlcDataMapper papper) { Console.WriteLine(); Console.ForegroundColor = ConsoleColor.DarkGreen; var result = papper.ReadAsync(PlcReadReference.FromAddress("DB_Safety.SafeMotion")).GetAwaiter().GetResult(); foreach (var item in result) { Console.WriteLine($"Red:{item.Address} = {item.Value}"); } Console.ResetColor(); }
/// <summary> /// If papper is existing, release the events and set it to null /// </summary> private void ClosePapperIfExits() { if (_papper != null) { using (var papperGuard = new WriterGuard(_papperLock)) { ClosePapperIfExits(); _papper.OnRead -= OnRead; _papper.OnWrite -= OnWrite; _papper = null; } } }
public static void Main(string[] args) { var papper = new PlcDataMapper(960, Papper_OnRead, Papper_OnWrite); papper.AddMapping(typeof(DB_Safety)); PerformReadFull(papper); PerformRead(papper); PerformWrite(papper); PerformRead(papper); PerformWrite(papper); PerformRead(papper); PerformDataChange(papper); PerformRawDataChange(papper); }
private static void PerformRead(PlcDataMapper papper) { Console.WriteLine(); Console.ForegroundColor = ConsoleColor.DarkGreen; var result = papper.ReadAsync(PlcReadReference.FromRoot("DB_Safety", "SafeMotion.Header.NumberOfActiveSlots", "SafeMotion.Header.Generated", "SafeMotion.Slots[42].SlotId", "SafeMotion.Slots[42].HmiId", "SafeMotion.Slots[42].Commands.TakeoverPermitted").ToArray()).GetAwaiter().GetResult();; foreach (var item in result) { Console.WriteLine($"Red:{item.Address} = {item.Value}"); } Console.ResetColor(); }
private static void PerformRawDataChange(PlcDataMapper papper) { Console.WriteLine(); Console.WriteLine($"Start PerformRawDataChange"); Console.ForegroundColor = ConsoleColor.Red; var writeData = new Dictionary <string, object> { { "W0", 3 }, { "X5_0", !_toggle ? true : false }, }; _toggle = !_toggle; var are = new AutoResetEvent(false); OnChangeEventHandler callback = (s, e) => { foreach (var item in e) { Console.WriteLine($"DataChanged detected:{item.Address} = {item.Value}"); } are.Set(); }; //papper.SubscribeRawDataChanges("DB15", callback); //papper.SetRawActiveState(true, "DB15", writeData.Keys.ToArray()); ////waiting for initialize //if (!are.WaitOne(10000)) // Console.WriteLine($"Error-> change!!!!!"); //foreach (var item in writeData) // Console.WriteLine($"Write:{item.Key} = {item.Value}"); //var result = papper.WriteAbs("DB15", writeData); ////waiting for write update //if (!are.WaitOne(10000)) // Console.WriteLine($"Error-> change!!!!!"); ////test if data change only occurred if data changed //if (are.WaitOne(5000)) // Console.WriteLine($"Error-> no change!!!!!"); //papper.SetRawActiveState(false, "DB15", writeData.Keys.ToArray()); //papper.Unsubscribe("DB15", callback); Console.ResetColor(); Console.WriteLine($"Finished PerformDataChange"); }
public void TestInvalidMappings() { var papper = new PlcDataMapper(960, Papper_OnRead, Papper_OnWrite, UpdateHandler, ReadMetaData, OptimizerType.Items); papper.AddMapping(typeof(DB_Safety)); using (var subscription = papper.CreateSubscription(ChangeDetectionStrategy.Event)) { Assert.True(subscription.TryAddItems(PlcWatchReference.FromAddress("DB_Safety.SafeMotion.Slots[0]", 100))); Assert.False(subscription.TryAddItems(PlcWatchReference.FromAddress("Test.XY", 100))); Assert.False(subscription.TryAddItems(PlcWatchReference.FromAddress("DB_Safety.XY", 100))); Assert.Throws <InvalidVariableException>(() => subscription.AddItems(PlcWatchReference.FromAddress("Test.XY", 100))); Assert.Throws <InvalidVariableException>(() => subscription.AddItems(PlcWatchReference.FromAddress("DB_Safety.XY", 100))); } }
/// <summary> /// Create an instance of a subscription to detect plc data changes /// </summary> /// <param name="mapper">The reference to the plcDatamapper.</param> /// <param name="vars">The variables we should watch.</param> /// <param name="defaultInterval">setup the default interval, if none was given by the <see cref="PlcWatchReference"/></param> public Subscription(PlcDataMapper mapper, ChangeDetectionStrategy changeDetectionStrategy = ChangeDetectionStrategy.Polling, IEnumerable <PlcWatchReference> vars = null, int defaultInterval = 1000) { _mapper = mapper ?? ExceptionThrowHelper.ThrowArgumentNullException <PlcDataMapper>(nameof(mapper)); _changeDetectionStrategy = changeDetectionStrategy; _defaultInterval = defaultInterval; _lock = new ReaderWriterLockSlim(); UpdateWatchCycle(vars); if (changeDetectionStrategy == ChangeDetectionStrategy.Event) { _changeEvent = new AsyncAutoResetEvent <IEnumerable <DataPack> >(); } if (vars != null) { AddItems(vars); } }
private void MainForm_Load(object sender, EventArgs e) { PlcDataMapper.InitializeData(); WireupForm(); CultureInfo CI = new CultureInfo(UserSettings.Default.Language); GetRes(CI); //Thread workerThread = new Thread(()=> GlobalConfig.testWorkerThread()); //workerThread.Start(); //OmronFINsPlcConnector dataConnector = new OmronFINsPlcConnector(PLCPort);//publisher //TestPrintResultService printService = new TestPrintResultService();//subscriber //suscribe events //dataConnector.PlcReadingCompleted += UpdateUIservice_read; //dataConnector.PlcWritingCompleted += UpdateUIservice_write; //start async operation //await dataConnector.PlcDataExchangeAllAsync(4000, cts.Token); //if (cts.IsCancellationRequested) // rtbOutput.Text += "Operation was cancelled"; //else // rtbOutput.Text += "ALL DONE!"; //progress.ProgressChanged += ReportProgress; //var result = await GlobalConfig.testWorkerThreadAsync(progress, cts.Token, 20); //PrintResult(result); //GlobalConfig.DataConnection.SetPort(PLCPort); //Progress<ProgressReportModel> progressDataExchange = new Progress<ProgressReportModel>(); //progressDataExchange.ProgressChanged += ReportProgress; //cts = new CancellationTokenSource(); //DataWorker dataWorker = new DataWorker(); //dataWorker.RunDataExchange(10, 3000, cts.Token, progressDataExchange); }
public async Task TestMultiWrite(string mapping, Type type) { _client = new Dacs7Client("192.168.0.148:102,0,2", PlcConnectionType.Basic, 5000); await _client.ConnectAsync(); if (_client.IsConnected && (_mapper == null || _mapper.PduSize > _client.PduSize)) { var pduSize = _client.PduSize; _mapper = new PlcDataMapper(pduSize, Papper_OnRead, Papper_OnWrite, OptimizerType.Items); _mapper.AddMapping(type); } var data = await _mapper.ReadAsync(PlcReadReference.FromAddress($"{mapping}.This")); await _mapper.WriteAsync(PlcWriteReference.FromAddress($"{mapping}.This", data)); await _client.DisconnectAsync(); }
private static void PerformWrite(PlcDataMapper papper) { Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Red; var writeData = new Dictionary <string, object> { { "SafeMotion.Header.NumberOfActiveSlots", 2 }, { "SafeMotion.Header.Generated", DateTime.Now }, { "SafeMotion.Slots[42].SlotId", 3 }, { "SafeMotion.Slots[42].HmiId", 4 }, { "SafeMotion.Slots[42].Commands.TakeoverPermitted", !_toggle ? true : false }, { "SafeMotion.Slots[250].SlotId", 1 }, { "SafeMotion.Slots[150].Handshake.MotionSelected", !_toggle ? true : false } }; _toggle = !_toggle; foreach (var item in writeData) { Console.WriteLine($"Write:{item.Key} = {item.Value}"); } var result = papper.WriteAsync(PlcWriteReference.FromRoot("DB_Safety", writeData.ToArray()).ToArray()); Console.ResetColor(); }
/// <summary> /// Read metadata of plc blocks /// </summary> /// <param name="mappings">mapping name specified in the MappingAttribute</param> /// <returns>The determined metadata.</returns> public static async Task <MetaDataResult[]> ReadMetaDataAsync(this PlcDataMapper papper, IEnumerable <string> mappings) { var results = new List <MetaDataPack>(); foreach (var mapping in mappings) { if (papper.EntriesByName.TryGetValue(mapping, out var entry)) { results.Add(new MetaDataPack { MappingName = entry.PlcObject.Name, AbsoluteName = entry.PlcObject.Selector }); } else { ExceptionThrowHelper.ThrowMappingNotFoundException(mapping); } } await papper.ReadBlockInfos(results); return(results.Select(x => new MetaDataResult(x.MetaData, x.ExecutionResult)).ToArray()); }
public static async Task <bool> WriteAsync <T1, T2>( this PlcDataMapper papper, (string path, T1 value) variable1,
/// <summary> /// Subscribe to changes of variables /// </summary> /// <param name="mapper">Reference to plc data mapper</param> /// <param name="callback">Callback method</param> /// <param name="items">items to watch</param> /// <param name="changeDetectionStrategy">setup the strategy to detect changes. <see cref="ChangeDetectionStrategy"/>. This setting depends on the access library.</param> /// <returns></returns> public static Subscription SubscribeDataChanges(this PlcDataMapper mapper, OnChangeEventHandler callback, IEnumerable <PlcWatchReference> items, ChangeDetectionStrategy changeDetectionStrategy = ChangeDetectionStrategy.Polling) => SubscribeDataChanges(mapper, callback, DefaultInterval, items as IEnumerable <PlcWatchReference>, changeDetectionStrategy);
/// <summary> /// Subscribe to changes of variables /// </summary> /// <param name="mapper">Reference to plc data mapper</param> /// <param name="callback">Callback method</param> /// <param name="items">items to watch</param> /// <returns></returns> public static Subscription SubscribeDataChanges(this PlcDataMapper mapper, OnChangeEventHandler callback, int interval, params PlcWatchReference[] items) => SubscribeDataChanges(mapper, callback, interval, items as IEnumerable <PlcWatchReference>);
/// <summary> /// Read metadata of plc blocks /// </summary> /// <param name="mappings">mapping name specified in the MappingAttribute</param> /// <returns>The determined metadata.</returns> public static Task <MetaDataResult[]> ReadMetaDataAsync(this PlcDataMapper papper, params string[] mappings) => papper.ReadMetaDataAsync(mappings as IEnumerable <string>);
public void PerformReadWriteRaw() { var papper = new PlcDataMapper(960, Papper_OnRead, Papper_OnWrite); var readResults = papper.ReadAsync(PlcReadReference.FromAddress("DB2000.W2")).GetAwaiter().GetResult(); var writeResults = papper.WriteAsync(PlcWriteReference.FromAddress("DB2000.W2", (UInt16)3)).GetAwaiter().GetResult(); }
public void TestExternalDataChange() { var papper = new PlcDataMapper(960, Papper_OnRead, Papper_OnWrite, UpdateHandler, ReadMetaData, OptimizerType.Items); papper.AddMapping(typeof(DB_Safety)); MockPlc.OnItemChanged = (items) => { papper.OnDataChanges(items.Select(i => new DataPack { Selector = i.Selector, Offset = i.Offset, Length = i.Length, BitMask = i.BitMask, ExecutionResult = ExecutionResult.Ok }.ApplyData(i.Data))); }; var sleepTime = 10000; var mapping = "DB_Safety"; var intiState = true; var originData = new Dictionary <string, object> { { "SafeMotion.Slots[16].SlotId", (byte)0 }, { "SafeMotion.Slots[16].HmiId", (UInt32)0 }, { "SafeMotion.Slots[16].Commands.TakeoverPermitted", false }, }; var writeData = new Dictionary <string, object> { { "SafeMotion.Slots[16].SlotId", (byte)3 }, { "SafeMotion.Slots[16].HmiId", (UInt32)4 }, { "SafeMotion.Slots[16].Commands.TakeoverPermitted", false }, }; var are = new AutoResetEvent(false); // write initial state papper.WriteAsync(PlcWriteReference.FromRoot(mapping, originData.ToArray()).ToArray()).GetAwaiter().GetResult(); using (var subscription = papper.CreateSubscription(ChangeDetectionStrategy.Event)) { subscription.AddItems(originData.Keys.Select(variable => PlcWatchReference.FromAddress($"{mapping}.{variable}", 100))); var t = Task.Run(async() => { try { while (!subscription.Watching.IsCompleted) { var res = await subscription.DetectChangesAsync(); if (!res.IsCompleted && !res.IsCanceled) { _output.WriteLine($"Changed: initial state is {intiState}"); if (!intiState) { Assert.Equal(2, res.Results.Count()); } else { Assert.Equal(3, res.Results.Count()); } foreach (var item in res.Results) { try { _output.WriteLine($"Changed: {item.Variable} = {item.Value}"); if (!intiState) { Assert.Equal(writeData[item.Variable], item.Value); } else { Assert.Equal(originData[item.Variable], item.Value); } } catch (Exception) { } } are.Set(); } } } catch (Exception) { } }); //waiting for initialize Assert.True(are.WaitOne(sleepTime), "waiting for initialize"); intiState = false; var writeResults = papper.WriteAsync(PlcWriteReference.FromRoot(mapping, writeData.ToArray()).ToArray()).GetAwaiter().GetResult(); foreach (var item in writeResults) { Assert.Equal(ExecutionResult.Ok, item.ActionResult); } //waiting for write update Assert.True(are.WaitOne(sleepTime), "waiting for write update"); //test if data change only occurred if data changed Assert.False(are.WaitOne(sleepTime), $"test if data change only occurred if data changed"); } }
public MappingEntry(PlcDataMapper mapper, MappingAttribute mapping, Type type, PlcMetaDataTree tree, int readDataBlockSize, int validationTimeInMs) : base(mapper, PlcObjectResolver.GetMapping(mapping?.Name, tree, type), readDataBlockSize, validationTimeInMs) { Mapping = mapping ?? ExceptionThrowHelper.ThrowArgumentNullException <MappingAttribute>(nameof(mapping)); Type = type ?? ExceptionThrowHelper.ThrowArgumentNullException <Type>(nameof(type)); }
public RawEntry(PlcDataMapper mapper, string from, int readDataBlockSize, int validationTimeInMs) : base(mapper, new PlcObjectRef(from, null) { Selector = @from }, readDataBlockSize, validationTimeInMs) { }
private void ExportAddress_Click(object sender, EventArgs e) { PlcDataMapper.ExportDataAddresses(); }
public async static Task <bool> WhenAsync <T1>(this PlcDataMapper papper, (PlcReadReference reference, Func <T1, bool> cmp) variable1,