gos7

repository·master·Indexed 19 days ago

https://github.com/robinson/gos7

A pure Go implementation of the Siemens S7 protocol for communicating with S7 family PLCs, such as S7-1200 and S7-1500. It supports Access Group (AG) functions for reading and writing Data Blocks (DB), Merkers (MB), I/O areas (EB/AB), Timers (TM), and Counters (CT), as well as Programming Group (PG) functions for CPU control, system information, and security management. The library includes a Helper utility for converting between raw byte arrays and S7 data types.

Tokens
12K
Snippets
44
Records
61
Agent score
64%

What's inside gos7

  1. Overview of gos7

    master

    gos7 is a pure Go implementation of the Siemens S7 protocol. It is designed for low-level communication with S7 family PLC devices. The library supports both AG (Access Group) and PG (Programming Group) functions, allowing for data manipulation and PLC management.

    Requirements:

    • Minimum Go version: 1.13
  2. Use gos7 Helpers for data type conversion

    master

    The gos7.Helper utility provides methods to convert between raw byte arrays and various Siemens S7 data types. This is essential for preparing buffers before writing or interpreting buffers after reading.

    Supported types include:

    • bit, int, word, dword, uint, etc.
    • real (floating point)
    • time
    • counter
  3. Connect to a PLC via TCP

    master

    To communicate with a PLC over TCP, you must create a TCPClientHandler, configure its connection parameters (IP, rack, slot), and then initialize a Client using that handler. It is recommended to call handler.Connect() manually to maintain a single connection session for multiple requests.

    const (
    	tcpDevice = "127.0.0.1"
    	rack      = 0
    	slot      = 2
    )
    
    // Initialize the TCP handler
    handler := gos7.NewTCPClientHandler(tcpDevice, rack, slot)
    handler.Timeout = 200 * time.Second
    handler.IdleTimeout = 200 * time.Second
    handler.Logger = log.New(os.Stdout, "tcp: ", log.LstdFlags)
    
    // Connect manually to reuse the connection for multiple requests
    handler.Connect()
    defer handler.Close()
    
    // Initialize the client
    client := gos7.NewClient(handler)
  4. Use the Helper struct for PLC data conversion

    master

    The Helper struct provides utility methods to read and write various Siemens S7 PLC data types (such as Real, DateTime, String, and Counter) to and from byte arrays. This is essential when communicating with PLCs via protocols like S7Comm, where data is transmitted in specific binary formats (BigEndian, BCD, etc.).

    import "github.com/robinson/robinson/gos7"
    
    helper := &gos7.Helper{}
    // Use helper methods to manipulate byte buffers
  5. Connection lifecycle: Connect, Send, and Close

    master

    A typical session follows this lifecycle:

    1. Connect: Establishes the TCP connection and performs the S7 protocol handshake.
    2. Send: Transmits a request byte slice and waits for the response. The Send method handles the TPKT and COTP headers automatically.
    3. Close: Terminates the connection.

    Idle Timeout: The handler includes an IdleTimeout mechanism. If no activity occurs within the configured duration, the connection is automatically closed to save resources.

  6. S7SZL and SZLHeader types

    master

    These types represent the System Status List (SZL) data structures used for diagnostic communication with S7 systems.

    SZLHeader contains the metadata for the SZL record:

    • LengthHeader: Length of the header.
    • NumberOfDataRecord: Number of data records present.

    S7SZL is the container for the header and the raw data payload.

    S7SZLList is a specialized version where the data is interpreted as a list of big-endian uint16 values.

    type SZLHeader struct {
    	LengthHeader       uint16
    	NumberOfDataRecord uint16
    }
    
    type S7SZL struct {
    	Header SZLHeader
    	Data   []byte
    }
    
    type S7SZLList struct {
    	Header SZLHeader
    	Data   []uint16
    }
  7. Initialize an S7 Client

    master

    To use the gos7 library, you must create a Client instance. You can do this using two different methods depending on whether you have a single object that implements both Packager and Transporter interfaces, or if you want to provide them separately.

    • NewClient(handler ClientHandler): Use this if your backend handler implements the ClientHandler interface (which combines Packager and Transporter).
    • NewClient2(packager Packager, transporter Transporter): Use this to provide distinct implementations for packaging and transporting data.
    // Using a single handler
    client := gos7.NewClient(myHandler)
    
    // Using separate packager and transporter
    client := gos7.NewClient2(myPackager, myTransporter)
  8. Initialize a TCP client for S7 communication

    master

    To connect to a Siemens PLC, use the TCPClient or TCPClientWithConnectType functions. These functions return a Client interface that manages the underlying TCP connection, ISO-on-TCP handshake, and S7 PDU negotiation.

    Connection Types:

    • connectionTypePG (1): Connect to the PLC as a Programming Device (PG).
    • connectionTypeOP (2): Connect to the PLC as an Operator Panel (OP).
    • connectionTypeBasic (3): Basic connection.

    Parameters:

    • address: The IP address of the PLC (e.g., "192.168.0.1"). If no port is provided, it defaults to 102 (ISO-on-TCP).
    • rack: The PLC rack number.
    • slot: The PLC slot number.
    • connectType: (Optional) The specific connection type to use.
    // Using default PG connection type
    client := gos7.TCPClient("192.168.0.1", 2, 0)
    
    // Using a specific connection type (e.g., OP)
    client := gos7.TCPClientWithConnectType("192.168.0.1", 2, 0, 2)
  9. Read and Write Data Blocks (DB) using gos7

    master

    Use AGWriteDB to write values to a Data Block and AGReadDB to read them. Because the protocol works with byte buffers, use gos7.Helper to encode values into a buffer before writing, or decode them from a buffer after reading.

    // Setup
    address := 2710
    start := 8
    size := 2
    buffer := make([]byte, 255)
    value := 100
    var helper gos7.Helper
    
    // 1. Write to DB
    // Prepare the buffer with the value
    helper.SetValueAt(buffer, 0, value)  
    // Write to address DB2710, starting at position 8, size 2
    err := client.AGWriteDB(address, start, size, buffer)
    
    // 2. Read from DB
    readBuf := make([]byte, 255)
    err = client.AGReadDB(address, start, size, readBuf)
    
    // 3. Interpret the result
    var result uint16
    var s7 gos7.Helper
    s7.GetValueAt(readBuf, 0, &result)
  10. Supported AG (Access Group) functions

    master

    The AG functions allow for reading and writing various memory areas in the PLC. The following operations are tested and supported:

    • Read/Write Data Block (DB)
    • Read/Write Merkers (MB)
    • Read/Write IPI (EB)
    • Read/Write IPU (AB)
    • Read/Write Timer (TM)
    • Read/Write Counter (CT)
    • Multiple Read/Write Area
    • Get Block Info
  11. Supported PG (Programming Group) functions

    master

    The PG functions are used for PLC management and system information. The following operations are tested and supported:

    • Hot start / Cold start / Stop PLC
    • Get CPU of PLC status
    • List available blocks in PLC
    • Set/Clear password for session
    • Get CPU protection and CPU Order code
    • Get CPU/CP Information
    • Read/Write clock for the PLC
  12. Convert error codes to human-readable text with ErrorText()

    master

    The ErrorText(err int) string function converts an integer error code into a descriptive string. This is useful for logging or displaying errors to users. It handles various error categories including TCP, ISO, and CLI/CPU errors. If an unknown error code is provided, it returns a default string containing the integer value.

    import "gos7"
    
    // Example usage
    errCode := 1 // errTCPSocketCreation
    message := gos7.ErrorText(errCode)
    fmt.Println(message) // Output: SYS : Error creating the Socket