Original post

Does anyone intrested in implementation of industrial communication protocols in go?

It can be used for automation projects, web based scadas, data acquisition systems, iot devices etc.

I have some experience and want to start an open source project.

go ahead and start doing it :slight_smile: It’s easier to find contributors to an existing project

Can i take some architectural ideas from you ? :slight_smile:

yeah, what do you need to know?

Thank you, i have a couple of industrial communication clients. i want to collect them in a library. Is this a good practice?

package main

import "fmt"

type Client interface {
        Connect()
}

type TcpClient struct {
        IpAddress string
        Port      int
}

type ModbusTcpClient struct {
        TcpClient
        UnitIndentifier int
}

func (c ModbusTcpClient) Connect() {
        fmt.Println("connect method for modbus tcp client", c)
}

type IsoOnTcpClient struct {
        TcpClient
        Rack int
        Slot int
}

func (c IsoOnTcpClient) Connect() {
        fmt.Println("connect method for iso on tcp client", c)
}

func NewModbusTcpClient(ipAddress string, port, unitIdentifier int) Client {
        c := ModbusTcpClient{
                UnitIndentifier: unitIdentifier,
        }
        c.IpAddress = ipAddress
        c.Port = port
        return c
}

func NewIsoOnTcpClient(ipAddress string, port, rack, slot int) Client {
        c := IsoOnTcpClient{
                Rack: rack,
                Slot: slot,
        }
        c.IpAddress = ipAddress
        c.Port = port
        return c
}

func main() {
        mtc := NewModbusTcpClient("1.2.3.4", 5, 6)
        mtc.Connect()

        iotc := NewIsoOnTcpClient("7.8.9.10", 11, 12, 13)
        iotc.Connect()
}

looks good for me, at least from what I can see.

I think the following (composite pattern) will be unnecessary since there is only two clients and eight different functions.

package main

import "fmt"

const (
        ModbusTcpClient = 1
        IsoOnTcpClient  = 2
)

type Connector interface {
        Connect()
}

type TcpConnector struct {
        IpAddress string
        Port      int
}

//iso on tcp
type IsoOnTcpConnector struct {
        TcpConnector
        Rack int
        Slot int
}

func (c *IsoOnTcpConnector) Connect() {
        fmt.Println("connect method for iso on tcp client")
}

//modbus tcp
type ModbusTcpConnector struct {
        TcpConnector
        UnitIdentifier int
}

func (c *ModbusTcpConnector) Connect() {
        fmt.Println("connect method for modbus tcp client")
}

type Configuration struct {
        Type           int
        IpAddress      string
        Port           int
        UnitIdentifier int
        Rack           int
        Slot           int
}

type Client struct {
        Connector
}

func New(c *Configuration) *Client {
        switch c.Type {
        case ModbusTcpClient:
                mtc := &ModbusTcpConnector{
                        UnitIdentifier: c.UnitIdentifier,
                }
                mtc.IpAddress = c.IpAddress
                mtc.Port = c.Port
                return &Client{
                        mtc,
                }
        case IsoOnTcpClient:
                iotc := &IsoOnTcpConnector{
                        Rack: c.Rack,
                        Slot: c.Slot,
                }
                iotc.IpAddress = c.IpAddress
                iotc.Port = c.Port
                return &Client{
                        iotc,
                }
        default:
                return nil
        }
}

func main() {
        mtc := New(&Configuration{
                Type:           ModbusTcpClient,
                IpAddress:      "1.2.3.4",
                Port:           502,
                UnitIdentifier: 0,
        })
        mtc.Connect()

        iotc := New(&Configuration{
                Type:      IsoOnTcpClient,
                IpAddress: "1.2.3.4",
                Port:      102,
                Rack:      0,
                Slot:      1,
        })
        iotc.Connect()
}

the question is if other clients will have similar configuration. You should follow open-closed principle. Right now, when a new type will come you have to edit New(c) function.

I’d keep them separate: NewModbusTcp() and NewIsoOnTcpClient(). What they really have in common is the Connect() function but right now I cannot see any use case for Connector interface so I’d drop it. At least for now.

Thank you, i understand.

Hello,

I could make some time and quite complete the project which you guided me about the architecture.

If you have time, i’ll be glad if you check even only the usage part.

https://github.com/ermanimer/ict/blob/master/README.md#usage

Best regards

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.