diff --git a/.vscode/launch.json b/.vscode/launch.json index b1375dd..aef7cc0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -24,5 +24,5 @@ "request": "attach", "processId": "${command:pickProcess}" } - ,] + ] } \ No newline at end of file diff --git a/README.md b/README.md index 62cffe6..f72d4fb 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Be careful! ## General -The client is wapper of [LibTagPLC](https://github.com/kyle-github/libplctag) library. +The client is wrapper of [LibTagPLC](https://github.com/kyle-github/libplctag) library. ## Main features @@ -47,7 +47,7 @@ The client is wapper of [LibTagPLC](https://github.com/kyle-github/libplctag) li - Controller implementation - Native Tag type INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32, FLOAT64, STRING - Custom class definition structure -- Manupulation local value variable +- Manipulation local value variable - Read and Write with advanced result - Time execution - Status code @@ -58,11 +58,12 @@ The client is wapper of [LibTagPLC](https://github.com/kyle-github/libplctag) li - Decode Error **StatusCodeOperation.DecodeError()** - Group interval read/write - Event result Tag and TagGroup with result changed value -- Enable "Fail Operation Raise Exception" -- Value Manager directry modify +- Enable "Fail Operation Raise Exception" (default: false) +- Value Manager directly modify - Bit manipulation - Debug level - Auto Read/Write when using value (default: false) +- Native support 32/64 bit for Windows/Linux ## Usage @@ -139,7 +140,7 @@ Are possible to create any tag: - CreateTagString - CreateTagFloat32 - CreateTagFloat64 -- CreateTagType specify type and name only, and automatcly calculated size from property or array +- CreateTagType specify type and name only, and automatically calculated size from property or array - CreateTagType specify name,size,length for array - CreateTagArray diff --git a/src/Corsinvest.AllenBradley.PLC.Api/.gitignore b/src/Corsinvest.AllenBradley.PLC.Api/.gitignore index d86ba9f..4c54512 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/.gitignore +++ b/src/Corsinvest.AllenBradley.PLC.Api/.gitignore @@ -1,2 +1,352 @@ -obj/ -bin/ \ No newline at end of file +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ \ No newline at end of file diff --git a/src/Corsinvest.AllenBradley.PLC.Api/Controller.cs b/src/Corsinvest.AllenBradley.PLC.Api/Controller.cs index ab80b3e..fd667a9 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/Controller.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/Controller.cs @@ -10,7 +10,7 @@ namespace Corsinvest.AllenBradley.PLC.Api /// public class Controller : IDisposable { - private List _tagGroups = new List(); + private readonly List _tagGroups = new List(); private bool _disposed; @@ -27,7 +27,7 @@ public Controller(string ipAddress, string path, CPUType cpuType) { if (cpuType == CPUType.LGX && string.IsNullOrEmpty(path)) { - throw new ArgumentException("PortType and Slot must be specified for Controllogix / Compactlogix processors"); + throw new ArgumentException("PortType and Slot must be specified for ControlLogix / CompactLogix processors"); } IPAddress = ipAddress; @@ -114,12 +114,12 @@ public bool Ping(bool echo = false) var reply = ping.Send(IPAddress); if (echo) { - Console.WriteLine($"Address: {reply.Address}"); - Console.WriteLine($"RoundTrip time: {reply.RoundtripTime}"); - Console.WriteLine($"Time to live: {reply.Options?.Ttl}"); - Console.WriteLine($"Don't fragment: {reply.Options?.DontFragment}"); - Console.WriteLine($"Buffer size: {reply.Buffer?.Length}"); - Console.WriteLine($"Status: {reply.Status}"); + Console.Out.WriteLine($"Address: {reply.Address}"); + Console.Out.WriteLine($"RoundTrip time: {reply.RoundtripTime}"); + Console.Out.WriteLine($"Time to live: {reply.Options?.Ttl}"); + Console.Out.WriteLine($"Don't fragment: {reply.Options?.DontFragment}"); + Console.Out.WriteLine($"Buffer size: {reply.Buffer?.Length}"); + Console.Out.WriteLine($"Status: {reply.Status}"); } return reply.Status == IPStatus.Success; diff --git a/src/Corsinvest.AllenBradley.PLC.Api/Corsinvest.AllenBradley.PLC.Api.csproj b/src/Corsinvest.AllenBradley.PLC.Api/Corsinvest.AllenBradley.PLC.Api.csproj index a18bcf7..c0d203c 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/Corsinvest.AllenBradley.PLC.Api.csproj +++ b/src/Corsinvest.AllenBradley.PLC.Api/Corsinvest.AllenBradley.PLC.Api.csproj @@ -2,7 +2,7 @@ netstandard2.0 true - 0.1.6 + 0.1.7 Corsinvest Srl Daniele Corsini Corsinvest Srl @@ -12,12 +12,23 @@ GPL-3.0-or-later https://github.com/Corsinvest/cv4ab-api-dotnet Rockwell;Allen-Bradley;Api,PLC;Corsinvest;LibTagPlc - https://www.corsinvest.it/wp-content/uploads/2016/08/Corsinvest.ico - + icon.png + New support 32/64 bit + true - - + + True + + + + + + + + + - \ No newline at end of file + + diff --git a/src/Corsinvest.AllenBradley.PLC.Api/ITags.cs b/src/Corsinvest.AllenBradley.PLC.Api/ITags.cs index 1dd6b7e..a2d8cce 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/ITags.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/ITags.cs @@ -23,7 +23,7 @@ public interface ITag : IDisposable /// Handle creation Tag /// /// - int Handle { get; } + Int32 Handle { get; } /// /// Controller reference. @@ -85,7 +85,7 @@ public interface ITag : IDisposable TagValueManager ValueManager { get; } /// - /// Peforms read of Tag + /// Performs read of Tag /// /// ResultOperation Read(); diff --git a/src/Corsinvest.AllenBradley.PLC.Api/NativeMethod.cs b/src/Corsinvest.AllenBradley.PLC.Api/NativeLibrary.cs similarity index 58% rename from src/Corsinvest.AllenBradley.PLC.Api/NativeMethod.cs rename to src/Corsinvest.AllenBradley.PLC.Api/NativeLibrary.cs index 6bab60b..58c3590 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/NativeMethod.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/NativeLibrary.cs @@ -3,98 +3,100 @@ namespace Corsinvest.AllenBradley.PLC.Api { - internal static class NativeMethod + internal static class NativeLibrary { - private const string DLL_NAME = "plctag"; + const string DLL_NAME = "plctag"; [DllImport(DLL_NAME, EntryPoint = "plc_tag_create", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_create([MarshalAs(UnmanagedType.LPStr)] string lpString, int timeout); + public static extern Int32 plc_tag_create([MarshalAs(UnmanagedType.LPStr)] string lpString, int timeout); [DllImport(DLL_NAME, EntryPoint = "plc_tag_destroy", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_destroy(int tagId); - - [DllImport(DLL_NAME, EntryPoint = "plc_tag_abort", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_abort(int tagId); + public static extern int plc_tag_destroy(Int32 tag); [DllImport(DLL_NAME, EntryPoint = "plc_tag_status", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_status(int tagId); - - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_size", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_get_size(int tagId); + public static extern int plc_tag_status(Int32 tag); [DllImport(DLL_NAME, EntryPoint = "plc_tag_decode_error", CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr plc_tag_decode_error(int error); - - [DllImport(DLL_NAME, EntryPoint = "plc_tag_read", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_read(int tagId, int timeout); + public static extern IntPtr plc_tag_decode_error(int error); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_write", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_write(int tagId, int timeout); + public static string DecodeError(int code) { return Marshal.PtrToStringAnsi(NativeLibrary.plc_tag_decode_error(code)); } - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint16", CallingConvention = CallingConvention.Cdecl)] - internal static extern ushort plc_tag_get_uint16(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_lock", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_lock(int tagId); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int16", CallingConvention = CallingConvention.Cdecl)] - internal static extern short plc_tag_get_int16(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_unlock", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_unlock(int tagId); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint16", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_uint16(int tagId, int offset, ushort val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_read", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_read(Int32 tag, int timeout); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int16", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_int16(int tagId, int offset, short val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_write", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_write(Int32 tag, int timeout); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint8", CallingConvention = CallingConvention.Cdecl)] - internal static extern byte plc_tag_get_uint8(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_size", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_get_size(Int32 tag); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int8", CallingConvention = CallingConvention.Cdecl)] - internal static extern sbyte plc_tag_get_int8(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_abort", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_abort(Int32 tag); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint8", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_uint8(int tagId, int offset, byte val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint64", CallingConvention = CallingConvention.Cdecl)] + public static extern UInt64 plc_tag_get_uint64(Int32 tag, int offset); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int8", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_int8(int tagId, int offset, sbyte val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int64", CallingConvention = CallingConvention.Cdecl)] + public static extern Int64 plc_tag_get_int64(Int32 tag, int offset); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_float32", CallingConvention = CallingConvention.Cdecl)] - internal static extern float plc_tag_get_float32(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint64", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_uint64(Int32 tag, int offset, UInt64 val); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_float32", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_float32(int tagId, int offset, float val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int64", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_int64(Int32 tag, int offset, Int64 val); [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_float64", CallingConvention = CallingConvention.Cdecl)] - internal static extern double plc_tag_get_float64(int tagId, int offset); + public static extern double plc_tag_get_float64(Int32 tag, int offset); [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_float64", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_float64(int tagId, int offset, double val); + public static extern int plc_tag_set_float64(Int32 tag, int offset, double val); [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint32", CallingConvention = CallingConvention.Cdecl)] - internal static extern uint plc_tag_get_uint32(int tagId, int offset); + public static extern UInt32 plc_tag_get_uint32(Int32 tag, int offset); [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int32", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_get_int32(int tagId, int offset); + public static extern Int32 plc_tag_get_int32(Int32 tag, int offset); [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint32", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_uint32(int tagId, int offset, uint val); + public static extern int plc_tag_set_uint32(Int32 tag, int offset, UInt32 val); [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int32", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_int32(int tagId, int offset, int val); + public static extern int plc_tag_set_int32(Int32 tag, int offset, Int32 val); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint64", CallingConvention = CallingConvention.Cdecl)] - internal static extern ulong plc_tag_get_uint64(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_float32", CallingConvention = CallingConvention.Cdecl)] + public static extern float plc_tag_get_float32(Int32 tag, int offset); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int64", CallingConvention = CallingConvention.Cdecl)] - internal static extern long plc_tag_get_int64(int tagId, int offset); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_float32", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_float32(Int32 tag, int offset, float val); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint64", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_uint64(int tagId, int offset, ulong val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint16", CallingConvention = CallingConvention.Cdecl)] + public static extern UInt16 plc_tag_get_uint16(Int32 tag, int offset); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int64", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_set_int64(int tagId, int offset, long val); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int16", CallingConvention = CallingConvention.Cdecl)] + public static extern Int16 plc_tag_get_int16(Int32 tag, int offset); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_lock", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_lock(int tagId); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint16", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_uint16(Int32 tag, int offset, UInt16 val); - [DllImport(DLL_NAME, EntryPoint = "plc_tag_unlock", CallingConvention = CallingConvention.Cdecl)] - internal static extern int plc_tag_unlock(int tagId); + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int16", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_int16(Int32 tag, int offset, Int16 val); + + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_uint8", CallingConvention = CallingConvention.Cdecl)] + public static extern byte plc_tag_get_uint8(Int32 tag, int offset); + + [DllImport(DLL_NAME, EntryPoint = "plc_tag_get_int8", CallingConvention = CallingConvention.Cdecl)] + public static extern sbyte plc_tag_get_int8(Int32 tag, int offset); + + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_uint8", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_uint8(Int32 tag, int offset, byte val); + + [DllImport(DLL_NAME, EntryPoint = "plc_tag_set_int8", CallingConvention = CallingConvention.Cdecl)] + public static extern int plc_tag_set_int8(Int32 tag, int offset, sbyte val); } } \ No newline at end of file diff --git a/src/Corsinvest.AllenBradley.PLC.Api/ResultOperation.cs b/src/Corsinvest.AllenBradley.PLC.Api/ResultOperation.cs index 4d734a6..6e92bde 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/ResultOperation.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/ResultOperation.cs @@ -43,7 +43,7 @@ internal ResultOperation(ITag tag, DateTime timestamp, long executionTime, int s public int StatusCode { get; } /// - /// Reduce multimple result to one. + /// Reduce multiple result to one. /// /// /// diff --git a/src/Corsinvest.AllenBradley.PLC.Api/StatusCodeOperation.cs b/src/Corsinvest.AllenBradley.PLC.Api/StatusCodeOperation.cs index 070fcc6..a25c1da 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/StatusCodeOperation.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/StatusCodeOperation.cs @@ -1,6 +1,4 @@ -using System.Runtime.InteropServices; - -namespace Corsinvest.AllenBradley.PLC.Api +namespace Corsinvest.AllenBradley.PLC.Api { /// /// Status code operation. @@ -224,6 +222,6 @@ public static class StatusCodeOperation /// /// Error code /// - public static string DecodeError(int code) { return Marshal.PtrToStringAnsi(NativeMethod.plc_tag_decode_error(code)); } + public static string DecodeError(int code) { return NativeLibrary.DecodeError(code); } } } \ No newline at end of file diff --git a/src/Corsinvest.AllenBradley.PLC.Api/Tag.cs b/src/Corsinvest.AllenBradley.PLC.Api/Tag.cs index 265bf68..b6f629b 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/Tag.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/Tag.cs @@ -44,7 +44,7 @@ internal Tag(Controller controller, string name, int size, int length = 1) if (controller.DebugLevel > 0) { url += $"&debug={controller.DebugLevel}"; } //create reference - Handle = NativeMethod.plc_tag_create(url, controller.Timeout); + Handle = NativeLibrary.plc_tag_create(url, controller.Timeout); Value = TagHelper.CreateObject(Length); } @@ -53,7 +53,7 @@ internal Tag(Controller controller, string name, int size, int length = 1) /// Handle creation Tag /// /// - public int Handle { get; } + public Int32 Handle { get; } /// /// Controller reference. @@ -111,7 +111,7 @@ public TType Value get { if (Controller.AutoReadValue) { Read(); } - return (TType)ValueManager.Get(_value, 0); + return (TType)ValueManager.Get(_value, 0); } set @@ -163,7 +163,7 @@ public bool IsChangedValue } /// - /// Peforms read of Tag + /// Performs read of Tag /// /// public ResultOperation Read() @@ -173,7 +173,7 @@ public ResultOperation Read() var timestamp = DateTime.Now; var watch = Stopwatch.StartNew(); - var statusCode = NativeMethod.plc_tag_read(Handle, Controller.Timeout); + var statusCode = NativeLibrary.plc_tag_read(Handle, Controller.Timeout); watch.Stop(); IsRead = true; @@ -220,7 +220,7 @@ private static T DeepClone(T obj) } /// - /// Peforms write of Tag + /// Performs write of Tag /// /// public ResultOperation Write() @@ -229,7 +229,7 @@ public ResultOperation Write() var timestamp = DateTime.Now; var watch = Stopwatch.StartNew(); - var statusCode = NativeMethod.plc_tag_write(Handle, Controller.Timeout); + var statusCode = NativeLibrary.plc_tag_write(Handle, Controller.Timeout); watch.Stop(); IsWrite = true; @@ -248,38 +248,38 @@ public ResultOperation Write() /// Abort any outstanding IO to the PLC. /// /// - public int Abort() { return NativeMethod.plc_tag_abort(Handle); } + public int Abort() { return NativeLibrary.plc_tag_abort(Handle); } /// /// Get size tag read from PLC. /// /// - public int GetSize() { return NativeMethod.plc_tag_get_size(Handle); } + public int GetSize() { return NativeLibrary.plc_tag_get_size(Handle); } /// /// Get status operation. /// /// - public int GetStatus() { return NativeMethod.plc_tag_status(Handle); } + public int GetStatus() { return NativeLibrary.plc_tag_status(Handle); } /// /// Lock for multitrading. /// /// - public int Lock() { return NativeMethod.plc_tag_lock(Handle); } + public int Lock() { return NativeLibrary.plc_tag_lock(Handle); } /// /// Unlock for multitrading /// /// - public int Unlock() { return NativeMethod.plc_tag_unlock(Handle); } + public int Unlock() { return NativeLibrary.plc_tag_unlock(Handle); } #region IDisposable Support void Dispose(bool disposing) { if (!_disposed) { - if (disposing) { NativeMethod.plc_tag_destroy(Handle); } + if (disposing) { NativeLibrary.plc_tag_destroy(Handle); } _disposed = true; } } diff --git a/src/Corsinvest.AllenBradley.PLC.Api/TagGroup.cs b/src/Corsinvest.AllenBradley.PLC.Api/TagGroup.cs index 7bb6567..59a3623 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/TagGroup.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/TagGroup.cs @@ -12,8 +12,8 @@ namespace Corsinvest.AllenBradley.PLC.Api public class TagGroup : IDisposable { private bool _disposed; - private Timer _timer; - private List _tags = new List(); + private readonly Timer _timer; + private readonly List _tags = new List(); private object _lockScan = new object(); /// @@ -78,7 +78,7 @@ public void RemoveTag(ITag tag) /// The textual name of the tag to access. The name is anything allowed by the protocol. /// E.g. myDataStruct.rotationTimer.ACC, myDINTArray[42] etc. /// - public Tag CreateTagInt64(string name) { return CreateTagType(name); } + public Tag CreateTagInt64(string name) { return CreateTagType(name); } /// /// Create Tag UInt64 @@ -86,7 +86,7 @@ public void RemoveTag(ITag tag) /// The textual name of the tag to access. The name is anything allowed by the protocol. /// E.g. myDataStruct.rotationTimer.ACC, myDINTArray[42] etc. /// - public Tag CreateTagUInt64(string name) { return CreateTagType(name); } + public Tag CreateTagUInt64(string name) { return CreateTagType(name); } /// /// Create Tag Int32 diff --git a/src/Corsinvest.AllenBradley.PLC.Api/TagOperationException.cs b/src/Corsinvest.AllenBradley.PLC.Api/TagOperationException.cs index c1fd4ae..099bb2a 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/TagOperationException.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/TagOperationException.cs @@ -9,11 +9,11 @@ namespace Corsinvest.AllenBradley.PLC.Api public class TagOperationException : Exception { /// - /// Costrucor + /// Constructor /// /// /// - public TagOperationException(ResultOperation result) : base("Error execut operation!") + public TagOperationException(ResultOperation result) : base("Error execute operation!") { Result = result; } diff --git a/src/Corsinvest.AllenBradley.PLC.Api/TagSize.cs b/src/Corsinvest.AllenBradley.PLC.Api/TagSize.cs index 07552d0..10113f6 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/TagSize.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/TagSize.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; namespace Corsinvest.AllenBradley.PLC.Api { @@ -71,17 +70,17 @@ public static class TagSize /// public static IReadOnlyDictionary NativeTypes { get; } = new Dictionary { - { typeof(long), INT64 }, - { typeof(ulong), UINT64 }, - { typeof(int), INT32 }, - { typeof(uint), UINT32 }, - { typeof(short), INT16 }, - { typeof(ushort), UINT16 }, + { typeof(Int64), INT64 }, + { typeof(UInt64), UINT64 }, + { typeof(Int32), INT32 }, + { typeof(UInt32), UINT32 }, + { typeof(Int16), INT16 }, + { typeof(UInt16), UINT16 }, { typeof(sbyte), INT8 }, { typeof(byte), UINT8 }, - { typeof(string), STRING }, { typeof(float), FLOAT32 }, { typeof(double), FLOAT64 }, + { typeof(string), STRING }, }; /// diff --git a/src/Corsinvest.AllenBradley.PLC.Api/TagValueManager.cs b/src/Corsinvest.AllenBradley.PLC.Api/TagValueManager.cs index e8f5dcb..c146e97 100644 --- a/src/Corsinvest.AllenBradley.PLC.Api/TagValueManager.cs +++ b/src/Corsinvest.AllenBradley.PLC.Api/TagValueManager.cs @@ -1,8 +1,6 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Text; namespace Corsinvest.AllenBradley.PLC.Api @@ -12,14 +10,14 @@ namespace Corsinvest.AllenBradley.PLC.Api /// public class TagValueManager { - private ITag _tag; + private readonly ITag _tag; /// /// Byte Length string in header /// private const byte BYTE_HEADER_LENGTH_STRING = 4; - const byte MAX_LENGT_STRING = 82; + const byte MAX_LENGTH_STRING = 82; internal TagValueManager(ITag tag) { _tag = tag; } @@ -45,19 +43,19 @@ internal object Get(object obj, int offset = 0) } else { - if (type == typeof(long)) { return GetInt64(offset); } - else if (type == typeof(ulong)) { return GetUInt64(offset); } - else if (type == typeof(int)) { return GetInt32(offset); } - else if (type == typeof(uint)) { return GetUInt32(offset); } - else if (type == typeof(short)) { return GetInt16(offset); } - else if (type == typeof(ushort)) { return GetUInt16(offset); } + if (type == typeof(Int64)) { return GetInt64(offset); } + else if (type == typeof(UInt64)) { return GetUInt64(offset); } + else if (type == typeof(Int32)) { return GetInt32(offset); } + else if (type == typeof(UInt32)) { return GetUInt32(offset); } + else if (type == typeof(Int16)) { return GetInt16(offset); } + else if (type == typeof(UInt16)) { return GetUInt16(offset); } else if (type == typeof(sbyte)) { return GetInt8(offset); } else if (type == typeof(byte)) { return GetUInt8(offset); } else if (type == typeof(float)) { return GetFloat32(offset); } else if (type == typeof(double)) { return GetFloat64(offset); } else if (type == typeof(string)) { return GetString(offset); } else if (type.IsClass && !type.IsAbstract) { return GetType(obj, offset); } - else { throw new Exception("Error data type!"); } + else { throw new ArgumentException("Error data type!"); } } } @@ -79,19 +77,19 @@ internal void Set(object value, int offset = 0) } else { - if (type == typeof(long)) { SetInt64((long)value, offset); } - else if (type == typeof(ulong)) { SetUInt64((ulong)value, offset); } - else if (type == typeof(int)) { SetInt32((int)value, offset); } - else if (type == typeof(uint)) { SetUInt32((uint)value, offset); } - else if (type == typeof(short)) { SetInt16((short)value, offset); } - else if (type == typeof(ushort)) { SetUInt16((ushort)value, offset); } + if (type == typeof(Int64)) { SetInt64((Int64)value, offset); } + else if (type == typeof(UInt64)) { SetUInt64((UInt64)value, offset); } + else if (type == typeof(Int32)) { SetInt32((int)value, offset); } + else if (type == typeof(UInt32)) { SetUInt32((uint)value, offset); } + else if (type == typeof(Int16)) { SetInt16((short)value, offset); } + else if (type == typeof(UInt16)) { SetUInt16((ushort)value, offset); } else if (type == typeof(sbyte)) { SetInt8((sbyte)value, offset); } else if (type == typeof(byte)) { SetUInt8((byte)value, offset); } - else if (type == typeof(string)) { SetString((string)value, offset); } else if (type == typeof(float)) { SetFloat32((float)value, offset); } else if (type == typeof(double)) { SetFloat64((float)value, offset); } + else if (type == typeof(string)) { SetString((string)value, offset); } else if (type.IsClass && !type.IsAbstract) { SetType(value, offset); } - else { throw new Exception("Error data type!"); } + else { throw new ArgumentException("Error data type!"); } } } @@ -100,98 +98,98 @@ internal void Set(object value, int offset = 0) /// /// /// - public ushort GetUInt16(int offset = 0) { return NativeMethod.plc_tag_get_uint16(_tag.Handle, offset); } + public UInt16 GetUInt16(int offset = 0) { return NativeLibrary.plc_tag_get_uint16(_tag.Handle, offset); } /// /// Set local value UInt16 /// /// /// - public void SetUInt16(ushort value, int offset = 0) { NativeMethod.plc_tag_set_uint16(_tag.Handle, offset, value); } + public void SetUInt16(UInt16 value, int offset = 0) { NativeLibrary.plc_tag_set_uint16(_tag.Handle, offset, value); } /// /// Get local value Int16 /// /// /// - public short GetInt16(int offset = 0) { return NativeMethod.plc_tag_get_int16(_tag.Handle, offset); } + public Int16 GetInt16(int offset = 0) { return NativeLibrary.plc_tag_get_int16(_tag.Handle, offset); } /// /// Set local value Int16 /// /// /// - public void SetInt16(short value, int offset = 0) { NativeMethod.plc_tag_set_int16(_tag.Handle, offset, value); } + public void SetInt16(Int16 value, int offset = 0) { NativeLibrary.plc_tag_set_int16(_tag.Handle, offset, value); } /// /// Get local value UInt8 /// /// /// - public byte GetUInt8(int offset = 0) { return NativeMethod.plc_tag_get_uint8(_tag.Handle, offset); } + public byte GetUInt8(int offset = 0) { return NativeLibrary.plc_tag_get_uint8(_tag.Handle, offset); } /// /// Set local value UInt8 /// /// /// - public void SetUInt8(byte value, int offset = 0) { NativeMethod.plc_tag_set_uint8(_tag.Handle, offset, value); } + public void SetUInt8(byte value, int offset = 0) { NativeLibrary.plc_tag_set_uint8(_tag.Handle, offset, value); } /// /// Get local value Int8 /// /// /// - public sbyte GetInt8(int offset = 0) { return NativeMethod.plc_tag_get_int8(_tag.Handle, offset); } + public sbyte GetInt8(int offset = 0) { return NativeLibrary.plc_tag_get_int8(_tag.Handle, offset); } /// /// Set local value Int8 /// /// /// - public void SetInt8(sbyte value, int offset = 0) { NativeMethod.plc_tag_set_int8(_tag.Handle, offset, value); } + public void SetInt8(sbyte value, int offset = 0) { NativeLibrary.plc_tag_set_int8(_tag.Handle, offset, value); } /// /// Get local value UInt32 /// /// /// - public uint GetUInt32(int offset = 0) { return NativeMethod.plc_tag_get_uint32(_tag.Handle, offset); } + public UInt32 GetUInt32(int offset = 0) { return NativeLibrary.plc_tag_get_uint32(_tag.Handle, offset); } /// /// Set local value UInt32 /// /// /// - public void SetUInt32(uint value, int offset = 0) { NativeMethod.plc_tag_set_uint32(_tag.Handle, offset, value); } + public void SetUInt32(UInt32 value, int offset = 0) { NativeLibrary.plc_tag_set_uint32(_tag.Handle, offset, value); } /// /// Get local value Int32 /// /// /// - public int GetInt32(int offset = 0) { return NativeMethod.plc_tag_get_int32(_tag.Handle, offset); } - + public Int32 GetInt32(int offset = 0) { return NativeLibrary.plc_tag_get_int32(_tag.Handle, offset); } + /// /// Set local value Int32 /// /// /// - public void SetInt32(int value, int offset = 0) { NativeMethod.plc_tag_set_int32(_tag.Handle, offset, value); } + public void SetInt32(Int32 value, int offset = 0) { NativeLibrary.plc_tag_set_int32(_tag.Handle, offset, value); } /// /// Get local value UInt64 /// /// /// - public ulong GetUInt64(int offset = 0) { return NativeMethod.plc_tag_get_uint64(_tag.Handle, offset); } + public UInt64 GetUInt64(int offset = 0) { return NativeLibrary.plc_tag_get_uint64(_tag.Handle, offset); } /// /// Set local value UInt64 /// /// /// - public void SetUInt64(ulong value, int offset = 0) { NativeMethod.plc_tag_set_uint64(_tag.Handle, offset, value); } + public void SetUInt64(UInt64 value, int offset = 0) { NativeLibrary.plc_tag_set_uint64(_tag.Handle, offset, value); } /// @@ -199,42 +197,42 @@ internal void Set(object value, int offset = 0) /// /// /// - public long GetInt64(int offset = 0) { return NativeMethod.plc_tag_get_int64(_tag.Handle, offset); } + public Int64 GetInt64(int offset = 0) { return NativeLibrary.plc_tag_get_int64(_tag.Handle, offset); } /// /// Set local value Int64 /// /// /// - public void SetInt64(long value, int offset = 0) { NativeMethod.plc_tag_set_int64(_tag.Handle, offset, value); } + public void SetInt64(Int64 value, int offset = 0) { NativeLibrary.plc_tag_set_int64(_tag.Handle, offset, value); } /// /// Get local value Float32 /// /// /// - public float GetFloat32(int offset = 0) { return NativeMethod.plc_tag_get_float32(_tag.Handle, offset); } + public float GetFloat32(int offset = 0) { return NativeLibrary.plc_tag_get_float32(_tag.Handle, offset); } /// /// Set local value Float32 /// /// /// - public void SetFloat32(float value, int offset = 0) { NativeMethod.plc_tag_set_float32(_tag.Handle, offset, value); } + public void SetFloat32(float value, int offset = 0) { NativeLibrary.plc_tag_set_float32(_tag.Handle, offset, value); } /// /// Get local value Float /// /// /// - public double GetFloat64(int offset = 0) { return NativeMethod.plc_tag_get_float64(_tag.Handle, offset); } + public double GetFloat64(int offset = 0) { return NativeLibrary.plc_tag_get_float64(_tag.Handle, offset); } /// /// Set local value Float /// /// /// - public void SetFloat64(double value, int offset = 0) { NativeMethod.plc_tag_set_float64(_tag.Handle, offset, value); } + public void SetFloat64(double value, int offset = 0) { NativeLibrary.plc_tag_set_float64(_tag.Handle, offset, value); } /// /// Get local value String @@ -260,7 +258,7 @@ public string GetString(int offset = 0) /// public void SetString(string value, int offset = 0) { - if (value.Length > MAX_LENGT_STRING) { throw new IndexOutOfRangeException($"Length strign <= {MAX_LENGT_STRING}!"); } + if (value.Length > MAX_LENGTH_STRING) { throw new ArgumentOutOfRangeException($"Length strign <= {MAX_LENGTH_STRING}!"); } //set length SetInt32(value.Length, offset); @@ -274,7 +272,7 @@ public void SetString(string value, int offset = 0) } // pad with zeros - for (; strIdx < MAX_LENGT_STRING; strIdx++) { SetUInt8(0, offset + BYTE_HEADER_LENGTH_STRING + strIdx); } + for (; strIdx < MAX_LENGTH_STRING; strIdx++) { SetUInt8(0, offset + BYTE_HEADER_LENGTH_STRING + strIdx); } } /// @@ -282,7 +280,7 @@ public void SetString(string value, int offset = 0) /// /// /// - public bool GetBit(int index) { return (Convert.ToInt64(GetNumvericValue()) & (1 << index)) != 0; } + public bool GetBit(int index) { return (Convert.ToInt64(GetNumericValue()) & (1 << index)) != 0; } /// /// Set bit from index and value @@ -291,7 +289,7 @@ public void SetString(string value, int offset = 0) /// public void SetBit(int index, bool value) { - if (_tag.Size * 8 <= index) { throw new IndexOutOfRangeException("Index out of bound!"); } + if (_tag.Size * 8 <= index) { throw new ArgumentOutOfRangeException("Index out of bound!"); } var bits = GetBits(); bits.Set(index, value); @@ -305,7 +303,7 @@ public void SetBit(int index, bool value) /// Get bit array from value /// /// - public BitArray GetBits() { return new BitArray(new[] { Convert.ToInt32(GetNumvericValue()) }); } + public BitArray GetBits() { return new BitArray(new[] { Convert.ToInt32(GetNumericValue()) }); } /// /// Get bit array from value @@ -365,10 +363,10 @@ public object GetType(object obj, int offset = 0) return obj; } - private object GetNumvericValue(int offset = 0) + private object GetNumericValue(int offset = 0) { if (IsNumericInteger()) { return Get(_tag.Value, offset); } - else { throw new Exception("Error data type!"); } + else { throw new ArgumentException("Error data type!"); } } private bool IsNumericInteger() diff --git a/src/Corsinvest.AllenBradley.PLC.Api/icon.png b/src/Corsinvest.AllenBradley.PLC.Api/icon.png new file mode 100644 index 0000000..1e18976 Binary files /dev/null and b/src/Corsinvest.AllenBradley.PLC.Api/icon.png differ diff --git a/src/Corsinvest.AllenBradley.PLC.Api/libplctag.so b/src/Corsinvest.AllenBradley.PLC.Api/libplctag.so deleted file mode 100755 index ca19d4d..0000000 Binary files a/src/Corsinvest.AllenBradley.PLC.Api/libplctag.so and /dev/null differ diff --git a/src/Corsinvest.AllenBradley.PLC.Api/plctag.dll b/src/Corsinvest.AllenBradley.PLC.Api/plctag.dll deleted file mode 100644 index f35cb96..0000000 Binary files a/src/Corsinvest.AllenBradley.PLC.Api/plctag.dll and /dev/null differ diff --git a/src/Corsinvest.AllenBradley.PLC.Api/runtimes/linux-x64/native/plctag.so b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/linux-x64/native/plctag.so new file mode 100644 index 0000000..7ff7428 Binary files /dev/null and b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/linux-x64/native/plctag.so differ diff --git a/src/Corsinvest.AllenBradley.PLC.Api/runtimes/linux-x86/native/plctag.so b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/linux-x86/native/plctag.so new file mode 100644 index 0000000..b89ec85 --- /dev/null +++ b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/linux-x86/native/plctag.so @@ -0,0 +1 @@ +This is a fake file - eventually it will be updated with a real binary \ No newline at end of file diff --git a/src/Corsinvest.AllenBradley.PLC.Api/runtimes/win-x64/native/plctag.dll b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/win-x64/native/plctag.dll new file mode 100644 index 0000000..f1300b4 Binary files /dev/null and b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/win-x64/native/plctag.dll differ diff --git a/src/Corsinvest.AllenBradley.PLC.Api/runtimes/win-x86/native/plctag.dll b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/win-x86/native/plctag.dll new file mode 100644 index 0000000..e8ae1ae Binary files /dev/null and b/src/Corsinvest.AllenBradley.PLC.Api/runtimes/win-x86/native/plctag.dll differ