All Projects → Rickedb → OpenProtocolInterpreter

Rickedb / OpenProtocolInterpreter

Licence: MIT license
Converts the ugly package that came from Open Protocol to an object

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to OpenProtocolInterpreter

lingtypology
R package for linguistic cartography and typological databases search
Stars: ✭ 47 (-50%)
Mutual labels:  atlas
material-combiner-addon
Blender addon for material combining, uv bounds fixing
Stars: ✭ 309 (+228.72%)
Mutual labels:  atlas
community-actions
Actions for Atlas created by the community.
Stars: ✭ 15 (-84.04%)
Mutual labels:  atlas
joyconpi
An attempt at emulating a Nintendo Switch Joy-Con controller with a Raspberry Pi
Stars: ✭ 24 (-74.47%)
Mutual labels:  controller
lwpkt
Lightweight packet protocol structure for multi-device communication focused on RS-485
Stars: ✭ 71 (-24.47%)
Mutual labels:  protocol
bitwig
Some controller scripts for Bitwig
Stars: ✭ 43 (-54.26%)
Mutual labels:  controller
vpc-peering-operator
A Kubernetes Operator to manage the lifecycle of AWS VPC Peering Connections
Stars: ✭ 23 (-75.53%)
Mutual labels:  controller
subpixel-embedding-segmentation
PyTorch Implementation of Small Lesion Segmentation in Brain MRIs with Subpixel Embedding (ORAL, MICCAIW 2021)
Stars: ✭ 22 (-76.6%)
Mutual labels:  atlas
stick
Platform-agnostic asynchronous gamepad, joystick and flightstick library for the Rust Programming Language
Stars: ✭ 41 (-56.38%)
Mutual labels:  controller
ethereum-crowdsale
0xcert protocol crowdsale contracts for Ethereum blockchain.
Stars: ✭ 15 (-84.04%)
Mutual labels:  protocol
kerntroller
No description or website provided.
Stars: ✭ 31 (-67.02%)
Mutual labels:  controller
pymobiledevice3
Pure python3 implementation for working with iDevices (iPhone, etc...).
Stars: ✭ 259 (+175.53%)
Mutual labels:  protocol
arkadiko-dao
Arkadiko is a liquidity protocol that implements a stablecoin (xUSD) and governance token (DIKO) on Stacks
Stars: ✭ 34 (-63.83%)
Mutual labels:  protocol
baseline
The Baseline Protocol is an open source initiative that combines advances in cryptography, messaging, and distributed ledger technology to enable confidential and complex coordination between enterprises while keeping data in systems of record. This repo serves as the main repo for the Baseline Protocol, containing core packages, examples, and r…
Stars: ✭ 565 (+501.06%)
Mutual labels:  protocol
open-dis-java
Java implementation of the IEEE-1278.1 Distributed Interactive Simulation (DIS) application protocol v6 and v7 💥
Stars: ✭ 30 (-68.09%)
Mutual labels:  protocol
ethereumd-proxy
Proxy client-server for Ethereum node using bitcoin JSON-RPC interface.
Stars: ✭ 21 (-77.66%)
Mutual labels:  protocol
robotarium-rendezvous-RSSDOA
This repository contains the Matlab source codes (to use in Robotarium platform) of various rendezvous controllers for consensus control in a multi-agent / multi-robot system.
Stars: ✭ 35 (-62.77%)
Mutual labels:  controller
Adium-Steam-IM
Adium protocol plugin to support Steam instant messaging
Stars: ✭ 50 (-46.81%)
Mutual labels:  protocol
amala
Lightweight, Typescript REST library powered by Koa 2+. Use classes and decorators to define your API. Inject arguments from ctx. Supports API versioning. Future support for OpenAPI3. Works with koa-router.
Stars: ✭ 41 (-56.38%)
Mutual labels:  controller
libmicrohttpd-http2
HTTP/2 support for libmicrohttpd
Stars: ✭ 21 (-77.66%)
Mutual labels:  protocol

Open Protocol Interpreter

Buy me a coffee MIT

OpenProtocol communication utility

  1. What is Open Protocol at all?
  2. What is OpenProtocolInterpreter?
  3. How does it work?
  4. Usage examples
  5. Available on package managers
  6. Advanced section
  7. Tips
  8. Contribute to the project
  9. Still unavailable mids

What is Open Protocol at all?

Open Protocol, as the name says, it's a protocol to communicate with Atlas Copco Tightening Controllers or whatever that implement that protocol. Most common Tightening Controllers from Atlas Copco company are PowerFocus4000 and PowerMacs.

Although, some other companies adhered to use the same protocol.

What is OpenProtocolInterpreter?

OpenProtocolInterpreter is a library that converts the ugly string that came from Open Protocol packages, which is commonly called MID, to an object. "Substringing" packages is such a boring thing to do, so let OpenProtocolIntepreter do it for you!

If you're curious, just take a look at their documentation.

How does it work?

It's simple, you give us your byte[] or string package and we deliver you an object, simple as that!

For example, let's imagine you received the following string package:

string package = "00240005001         0018";

It's MID 5, so OpenProtocolIntepreter will return a Mid0005 class for you with all his datafields and the package entire translated to an object.

Let's see some examples of usage

A simple usage:

var interpreter = new MidInterpreter();
var midPackage = @"00260004001         001802";
var myMid04 = interpreter.Parse<Mid0004>(midPackage);
//MID 0004 is an error mid which contains which MID Failed and its error code
//Int value of the Failed Mid
int myFailedMid = myMid04.FailedMid;
//An enum with Error Code
Error errorCode = myMid04.ErrorCode;

It can generate an object from a string, but can it make it to the other way?? FOR SURE!

var jobUploadRequest = new Mid0032(1, 2); //Job id 1, revision 2
var package = jobUploadRequest.Pack();
//Generated package => 00240032002         0001

Get it on NuGet!

Install-Package OpenProtocolInterpreter

Advanced Section!

Now we will get real! Put one thing in mind, in real world we will always need to build something more complex than the dummies examples we give to you. With this in mind, this section is for you:

How it was built?

It used to rely on Chain Of Responsabilities design pattern, but since we had some problems with instance references, it changed! For now, instead of iterating through all Mids of the same category, it relies on a Dictionary, which every category knows which mid it attends, once it found it creates a new Instance via System.Reflection and parse it.

MIDs Identifying Customization

We have several MIDs inside Open Protocol documentation, but do you really need all of them? The answer is... NO!

You will probably need only to use a range of MIDs, with this in mind, we did something to make things faster. You can tell us which MIDs we should considerate!

*NOTE: You can register only mids you need to call "Parse" method

Here is an example:

string package = "00260004001         001802";
var myCustomInterpreter = new MidInterpreter()
								.UseAllMessages(new Type[]
		                        {
		                            typeof(Mid0001),
		                            typeof(Mid0002),
		                            typeof(Mid0003),
		                            typeof(Mid0004),
		                            typeof(Mid0106)
		                        });
//Will work:
var myMid04 = myCustomInterpreter.Parse<Mid0004>(package);
//Won't work, will throw NotImplementedException:
var myMid30 = myCustomInterpreter.Parse<Mid0030>(package);        
//Won't work, will throw InvalidCastException:
var myMid01 = myCustomInterpreter.Parse<Mid0001>(package);

When you don't know which package will come, use Parse overload, not Parse<DesiredMid>. If you want, take a look at the sample on this repository.

If necessary, there is a new overload where you can define if you're the controller or the integrator, which will automatically handle implemented mids

MIDs Overriding

Maybe you have a totally crazy controller that does not implement the Mid as the documentation says or you might want to inject your own Mid inheriting another Mid, so you can customize it and add more properties to handle some conversions. Anyway, if you need that, it's possible to override!

Here is an example:

//This will override Mid 81 with my custom Mid
var _midInterpreter new MidInterpreter().UseAllMessages()
                                        .UseTimeMessages(new Dictionary<int, Type>() { { 81, typeof(OverridedMid0081) } });


public class OverridedMid0081 : Mid0081
{
    public string FormattedDate
    {
        get => Time.ToString("dd/MM/yyyy HH:mm:ss");
        set => Time = DateTime.Parse(value);
    }

    public OverridedMid0081()
    {
        
    }

    public override string Pack()
    {
        Time = TestCustomMid.Now;
        return base.Pack();
    }
}

Adding MIDs that are not in documentation

Maybe your controller is weird and have unknown MID numbers, MIDs that are not in the documentation and you want to inject into MidInterpreter, there is a way:

var _midInterpreter new MidInterpreter().UseAllMessages()
                                        .UseCustomMessage(new Dictionary<int, Type>() { { 83, typeof(NewMid0083) } });

public class NewMid0083 : Mid
{
    private readonly IValueConverter<DateTime> _dateConverter;
    private const int LAST_REVISION = 1;
    public const int MID = 83;

    public DateTime Time
    {
        get => GetField(1, (int)DataFields.TIME).GetValue(_dateConverter.Convert);
        set => GetField(1, (int)DataFields.TIME).SetValue(_dateConverter.Convert, value);
    }
    public string TimeZone
    {
        get => GetField(1, (int)DataFields.TIMEZONE).Value;
        set => GetField(1, (int)DataFields.TIMEZONE).SetValue(value);
    }

    public NewMid0083() : base(MID, LAST_REVISION)
    {
        _dateConverter = new DateConverter();
    }

    protected override Dictionary<int, List<DataField>> RegisterDatafields()
    {
        return new Dictionary<int, List<DataField>>()
        {
            {
                1, new List<DataField>()
                        {
                            new DataField((int)DataFields.TIME, 20, 19),
                            new DataField((int)DataFields.TIMEZONE, 41, 2)
                        }
            }
        };
    }

    public enum DataFields
    {
        TIME,
        TIMEZONE
    }
}

NOTE: Custom messages might not perform as fast as other MIDs because they don't have optimizations for finding it

Advanced Example

Declared a delegate:

protected delegate void ReceivedCommandActionDelegate(ReceivedMIDEventArgs e);

ReceivedMIDEventArgs class:

public class ReceivedMidEventArgs : EventArgs
{
    public Mid ReceivedMid { get; set; }
}

Created a method to register all those MID types by delegates:

protected Dictionary<Type, ReceivedCommandActionDelegate> RegisterOnAsyncReceivedMids()
{
    var receivedMids = new Dictionary<Type, ReceivedCommandActionDelegate>();
    receivedMids.Add(typeof(Mid0005), new ReceivedCommandActionDelegate(OnCommandAcceptedReceived));
    receivedMids.Add(typeof(Mid0004), new ReceivedCommandActionDelegate(OnErrorReceived));
    receivedMids.Add(typeof(Mid0071), new ReceivedCommandActionDelegate(OnAlarmReceived));
    receivedMids.Add(typeof(Mid0061), new ReceivedCommandActionDelegate(OnTighteningReceived));
    receivedMids.Add(typeof(Mid0035), new ReceivedCommandActionDelegate(OnJobInfoReceived));
    return receivedMids;
}

What was done is registering in a dictionary the correspondent delegate for a determinated MID, once done that we just need to invoke the delegate everytime you face a desired MID.

When a package income:

protected void OnPackageReceived(string message)
{
    try
    {
        //Parse to mid class
        var mid = Interpreter.Parse(message);

        //Get Registered delegate for the MID that was identified
        var action = OnReceivedMid.FirstOrDefault(x => x.Key == mid.GetType());
        
        if (action.Equals(default(KeyValuePair<Type, ReceivedCommandActionDelegate>)))
           return; //Stop if there is no delegate registered for the message that arrived

         action.Value(new ReceivedMidEventArgs() { ReceivedMid = mid }); //Call delegate
     }
     catch (Exception ex)
     {
        Console.log(ex.Message);
     }
}

This would call the registered delegate which you're sure what mid it is. For example when a MID_0061 (last tightening) pop up, the onTighteningReceived delegate will be called:

protected void OnTighteningReceived(ReceivedMidEventArgs e)
{
    try
    {
        Mid0061 tighteningMid = e.ReceivedMID as Mid0061; //Casting to the right mid

        //This method just send the ack from tightening mid
        BuildAndSendAcknowledge(tighteningMid); 
        Console.log("TIGHTENING ARRIVED")
     }
     catch (Exception ex)
     {
         Console.log(ex.Message);
     }
}

protected void BuildAndSendAcknowledge(Mid mid)
{
     TcpClient.GetStream().Write(new Mid0062().Pack()); //Send acknowledge to controller
}

Tips

Instantiate the MIDIdentifier class just once and keep working with it!

Controller Implementation Tip: Always TRY to register used MIDs, not all Tightening Controllers use every available MID.

Integrator Implementation Tip: Always DO register used MIDs, I'm pretty sure you won't need all of them to your application.

Contribute to the project

Lot's of effort were given to this project and by seen people using it motivated me a lot to improve it more and more.

Does it help you a lot? That's awesome and very rewarding! But if you wish, you can support and help to motivate the constant improving of this library by contributing in OpenCollective.

List of still unavailable Mids

  • Mid 0009;
  • Mid 0066;
  • Mid 0700;
  • Mid 0702;
  • Mid 0703;
  • Mid 0900;
  • Mid 0901;
  • Mid 1000;
  • Mid 1001;
  • Mid 1601;
  • Mid 1602;
  • Mid 1900;
  • Mid 1901;
  • Mid 2100;
  • Mid 2500;
  • Mid 2501;
  • Mid 2505;
  • Mid 2600;
  • Mid 2601;
  • Mid 2602;
  • Mid 2603;
  • Mid 2604;
  • Mid 2605;
  • Mid 2606.

Feel free to fork and contribute to add any of those mids.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].