gos7

package module
v0.1.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2023 License: BSD-3-Clause Imports: 11 Imported by: 0

README

gos7

Implementation of Siemens S7 protocol in golang

Overview

For years, numerous drivers/connectors, available in both commercial and open source domains, have supported the connection to S7 family PLC devices. GoS7 fills the gaps in the S7 protocol, implementing it with pure Go (also known as golang). There is a strong belief that low-level communication should be implemented with a low-level programming language that is close to binary and memory.

The minimum supported Go version is 1.13.

Functions

AG:

  • Read/Write Data Block (DB) (tested)
  • Read/Write Merkers(MB) (tested)
  • Read/Write IPI (EB) (tested)
  • Read/Write IPU (AB) (tested)
  • Read/Write Timer (TM) (tested)
  • Read/Write Counter (CT) (tested)
  • Multiple Read/Write Area (tested)
  • Get Block Info (tested)

PG:

  • Hot start/Cold start / Stop PLC
  • Get CPU of PLC status (tested)
  • List available blocks in PLC (tested)
  • Set/Clear password for session
  • Get CPU protection and CPU Order code
  • Get CPU/CP Information (tested)
  • Read/Write clock for the PLC Helpers:
  • Get/set value for a byte array for types: value(bit/int/word/dword/uint...), real, time, counter

Supported communication

  • TCP
  • Serial (PPI, MPI) (under construction)

How to:

following is a simple usage to connect with PLC via TCP

const (
	tcpDevice = "127.0.0.1"
	rack      = 0
	slot      = 2
)
// TCPClient
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 so that multiple requests are handled in one connection session
handler.Connect()
defer handler.Close()
//init client
client := gos7.NewClient(handler)
address := 2710
start := 8
size := 2
buffer := make([]byte, 255)
value := 100
//AGWriteDB to address DB2710 with value 100, start from position 8 with size = 2 (for an integer)
var helper gos7.Helper
helper.SetValueAt(buffer, 0, value)  
err := client.AGWriteDB(address, start, size, buffer)
buf := make([]byte, 255)
//AGReadDB to address DB2710, start from position 8 with size = 2
err := client.AGReadDB(address, start, size, buf)
var s7 gos7.Helper
var result uint16
s7.GetValueAt(buf, 0, &result)	 
  

References

Simatic, Simatic S5, Simatic S7, S7-200, S7-300, S7-400, S7-1200, S7-1500 are registered Trademarks of Siemens

License

https://opensource.org/licenses/BSD-3-Clause

Copyright (c) 2018, robinson

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CPUError

func CPUError(err uint) int

CPUError specific CPU error after response

func ErrorText

func ErrorText(err int) string

ErrorText return a string error text from error code integer

Types

type Client

type Client interface {
	/***************start API AG (Automatisationsgerät)***************/
	//Read data blocks from PLC
	AGReadDB(dbNumber int, start int, size int, buffer []byte) (err error)
	//write data blocks into PLC
	AGWriteDB(dbNumber int, start int, size int, buffer []byte) (err error)
	//Read Merkers area from PLC
	AGReadMB(start int, size int, buffer []byte) (err error)
	//Write Merkers from into PLC
	AGWriteMB(start int, size int, buffer []byte) (err error)
	//Read IPI from PLC
	AGReadEB(start int, size int, buffer []byte) (err error)
	//Write IPI into PLC
	AGWriteEB(start int, size int, buffer []byte) (err error)
	//Read IPU from PLC
	AGReadAB(start int, size int, buffer []byte) (err error)
	//Write IPU into PLC
	AGWriteAB(start int, size int, buffer []byte) (err error)
	//Read timer from PLC
	AGReadTM(start int, size int, buffer []byte) (err error)
	//Write timer into PLC
	AGWriteTM(start int, size int, buffer []byte) (err error)
	//Read counter from PLC
	AGReadCT(start int, size int, buffer []byte) (err error)
	//Write counter into PLC
	AGWriteCT(start int, size int, buffer []byte) (err error)
	//multi read area
	AGReadMulti(dataItems []S7DataItem, itemsCount int) (err error)
	AGReadMultiResponse(dataItems []S7DataItemWithResponse, itemsCount int) (err error)
	//multi write area
	AGWriteMulti(dataItems []S7DataItem, itemsCount int) (err error)
	/*block*/
	DBFill(dbnumber int, fillchar int) error
	DBGet(dbnumber int, usrdata []byte, size int) error
	//general read function with S7 sytax
	Read(variable string, buffer []byte) (value interface{}, err error)
	//Get block  infor in AG area, refer an S7BlockInfor pointer
	GetAgBlockInfo(blocktype int, blocknum int) (info S7BlockInfo, err error)

	/***************start API PG (Programmiergerät)***************/
	/*control*/
	//Hotstart PLC, Puts the CPU in RUN mode performing an HOT START.
	PLCHotStart() error
	//Cold start PLC, change CPU into runmode performing and COLD START
	PLCColdStart() error
	//change CPU to stop mode
	PLCStop() error
	//return CPU status: running/stopped
	PLCGetStatus() (status int, err error)
	/*directory*/
	//list all blocks in PLC, return a Blockslist which contains list of OB, DB, ...
	PGListBlocks() (list S7BlocksList, err error)
	/*security*/
	//set the session password for PLC to meet its security level
	SetSessionPassword(password string) error
	//clear the password set for current session
	ClearSessionPassword() error
	//return the CPU protection level info, refer to: §33.19 of "System Software for S7-300/400 System and Standard Functions"
	//return S7Protection and its properties.
	GetProtection() (protection S7Protection, err error)
	/*system information*/
	//get CPU order code, return S7OrderCode
	GetOrderCode() (info S7OrderCode, err error)
	//get CPU info, return S7CpuInfo and its properties
	GetCPUInfo() (info S7CpuInfo, err error)
	//get CP info, return S7CpInfo and its properties
	GetCPInfo() (info S7CpInfo, err error)
	/*datetime*/
	//read clock on PLC, return a time
	PGClockRead(datetime time.Time) error
	//write clock to PLC with datetime input
	PGClockWrite() (dt time.Time, err error)
}

Client interface s7 client

func NewClient

func NewClient(handler ClientHandler) Client

NewClient creates a new s7 client with given backend handler.

func NewClient2

func NewClient2(packager Packager, transporter Transporter) Client

NewClient2 creates a new s7 client with given backend packager and transporter.

func TCPClient

func TCPClient(address string, rack int, slot int) Client

TCPClient creator for a TCP client with address, rack and slot, implement from interface client

type ClientHandler

type ClientHandler interface {
	Packager
	Transporter
}

CliePDULengthntHandler is the interface that groups the Packager and Transporter methods.

type Helper

type Helper struct{}

Helper the helper to get/set value from/to byte array with difference types

func (*Helper) GetBoolAt

func (s7 *Helper) GetBoolAt(b byte, pos uint) bool

GetBoolAt gets a boolean (bit) from a byte at position

func (*Helper) GetCharsAt

func (s7 *Helper) GetCharsAt(buffer []byte, pos int, Size int) string

GetCharsAt Get Array of char (S7 ARRAY OF CHARS)

func (*Helper) GetCounter

func (s7 *Helper) GetCounter(value uint16) int

GetCounter Get S7 Counter

func (*Helper) GetCounterAt

func (s7 *Helper) GetCounterAt(buffer []uint16, index int) int

GetCounterAt Get S7 Counter at a index

func (*Helper) GetDTLAt

func (s7 *Helper) GetDTLAt(buffer []byte, pos int) time.Time

GetDTLAt DTL (S71200/1500 Date and Time)

func (*Helper) GetDateAt

func (s7 *Helper) GetDateAt(buffer []byte, pos int) time.Time

GetDateAt DATE (S7 DATE)

func (*Helper) GetDateTimeAt

func (s7 *Helper) GetDateTimeAt(Buffer []byte, Pos int) time.Time

GetDateTimeAt DateTime (S7 DATE_AND_TIME)

func (*Helper) GetLDTAt

func (s7 *Helper) GetLDTAt(buffer []byte, pos int) time.Time

GetLDTAt LDT (S7 1500 Long Date and Time)

func (*Helper) GetLRealAt

func (s7 *Helper) GetLRealAt(buffer []byte, pos int) float64

GetLRealAt 64 bit floating point number (S7 LReal) (Range of float64)

func (*Helper) GetLTODAt

func (s7 *Helper) GetLTODAt(Buffer []byte, Pos int) time.Time

GetLTODAt LTOD (S7 1500 LONG TIME_OF_DAY)

func (*Helper) GetRealAt

func (s7 *Helper) GetRealAt(buffer []byte, pos int) float32

GetRealAt 32 bit floating point number (S7 Real) (Range of float32)

func (*Helper) GetS5TimeAt

func (s7 *Helper) GetS5TimeAt(buffer []byte, pos int) time.Duration

Get S5Time

func (*Helper) GetStringAt

func (s7 *Helper) GetStringAt(buffer []byte, pos int) string

GetStringAt Get String

func (*Helper) GetTODAt

func (s7 *Helper) GetTODAt(buffer []byte, pos int) time.Time

GetTODAt TOD (S7 TIME_OF_DAY)

func (*Helper) GetValueAt

func (s7 *Helper) GetValueAt(buffer []byte, pos int, value interface{})

GetValueAt set a value at a position of a byte array, which based on builtin function: https://golang.org/pkg/encoding/binary/#Write

func (*Helper) GetWStringAt

func (s7 *Helper) GetWStringAt(buffer []byte, pos int) string

GetWStringAt Get WString

func (*Helper) SetBoolAt

func (s7 *Helper) SetBoolAt(b byte, bitPos uint, data bool) byte

SetBoolAt sets a boolean (bit) within a byte at bit position without changing the other bits it returns the resulted byte

func (*Helper) SetCharsAt

func (s7 *Helper) SetCharsAt(buffer []byte, pos int, value string)

SetCharsAt Get Array of char (S7 ARRAY OF CHARS)

func (*Helper) SetCounterAt

func (s7 *Helper) SetCounterAt(buffer []uint16, pos int, value int) []uint16

SetCounterAt set a counter at a postion

func (*Helper) SetDTLAt

func (s7 *Helper) SetDTLAt(buffer []byte, pos int, value time.Time) []byte

SetDTLAt DTL (S71200/1500 Date and Time)

func (*Helper) SetDateAt

func (s7 *Helper) SetDateAt(buffer []byte, pos int, value time.Time)

SetDateAt DATE (S7 DATE)

func (*Helper) SetDateTimeAt

func (s7 *Helper) SetDateTimeAt(buffer []byte, pos int, value time.Time)

SetDateTimeAt DateTime (S7 DATE_AND_TIME)

func (*Helper) SetLDTAt

func (s7 *Helper) SetLDTAt(buffer []byte, pos int, value time.Time)

SetLDTAt LDT (S7 1500 Long Date and Time)

func (*Helper) SetLRealAt

func (s7 *Helper) SetLRealAt(Buffer []byte, Pos int, Value float64)

SetLRealAt 64 bit floating point number (S7 LReal) (Range of float64)

func (*Helper) SetLTODAt

func (s7 *Helper) SetLTODAt(buffer []byte, pos int, value time.Time)

SetLTODAt LTOD (S7 1500 LONG TIME_OF_DAY)

func (*Helper) SetRealAt

func (s7 *Helper) SetRealAt(buffer []byte, pos int, value float32)

SetRealAt 32 bit floating point number (S7 Real) (Range of float32)

func (*Helper) SetS5TimeAt

func (s7 *Helper) SetS5TimeAt(buffer []byte, pos int, value time.Duration) []byte

SetS5TimeAt Set S5Time

func (*Helper) SetStringAt

func (s7 *Helper) SetStringAt(buffer []byte, pos int, maxLen int, value string) []byte

SetStringAt Set String (S7 String)

func (*Helper) SetTODAt

func (s7 *Helper) SetTODAt(buffer []byte, pos int, value time.Time)

SetTODAt TOD (S7 TIME_OF_DAY)

func (*Helper) SetValueAt

func (s7 *Helper) SetValueAt(buffer []byte, pos int, data interface{})

SetValueAt set a value at a position of a byte array, which based on builtin function: https://golang.org/pkg/encoding/binary/#Read

func (*Helper) SetWStringAt

func (s7 *Helper) SetWStringAt(buffer []byte, pos int, maxLen int, value string) []byte

SetWStringAt Set String (WString)

func (*Helper) ToCounter

func (s7 *Helper) ToCounter(value int) uint16

ToCounter convert value to s7

type Packager

type Packager interface {
	//reserve for future use
	Verify(request []byte, response []byte) (err error)
}

Packager specifies the communication layer.

type ProtocolDataUnit

type ProtocolDataUnit struct {
	Data []byte
}

ProtocolDataUnit (PDU) is independent of underlying communication layers.

func NewProtocolDataUnit

func NewProtocolDataUnit(data []byte) ProtocolDataUnit

NewProtocolDataUnit ProtocolDataUnit Constructor

type S7BlockInfo

type S7BlockInfo struct {
	BlkType   int
	BlkNumber int
	BlkLang   int
	BlkFlags  int
	MC7Size   int // The real size in bytes
	LoadSize  int
	LocalData int
	SBBLength int
	CheckSum  int
	Version   int
	// Chars info
	CodeDate string
	IntfDate string
	Author   string
	Family   string
	Header   string
}

S7BlockInfo Managed Block Info

type S7BlocksList

type S7BlocksList struct {
	OBList  []int
	FBList  []int
	FCList  []int
	SFBList []int
	SFCList []int
	DBList  []int
	SDBList []int
}

S7BlocksList Block List

type S7CpInfo

type S7CpInfo struct {
	MaxPduLength   int
	MaxConnections int
	MaxMpiRate     int
	MaxBusRate     int
}

S7CpInfo cp info

type S7CpuInfo

type S7CpuInfo struct {
	ModuleTypeName string
	SerialNumber   string
	ASName         string
	Copyright      string
	ModuleName     string
}

S7CpuInfo CPU Info

type S7DataItem

type S7DataItem struct {
	Area     int
	WordLen  int
	DBNumber int
	Start    int
	Bit      int
	Amount   int
	Data     []byte
	Error    string
}

S7DataItem which expose as S7DataItem to use in Multiple read/write

type S7DataItemWithResponse

type S7DataItemWithResponse struct {
	Area     int
	WordLen  int
	DBNumber int
	Start    int
	Bit      int
	Amount   int
	Id       string
	Params   interface{}
	OnData   func(string, []byte, interface{})
	OnError  func(string, string)
}

S7DataItem which expose as S7DataItem to use in Multiple read/write

type S7Error

type S7Error struct {
	High byte
	Low  byte
}

S7Error implements error interface.

func (*S7Error) Error

func (e *S7Error) Error() string

Error converts known s7 exception code to error message.

type S7OrderCode

type S7OrderCode struct {
	Code string // such as "6ES7 151-8AB01-0AB0"
	V1   byte   // Version 1st digit
	V2   byte   // Version 2nd digit
	V3   byte   // Version 3th digit
}

S7OrderCode Order Code + Version

type S7Protection

type S7Protection struct {
	// contains filtered or unexported fields
}

S7Protection See §33.19 of "System Software for S7-300/400 System and Standard Functions"

type S7SZL

type S7SZL struct {
	Header SZLHeader
	Data   []byte
}

S7SZL constains header and data

type S7SZLList

type S7SZLList struct {
	Header SZLHeader
	Data   []uint16
}

S7SZLList of available SZL IDs : same as SZL but List items are big-endian adjusted

type SZLHeader

type SZLHeader struct {
	LengthHeader       uint16
	NumberOfDataRecord uint16
}

SZLHeader See §33.1 of "System Software for S7-300/400 System and Standard Functions" and see SFC51 description too

type TCPClientHandler

type TCPClientHandler struct {
	// contains filtered or unexported fields
}

TCPClientHandler implements Packager and Transporter interface.

func NewTCPClientHandler

func NewTCPClientHandler(address string, rack int, slot int) *TCPClientHandler

NewTCPClientHandler allocates a new TCPClientHandler.

func (*TCPClientHandler) Close

func (mb *TCPClientHandler) Close() error

Close closes current connection.

func (*TCPClientHandler) Connect

func (mb *TCPClientHandler) Connect() error

Connect establishes a new connection to the address in Address. Connect and Close are exported so that multiple requests can be done with one session

func (*TCPClientHandler) Send

func (mb *TCPClientHandler) Send(request []byte) (response []byte, err error)

Send sends data to server and ensures response length is greater than header length.

func (*TCPClientHandler) Verify

func (mb *TCPClientHandler) Verify(request []byte, response []byte) (err error)

reserve for future use, need to verify the request and response

type Transporter

type Transporter interface {
	Send(request []byte) (response []byte, err error)
}

Transporter specifies the transport layer.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL