mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 03:01:24 +00:00
Update README.md
This commit is contained in:
166
README.md
166
README.md
@@ -1,16 +1,22 @@
|
|||||||
[](https://github.com/WOmed/MewtocolNet/actions/workflows/publish-pipeline.yml)
|
[](https://github.com/WOmed/MewtocolNet/actions/workflows/publish-pipeline.yml)
|
||||||
[](https://github.com/WOmed/MewtocolNet/actions/workflows/test-pipeline.yml)
|
[](https://github.com/WOmed/MewtocolNet/actions/workflows/test-pipeline.yml)
|
||||||
[](https://github.com/WOmed/MewtocolNet/pkgs/nuget/Mewtocol.NET)
|
[](https://github.com/WOmed/MewtocolNet/pkgs/nuget/Mewtocol.NET)
|
||||||
[](https://htmlpreview.github.io/?https://github.com/WOmed/MewtocolNet/blob/badges/Builds/TestResults/summary_master.html)
|
[](https://htmlpreview.github.io/?https://github.com/WOmed/MewtocolNet/blob/badges/Builds/TestResults/summary_master.html)
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
# MewtocolNet
|
# MewtocolNet
|
||||||
An easy to use Mewtocol protocol library to interface with Panasonic PLCs over TCP/Serial.
|
An easy to use Mewtocol protocol library to interface with Panasonic PLCs over TCP/Serial.
|
||||||
|
|
||||||
## Disclaimer
|
> ⚠️ This library is not an official panasonic product nor does panasonic provide financial support or limitations in any form.
|
||||||
This library is not an official panasonic product nor does panasonic provide financial support or limitations in any form.
|
> This software was written by WOLF Medizintechnik GmbH (@WOmed/dev).
|
||||||
This software was written by WOLF Medizintechnik GmbH (@WOmed/dev).
|
|
||||||
|
# PLC Support
|
||||||
|
|
||||||
|
## For a full list check [this table](../master_auto_docs/plctypes.md)
|
||||||
|
|
||||||
|
> This library was only tested with a few PLCs, other types that support the Panasonic Mewtocol protocol might work.
|
||||||
|
> Use at your own risk, others might follow with community feedback
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
@@ -32,18 +38,7 @@ This library was written in **netstandard2.0** and should be compatible with a l
|
|||||||
|
|
||||||
For a full list of supported .NET clrs see [this page](https://docs.microsoft.com/de-de/dotnet/standard/net-standard?tabs=net-standard-2-0#select-net-standard-version)
|
For a full list of supported .NET clrs see [this page](https://docs.microsoft.com/de-de/dotnet/standard/net-standard?tabs=net-standard-2-0#select-net-standard-version)
|
||||||
|
|
||||||
## PLC Support
|
# Installation
|
||||||
|
|
||||||
> This library was only tested with a few PLCs, other types that support the Panasonic Mewtocol protocol might work.
|
|
||||||
> Use at your own risk, others might follow with community feedback
|
|
||||||
|
|
||||||
For a **Support List** check [this table](AutoTools.DocBuilder/Docs/plctypes.md)
|
|
||||||
|
|
||||||
Where is the RS232/Serial support?
|
|
||||||
|
|
||||||
> Support for the serial protocol will be added soon, feel free to contribute
|
|
||||||
|
|
||||||
# Installing
|
|
||||||
|
|
||||||
Use the dotnet CLI and run
|
Use the dotnet CLI and run
|
||||||
```Shell
|
```Shell
|
||||||
@@ -57,51 +52,51 @@ Refer to this site if you want to see the general functionality or add / report
|
|||||||
|
|
||||||
> This library is at the time not feature complete, but all essential features are provided
|
> This library is at the time not feature complete, but all essential features are provided
|
||||||
|
|
||||||
# Usage
|
# Examples
|
||||||
|
|
||||||
See [More examples](/Examples) here
|
To see a full list of examples [click here](/Examples).
|
||||||
|
|
||||||
## Connecting to a PLC
|
## Connecting to a PLC
|
||||||
|
|
||||||
Connecting to a PLC is as simple as
|
Connecting to a PLC is as simple as
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
//attaching a logger
|
using (var plc = Mewtocol.Ethernet("192.168.178.55").Build()) {
|
||||||
Logger.LogLevel = LogLevel.Verbose;
|
|
||||||
Logger.OnNewLogMessage((date, msg) => {
|
|
||||||
Console.WriteLine($"{date.ToString("HH:mm:ss")} {msg}");
|
|
||||||
});
|
|
||||||
|
|
||||||
//setting up a new PLC interface
|
|
||||||
MewtocolInterface plc = new MewtocolInterface("192.168.115.5");
|
|
||||||
|
|
||||||
await plc.ConnectAsync();
|
await plc.ConnectAsync();
|
||||||
|
if (!plc.IsConnected) {
|
||||||
|
Console.WriteLine("Failed to connect to the plc...");
|
||||||
|
} else {
|
||||||
|
Console.WriteLine(plc.PlcInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Reading data registers / contacts
|
## Reading data registers / contacts
|
||||||
|
|
||||||
[Detailed instructions](https://github.com/WOmed/MewtocolNet/wiki/Attribute-handled-reading)
|
[Detailed instructions](https://github.com/WOmed/MewtocolNet/wiki/Attribute-handled-reading)
|
||||||
|
|
||||||
- Create a new class that inherits from `RegisterCollectionBase`
|
- Create a new class that inherits from `RegisterCollection`
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
public class TestRegisters : RegisterCollectionBase {
|
public class TestRegisters : RegisterCollection {
|
||||||
|
|
||||||
//corresponds to a R100 boolean register in the PLC
|
//corresponds to a R100 boolean register in the PLC
|
||||||
[Register(100, RegisterType.R)]
|
[Register("R100")]
|
||||||
public bool TestBool1 { get; private set; }
|
public bool TestBool1 { get; private set; }
|
||||||
|
|
||||||
//corresponds to a XD input of the PLC
|
//corresponds to a XD input of the PLC
|
||||||
[Register(RegisterType.X, SpecialAddress.D)]
|
[Register("XD")]
|
||||||
public bool TestBoolInputXD { get; private set; }
|
public bool TestBoolInputXD { get; private set; }
|
||||||
|
|
||||||
//corresponds to a DT7012 - DT7013 as a 32bit time value that gets parsed as a timespan (TIME)
|
//corresponds to a DDT7012 - DDT7013 as a 32bit time value that gets parsed as a timespan (TIME)
|
||||||
//the smallest value to communicate to the PLC is 10ms
|
//the smallest value to communicate to the PLC is 10ms
|
||||||
[Register(7012)]
|
[Register("DDT7012")]
|
||||||
public TimeSpan TestTime { get; private set; }
|
public TimeSpan TestTime { get; private set; }
|
||||||
|
|
||||||
//corresponds to a DT1101 - DT1104 string register in the PLC with (STRING[4])
|
//corresponds to a DT1101 - DT1104 string register in the PLC with (STRING[4])
|
||||||
[Register(1101, 4)]
|
[Register("DT1101", "STRING[4]")]
|
||||||
public string TestString1 { get; private set; }
|
public string TestString1 { get; private set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -111,80 +106,69 @@ public class TestRegisters : RegisterCollectionBase {
|
|||||||
- attach an automatic poller by chaining `.WithPoller()` after the register attachment
|
- attach an automatic poller by chaining `.WithPoller()` after the register attachment
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
//setting up a new PLC interface and register collection
|
|
||||||
MewtocolInterface plc = new MewtocolInterface("192.168.115.5");
|
|
||||||
TestRegisters registers = new TestRegisters();
|
|
||||||
|
|
||||||
//attaching the register collection and an automatic poller
|
TestRegisters registers = null;
|
||||||
plc.WithRegisterCollection(registers).WithPoller();
|
|
||||||
|
//setting up a new PLC serial interface and tell it to use the register collection
|
||||||
|
var plc = Mewtocol.Serial("COM4", BaudRate._19200)
|
||||||
|
.WithPoller()
|
||||||
|
.WithRegisterCollections(c => {
|
||||||
|
registers = c.AddCollection<TestRegisters>();
|
||||||
|
// or use
|
||||||
|
// c.AddCollection(new TestRegisters());
|
||||||
|
// if you want to pass data to a constructor
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
//connect to it
|
||||||
|
await plc.ConnectAsync(async () => {
|
||||||
|
|
||||||
|
//restart the plc program during the connection process
|
||||||
|
await plc.RestartProgramAsync();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//wait for the first data cycle of the poller module
|
||||||
|
//otherwise the property value might still be unset or null
|
||||||
|
await App.ViewModel.Plc.AwaitFirstDataCycleAsync();
|
||||||
|
|
||||||
|
if (App.ViewModel.Plc.IsConnected) {
|
||||||
|
|
||||||
|
Console.WriteLine(registers.TestBool1);
|
||||||
|
|
||||||
await plc.ConnectAsync(
|
|
||||||
(plcinf) => {
|
|
||||||
//reading a value from the register collection
|
|
||||||
Console.WriteLine($"Time Value is: {registers.TestTime}");
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
```
|
```
|
||||||
- Your properties are getting automatically updated after the initial connection
|
- Your properties are getting automatically updated after the initial connection
|
||||||
|
|
||||||
> Note! this is not your only option to read registers, see here
|
> Note! this is not your only option to read registers, see here
|
||||||
|
|
||||||
## Writing data registers / contacts
|
## Reading & Writing
|
||||||
|
|
||||||
Registers are stored in an underlying layer for automatic handling, each register has a unique name and address.
|
In addition to the automatic property binding you can use these patterns:
|
||||||
|
|
||||||
Classes that derive from `RegisterCollectionBase` reference these registers automatically using attributes.
|
### Reading & Writing by using the anonymous builder pattern
|
||||||
All the heavy lifting is done automatically for you, setting this up is described [here](https://github.com/WOmed/MewtocolNet/wiki/Attribute-handled-reading)
|
|
||||||
|
|
||||||
### Asynchronous
|
|
||||||
|
|
||||||
This operations awaits a task to make sure the register was actually set to your desired value before progressing
|
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
//sets the register to false
|
await plc.Register.Struct<short>("DT100").WriteAsync(100);
|
||||||
await plc.SetRegisterAsync(nameof(registers.TestBool1), false);
|
|
||||||
|
|
||||||
//set the current second to the PLCs TIME register
|
var value = await plc.Register.Struct<short>("DT100").ReadAsync();
|
||||||
await plc.SetRegisterAsync(nameof(registers.TestTime), TimeSpan.FromSeconds(DateTime.Now.Second));
|
|
||||||
```
|
```
|
||||||
|
### Reading & Writing by using the direct reference from the builder pattern
|
||||||
### Synchronous
|
|
||||||
|
|
||||||
Sets the register without feedback if it was set
|
|
||||||
|
|
||||||
You can use the method to set a register
|
|
||||||
|
|
||||||
```C#
|
```C#
|
||||||
//inverts the boolean register
|
|
||||||
plc.SetRegister(nameof(registers.TestBool1), !registers.TestBool1);
|
|
||||||
|
|
||||||
//set the current second to the PLCs TIME register
|
IRegister<bool> outputContactReference;
|
||||||
plc.SetRegister(nameof(registers.TestTime), TimeSpan.FromSeconds(DateTime.Now.Second));
|
|
||||||
|
|
||||||
//writes 'Test' to the PLCs string register
|
var plc = Mewtocol.Ethernet("127.0.0.1")
|
||||||
plc.SetRegister(nameof(registers.TestString1), "Test");
|
.WithRegisters(b => {
|
||||||
```
|
|
||||||
|
b.Bool("Y4").Build(out outputContactReference);
|
||||||
or write to a register in your `RegisterCollectionBase` directly (you need to attach a register collection to your interface beforehand)
|
|
||||||
|
})
|
||||||
```C#
|
.Build();
|
||||||
//inverts the boolean register
|
|
||||||
registers.TestBool1 = true;
|
await plc.ConnectAsync();
|
||||||
```
|
|
||||||
|
await outputContactReference.WriteAsync(true);
|
||||||
You can also set a register by calling its name directly (Must be either in an attached register collection or added to the list manually)
|
|
||||||
|
|
||||||
Adding registers to a manual list
|
|
||||||
```C#
|
|
||||||
plc.AddRegister<bool>(105, _name: "ManualBoolRegister");
|
|
||||||
```
|
|
||||||
|
|
||||||
Reading the value of the manually added register
|
|
||||||
```C#
|
|
||||||
//get the value as a string
|
|
||||||
string value = plc.GetRegister("ManualBoolRegister").GetValueString();
|
|
||||||
//get the value by casting
|
|
||||||
bool value2 = plc.GetRegister<BRegister>("ManualBoolRegister").Value;
|
|
||||||
//for double casted ones like numbers
|
|
||||||
var value2 = plc.GetRegister<NRegister<short>>("NumberRegister").Value;
|
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user