ads

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 18 Imported by: 0

README

go-ads

A pure Go library for communicating with Beckhoff TwinCAT PLCs using the ADS (Automation Device Specification) protocol.

Features

  • Connect to TwinCAT 2 and TwinCAT 3 PLCs over TCP
  • Read/write PLC symbols by name
  • Batch read multiple symbols in a single round-trip (SumRead)
  • Subscribe to symbol change notifications (single and batch)
  • Automatic symbol table and datatype discovery
  • Auto-reconnect with notification re-subscribe
  • Symbol version change detection and refresh

Install

go get github.com/RuneRoven/go-ads

Quick start

package main

import (
	"context"
	"fmt"
	"time"

	ads "github.com/RuneRoven/go-ads"
)

func main() {
	ctx := context.Background()
	conn, _ := ads.NewConnection(ctx, "192.168.1.100", 48898, "5.1.2.3.1.1", 851, "auto", 10500, 5*time.Second)
	conn.Connect(false)
	defer conn.Close()

	info, _ := conn.ReadDeviceInfo()
	fmt.Printf("Device: %s\n", string(info.DeviceName[:]))

	// Symbols are resolved on-demand — no full discovery needed
	value, _ := conn.ReadFromSymbol("MAIN.myVar")
	fmt.Println("Value:", value)

	// Optional: load full symbol table for listing/struct access
	conn.LoadSymbols()
	symbols, _ := conn.ListSymbols()
	fmt.Printf("Total symbols: %d\n", len(symbols))
}

Example CLI

A ready-to-run example is included:

cd examples/simple
go run . -ip 192.168.1.100 -netid 5.1.2.3.1.1 -list

See examples/simple/main.go for all available flags.

Development

Prerequisites
Before pushing

Run all checks locally — this mirrors what CI does on every PR:

make all        # format, lint, vet, test

Or run individual targets:

make fmt        # format code (gofumpt + goimports)
make lint       # run golangci-lint
make vet        # run go vet
make test       # run tests
make test-race  # run tests with race detector
make test-cover # run tests with coverage report
make build      # build all packages
CI

CI runs automatically on pull requests to main with 4 parallel jobs: lint, test, test-race, and build. All must pass before merging.

License

MIT — see LICENSE for details.

Original ADS protocol implementation based on go-native-ads by Bob Klosinski.

Documentation

Index

Constants

View Source
const ReturnCodeErrorOffset = 0x0700

ReturnCodeErrorOffset General ADS errors begin at this offset

Variables

View Source
var ErrDisconnected = fmt.Errorf("connection is disconnected")

ErrDisconnected is returned when attempting to send on a closed connection.

Functions

func AddRemoteRoute

func AddRemoteRoute(remoteHost string, localNetId [6]byte, routeName string, computerName string, username string, password string) error

AddRemoteRoute registers a route on the remote PLC via the Beckhoff UDP protocol (port 48899). This tells the PLC how to reach this client's AmsNetId.

Parameters:

  • remoteHost: IP or hostname of the PLC
  • localNetId: the AMS NetID this client will use as source
  • routeName: name for the route entry on the PLC
  • computerName: the IP/hostname the PLC should use to connect back to this client
  • username: PLC admin username (typically "Administrator")
  • password: PLC admin password

func ParseUploadSymbolInfoDataTypes

func ParseUploadSymbolInfoDataTypes(data []byte) (datatypes map[string]SymbolUploadDataType, err error)

func ParseUploadSymbolInfoSymbols

func ParseUploadSymbolInfoSymbols(data []byte, datatypes map[string]SymbolUploadDataType) (symbols map[string]*Symbol, err error)

func StringToNetID

func StringToNetID(source string) ([6]byte, error)

StringToNetID converts a dotted notation NetID string (e.g. "192.168.1.1.1.1") to a 6-byte array. Returns an error if the string is malformed (wrong number of parts or non-numeric values).

Types

type AdsState

type AdsState uint16
const (
	AdsStateInvalid      AdsState = 0
	AdsStateIdle         AdsState = 1
	AdsStateReset        AdsState = 2
	AdsStateInit         AdsState = 3
	AdsStateStart        AdsState = 4
	AdsStateRun          AdsState = 5
	AdsStateStop         AdsState = 6
	AdsStateSaveCfg      AdsState = 7
	AdsStateLoadCfg      AdsState = 8
	AdsStatePowerFailure AdsState = 9
	AdsStatePowerGood    AdsState = 10
	AdsStateError        AdsState = 11
	AdsStateShutdown     AdsState = 12
	AdsStateSuspend      AdsState = 13
	AdsStateResume       AdsState = 14
	AdsStateConfig       AdsState = 15 // System Is In Config Mode
	AdsStateReconfig     AdsState = 16 // System Should Restart In Config Mode
	AdsStateMaxStates    AdsState = 255
)

type AmsAddress

type AmsAddress struct {
	NetID [6]byte
	Port  uint16
}

AMSAddress netid and port of device

type CommandID

type CommandID uint16

CommandID Ads Command IDS

const (
	CommandIDInValueID CommandID = iota
	CommandIDReadDeviceInfo
	CommandIDRead
	CommandIDWrite
	CommandIDReadState
	CommandIDWriteControl
	CommandIDAddDeviceNotification
	CommandIDDeleteDeviceNotification
	CommandIDDeviceNotification
	CommandIDReadWrite
)

type Connection

type Connection struct {
	RequestTimeout time.Duration
	// contains filtered or unexported fields
}

func NewConnection

func NewConnection(ctx context.Context, ip string, port int, netid string, amsPort int, localNetID string, localPort int, requestTimeout time.Duration) (conn *Connection, err error)

NewConnection creates a new ADS connection. requestTimeout is the timeout for individual ADS requests. If requestTimeout is 0, a default of 5000ms is used.

func (*Connection) AddDeviceNotification

func (conn *Connection) AddDeviceNotification(
	group uint32,
	offset uint32,
	length uint32,
	transmissionMode TransMode,
	maxDelay time.Duration,
	cycleTime time.Duration,
) (handle uint32, err error)

func (*Connection) AddSymbolNotification

func (conn *Connection) AddSymbolNotification(symbolName string, maxDelay int, cycleTime int, transMode TransMode, updateReceiver chan *Update) (uint32, error)

AddSymbolNotification registers a notification for a single symbol. Note: all notifications must share the same updateReceiver channel. On reconnect, the stored channel is used to re-subscribe all notifications. For multiple notifications, prefer AddSymbolNotifications.

func (*Connection) AddSymbolNotifications

func (conn *Connection) AddSymbolNotifications(configs []NotificationConfig, ch chan *Update) error

AddSymbolNotifications adds multiple symbol notifications in a single ADS round-trip using SumAddDeviceNotification.

func (*Connection) BrowseSymbols added in v1.1.0

func (conn *Connection) BrowseSymbols(path string) ([]SymbolBrowseEntry, error)

BrowseSymbols returns browsable entries at the given path in the symbol hierarchy. If path is empty, returns root-level groupings (first path segments). If path is specified, returns children of that symbol or prefix. Requires LoadSymbolList() or LoadSymbols() to have been called first.

func (*Connection) CheckSymbolVersion

func (conn *Connection) CheckSymbolVersion() (changed bool, err error)

CheckSymbolVersion compares the current PLC symbol version against the stored version. Returns true if the version has changed.

func (*Connection) Close

func (conn *Connection) Close()

Close closes connection and waits for completion

func (*Connection) Connect

func (conn *Connection) Connect(local bool) error

func (*Connection) DeleteDeviceNotification

func (conn *Connection) DeleteDeviceNotification(handle uint32) error

DeleteDeviceNotification deletes a device notification by handle.

func (*Connection) DeviceNotification

func (conn *Connection) DeviceNotification(ctx context.Context, in []byte) error

DeviceNotification - ADS command id: 8

func (*Connection) GetHandleByName

func (conn *Connection) GetHandleByName(symbolName string) (handle uint32, err error)

func (*Connection) GetSymbol

func (conn *Connection) GetSymbol(symbolName string) (*Symbol, error)

func (*Connection) GetSymbolUploadInfo

func (conn *Connection) GetSymbolUploadInfo() (uploadInfo SymbolUploadInfo, err error)

func (*Connection) GetSymbolVersion

func (conn *Connection) GetSymbolVersion() (uint32, error)

GetSymbolVersion reads the current symbol version from the PLC.

func (*Connection) GetUploadSymbolInfoDataTypes

func (conn *Connection) GetUploadSymbolInfoDataTypes(length uint32) (data []byte, err error)

func (*Connection) GetUploadSymbolInfoSymbols

func (conn *Connection) GetUploadSymbolInfoSymbols(length uint32) (data []byte, err error)

func (*Connection) IsDisconnected

func (conn *Connection) IsDisconnected() bool

IsDisconnected returns whether the connection is currently in a disconnected state.

func (*Connection) ListSymbols

func (conn *Connection) ListSymbols() (map[string]*Symbol, error)

ListSymbols returns the full symbol table. Requires LoadSymbols() or LoadSymbolsSlow() to have been called first. Returns an error if full discovery has not been performed.

func (*Connection) LoadDataTypes added in v1.1.0

func (conn *Connection) LoadDataTypes(cfg SlowDiscoveryConfig) error

LoadDataTypes downloads only the datatype table (0xF00E) from the PLC in chunks. After calling this along with LoadSymbolList(), struct/array children can be browsed and expanded via BrowseSymbols().

func (*Connection) LoadSymbolList added in v1.1.0

func (conn *Connection) LoadSymbolList(cfg SlowDiscoveryConfig) error

LoadSymbolList downloads only the symbol table (0xF00B) from the PLC in chunks. This is the smaller of the two tables and enables browsing top-level symbol names. After calling this, BrowseSymbols() can list root symbols and navigate by prefix. To also expand struct/array children, call LoadDataTypes() afterwards.

func (*Connection) LoadSymbols added in v1.1.0

func (conn *Connection) LoadSymbols() error

LoadSymbols performs full symbol and datatype discovery from the PLC. After calling this, ListSymbols() returns all symbols, and struct/array children are available. Write operations with type aliases also work. This downloads the entire symbol and datatype tables in single requests, which may cause real-time jitter on the PLC. For large programs, consider LoadSymbolsSlow() instead.

func (*Connection) LoadSymbolsSlow added in v1.1.0

func (conn *Connection) LoadSymbolsSlow(cfg SlowDiscoveryConfig) error

LoadSymbolsSlow downloads the full symbol table in chunks with delays between each chunk, to minimize disruption to the PLC's real-time task. If the PLC does not support offset-based chunked reads, it falls back to downloading each table in a single request with a delay between them.

func (*Connection) Read

func (conn *Connection) Read(group uint32, offset uint32, length uint32) (data []byte, err error)

func (*Connection) ReadDeviceInfo

func (conn *Connection) ReadDeviceInfo() (response DeviceInfo, err error)

func (*Connection) ReadFromSymbol

func (conn *Connection) ReadFromSymbol(symbolName string) (string, error)

func (*Connection) ReadMultipleSymbols

func (conn *Connection) ReadMultipleSymbols(names []string) (map[string]string, error)

ReadMultipleSymbols reads multiple symbols in a single ADS round-trip using SumRead. Returns a map of symbol name to parsed string value.

func (*Connection) ReadState

func (conn *Connection) ReadState() (response States, err error)

func (*Connection) Reconnect

func (conn *Connection) Reconnect() error

Reconnect attempts to re-establish the TCP connection, reload symbols, and re-subscribe to previously registered notifications.

func (*Connection) RefreshSymbols

func (conn *Connection) RefreshSymbols() error

RefreshSymbols reloads the symbol table if the symbol version has changed. It releases old handles, reloads symbol/datatype tables, and re-acquires handles for active symbols.

func (*Connection) SumAddDeviceNotification

func (conn *Connection) SumAddDeviceNotification(requests []SumNotificationRequest) (handles []uint32, errors []ReturnCode, err error)

SumAddDeviceNotification adds multiple device notifications in a single ADS round-trip using GroupSumupAddDeviceNotification (0xF085). Falls back to individual AddDeviceNotification calls on older PLCs.

func (*Connection) SumDeleteDeviceNotification

func (conn *Connection) SumDeleteDeviceNotification(handles []uint32) ([]ReturnCode, error)

SumDeleteDeviceNotification deletes multiple device notifications in a single ADS round-trip using GroupSumupDeleteDeviceNotification (0xF086). Falls back to individual DeleteDeviceNotification calls on older PLCs.

func (*Connection) SumRead

func (conn *Connection) SumRead(requests []SumReadRequest) ([]SumReadResult, error)

SumRead performs a batch read using GroupSumupReadEx2 (0xF084). This reads multiple index group/offset/length combinations in a single ADS round-trip. If the sum command fails (e.g. on older PLCs), it falls back to individual reads.

func (*Connection) SumWrite added in v1.1.0

func (conn *Connection) SumWrite(requests []SumWriteRequest) ([]SumWriteResult, error)

SumWrite performs a batch write using GroupSumupWrite (0xF081). This writes multiple index group/offset combinations in a single ADS round-trip. If the sum command fails (e.g. on older PLCs), it falls back to individual writes.

func (*Connection) Write

func (conn *Connection) Write(group uint32, offset uint32, data []byte) error

Write - ADS command id: 3

func (*Connection) WriteMultipleSymbols added in v1.1.0

func (conn *Connection) WriteMultipleSymbols(values map[string]string) (map[string]ReturnCode, error)

WriteMultipleSymbols writes multiple symbols in a single ADS round-trip using SumWrite. Returns a map of symbol name to per-symbol error code. Uses direct iGroup/iOffs addressing when available (after LoadSymbols), falling back to handle-based addressing for on-demand symbols.

func (*Connection) WriteRead

func (conn *Connection) WriteRead(group uint32, offset uint32, readLength uint32, send []byte) (data []byte, err error)

func (*Connection) WriteToSymbol

func (conn *Connection) WriteToSymbol(symbolName string, value string) error

type DeviceInfo

type DeviceInfo struct {
	Major      uint8
	Minor      uint8
	Version    uint16
	DeviceName [16]byte
}

DeviceInfo connected device info

type Group

type Group uint32

Group reserved index groups

const (
	GroupSymbolTab   Group = 0xf000
	GroupSymbolName  Group = 0xf001
	GroupSymbolValue Group = 0xf002

	GroupSymbolHandleByName  Group = 0xF003
	GroupSymbolValueByName   Group = 0xF004
	GroupSymbolValueByHandle Group = 0xF005
	GroupSymbolReleaseHandle Group = 0xF006
	GroupSymbolInfoByName    Group = 0xF007
	GroupSymbolVersion       Group = 0xF008
	GroupSymbolInfoByNameEx  Group = 0xF009

	GroupSymbolDownload       Group = 0xF00A
	GroupSymbolUpload         Group = 0xF00B
	GroupSymbolUploadInfo     Group = 0xF00C
	GroupSymbolDownload2      Group = 0xF00D
	GroupSymbolDataTypeUpload Group = 0xF00E
	GroupSymbolUploadInfo2    Group = 0xF00F

	GroupSymbolNotification Group = 0xf010 // notification of named handle

	GroupSumupRead                     Group = 0xF080
	GroupSumupWrite                    Group = 0xF081
	GroupSumupReadWrite                Group = 0xF082
	GroupSumupReadEx                   Group = 0xF083
	GroupSumupReadEx2                  Group = 0xF084
	GroupSumupAddDeviceNotification    Group = 0xF085
	GroupSumupDeleteDeviceNotification Group = 0xF086

	GroupIoImageRwib   Group = 0xF020 // read/write input byte(s)
	GroupIoImageRwix   Group = 0xF021 // read/write input bit
	GroupIoImageRisize Group = 0xF025 // read input size (in byte)
	GroupIoImageRwob   Group = 0xF030 // read/write output byte(s)
	GroupIoImageRwox   Group = 0xF031 // read/write output bit
	GroupIoImageCleari Group = 0xF040 // write inputs to null
	GroupIoImageClearo Group = 0xF050 // write outputs to null
	GroupIoImageRwiob  Group = 0xF060 // read input and write output byte(s)

	GroupDeviceData Group = 0xF100 // state, name, etc...
)

type NotificationConfig

type NotificationConfig struct {
	SymbolName       string
	MaxDelay         int
	CycleTime        int
	TransmissionMode TransMode
}

NotificationConfig holds configuration for a symbol notification, used for batch add and reconnect re-subscribe.

type NotificationSample

type NotificationSample struct {
	Handle uint32
	Size   uint32
}

type NotificationStream

type NotificationStream struct {
	Length uint32
	Stamps uint32
}

type Offset

type Offset uint32
const (
	OffsetDeviceDataAdsState    Offset = 0x0000 // ads state of device
	OffsetDeviceDataDeviceState Offset = 0x0002 // device state
)

type Port

type Port uint32

Port default twincat ports

const (
	PortLogger    Port = 100
	PortR0Rtime   Port = 200
	PortR0Trace   Port = (PortR0Rtime + 90)
	PortR0Io      Port = 300
	PortR0Sps     Port = 400
	PortR0Nc      Port = 500
	PortR0Isg     Port = 550
	PortR0Pcs     Port = 600
	PortR0Plc     Port = 801
	PortR0PlcRts1 Port = 801
	PortR0PlcRts2 Port = 811
	PortR0PlcRts3 Port = 821
	PortR0PlcRts4 Port = 831
	PortR0PlcTc3  Port = 851
)

type ReturnCode

type ReturnCode uint32

ReturnCode ADS Return codes

const (
	ReturnCodeNoErrors ReturnCode = 0x00

	// Global error codes (0x01 - 0x1E)
	ReturnCodeGlobalInternalError       ReturnCode = 0x01
	ReturnCodeGlobalNoRtime             ReturnCode = 0x02
	ReturnCodeGlobalAllocLockedMemError ReturnCode = 0x03
	ReturnCodeGlobalInsertMailboxError  ReturnCode = 0x04
	ReturnCodeGlobalWrongReceiveHmsg    ReturnCode = 0x05
	ReturnCodeGlobalTargetPortNotFound  ReturnCode = 0x06
	ReturnCodeGlobalTargetNotFound      ReturnCode = 0x07
	ReturnCodeGlobalUnknownCommandID    ReturnCode = 0x08
	ReturnCodeGlobalBadTaskID           ReturnCode = 0x09
	ReturnCodeGlobalNoIO                ReturnCode = 0x0A
	ReturnCodeGlobalUnknownAdsCommand   ReturnCode = 0x0B
	ReturnCodeGlobalWin32Error          ReturnCode = 0x0C
	ReturnCodeGlobalPortNotConnected    ReturnCode = 0x0D
	ReturnCodeGlobalInvalidAdsLength    ReturnCode = 0x0E
	ReturnCodeGlobalInvalidAmsNetID     ReturnCode = 0x0F
	ReturnCodeGlobalLowInstallLevel     ReturnCode = 0x10
	ReturnCodeGlobalNoDebugAvailable    ReturnCode = 0x11
	ReturnCodeGlobalPortDisabled        ReturnCode = 0x12
	ReturnCodeGlobalPortAlreadyConn     ReturnCode = 0x13
	ReturnCodeGlobalAdsSyncW32Error     ReturnCode = 0x14
	ReturnCodeGlobalAdsSyncTimeout      ReturnCode = 0x15
	ReturnCodeGlobalAdsSyncAmsError     ReturnCode = 0x16
	ReturnCodeGlobalAdsSyncNoIndexMap   ReturnCode = 0x17
	ReturnCodeGlobalInvalidAdsPort      ReturnCode = 0x18
	ReturnCodeGlobalNoMemory            ReturnCode = 0x19
	ReturnCodeGlobalTcpSendError        ReturnCode = 0x1A
	ReturnCodeGlobalHostUnreachable     ReturnCode = 0x1B
	ReturnCodeGlobalInvalidAmsFragment  ReturnCode = 0x1C
	ReturnCodeGlobalTlsSendError        ReturnCode = 0x1D
	ReturnCodeGlobalAccessDenied        ReturnCode = 0x1E

	// Router error codes (0x500 - 0x50D)
	ReturnCodeRouterNoLockedMemory   ReturnCode = 0x500
	ReturnCodeRouterResizeMemory     ReturnCode = 0x501
	ReturnCodeRouterMailboxFull      ReturnCode = 0x502
	ReturnCodeRouterDebugBoxFull     ReturnCode = 0x503
	ReturnCodeRouterUnknownPortType  ReturnCode = 0x504
	ReturnCodeRouterNotInitialized   ReturnCode = 0x505
	ReturnCodeRouterPortAlreadyInUse ReturnCode = 0x506
	ReturnCodeRouterNotRegistered    ReturnCode = 0x507
	ReturnCodeRouterNoMoreQueues     ReturnCode = 0x508
	ReturnCodeRouterInvalidPort      ReturnCode = 0x509
	ReturnCodeRouterNotActivated     ReturnCode = 0x50A
	ReturnCodeRouterFragmentBoxFull  ReturnCode = 0x50B
	ReturnCodeRouterFragmentTimeout  ReturnCode = 0x50C
	ReturnCodeRouterToBeRemoved      ReturnCode = 0x50D

	// General ADS error codes (0x700 - 0x739)
	ReturnCodeDeviceError                 ReturnCode = (0x00 + ReturnCodeErrorOffset)
	ReturnCodeDeviceServiceNotSupported   ReturnCode = (0x01 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidGroup          ReturnCode = (0x02 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidOffset         ReturnCode = (0x03 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidAccess         ReturnCode = (0x04 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidSize           ReturnCode = (0x05 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidData           ReturnCode = (0x06 + ReturnCodeErrorOffset)
	ReturnCodeDeviceNotReady              ReturnCode = (0x07 + ReturnCodeErrorOffset)
	ReturnCodeDeviceBusy                  ReturnCode = (0x08 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidContext        ReturnCode = (0x09 + ReturnCodeErrorOffset)
	ReturnCodeDeviceNoMemory              ReturnCode = (0x0A + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidParam          ReturnCode = (0x0B + ReturnCodeErrorOffset)
	ReturnCodeDeviceNotFound              ReturnCode = (0x0C + ReturnCodeErrorOffset)
	ReturnCodeDeviceSyntax                ReturnCode = (0x0D + ReturnCodeErrorOffset)
	ReturnCodeDeviceIncompatible          ReturnCode = (0x0E + ReturnCodeErrorOffset)
	ReturnCodeDeviceExists                ReturnCode = (0x0F + ReturnCodeErrorOffset)
	ReturnCodeDeviceSymbolNoFound         ReturnCode = (0x10 + ReturnCodeErrorOffset)
	ReturnCodeDeviceSymbolVersionInvalid  ReturnCode = (0x11 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidState          ReturnCode = (0x12 + ReturnCodeErrorOffset)
	ReturnCodeDeviceTransModeNotSupported ReturnCode = (0x13 + ReturnCodeErrorOffset)
	ReturnCodeDeviceNotifyHandleInvalid   ReturnCode = (0x14 + ReturnCodeErrorOffset)
	ReturnCodeDeviceClientUnknown         ReturnCode = (0x15 + ReturnCodeErrorOffset)
	ReturnCodeDeviceNoMoreHandles         ReturnCode = (0x16 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidWatchSize      ReturnCode = (0x17 + ReturnCodeErrorOffset)
	ReturnCodeDeviceNotInitialized        ReturnCode = (0x18 + ReturnCodeErrorOffset)
	ReturnCodeDeviceTimeout               ReturnCode = (0x19 + ReturnCodeErrorOffset)
	ReturnCodeDeviceNoInterface           ReturnCode = (0x1A + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidInterface      ReturnCode = (0x1B + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidClsID          ReturnCode = (0x1C + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidObjID          ReturnCode = (0x1D + ReturnCodeErrorOffset)
	ReturnCodeDevicePending               ReturnCode = (0x1E + ReturnCodeErrorOffset)
	ReturnCodeDeviceAborted               ReturnCode = (0x1F + ReturnCodeErrorOffset)
	ReturnCodeDeviceWarning               ReturnCode = (0x20 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidArrayIndex     ReturnCode = (0x21 + ReturnCodeErrorOffset)
	ReturnCodeDeviceSymbolNotActive       ReturnCode = (0x22 + ReturnCodeErrorOffset)
	ReturnCodeDeviceAccessDenied          ReturnCode = (0x23 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseNotFound       ReturnCode = (0x24 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseExpired        ReturnCode = (0x25 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseExceeded       ReturnCode = (0x26 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseInvalid        ReturnCode = (0x27 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseSystemID       ReturnCode = (0x28 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseNoTimeLimit    ReturnCode = (0x29 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseFutureIssue    ReturnCode = (0x2A + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseTimeToLong     ReturnCode = (0x2B + ReturnCodeErrorOffset)
	ReturnCodeDeviceException             ReturnCode = (0x2C + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseDuplicated     ReturnCode = (0x2D + ReturnCodeErrorOffset)
	ReturnCodeDeviceSignatureInvalid      ReturnCode = (0x2E + ReturnCodeErrorOffset)
	ReturnCodeDeviceCertificateInvalid    ReturnCode = (0x2F + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseOemNotFound    ReturnCode = (0x30 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseRestricted     ReturnCode = (0x31 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicenseDemoDenied     ReturnCode = (0x32 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidFuncID         ReturnCode = (0x33 + ReturnCodeErrorOffset)
	ReturnCodeDeviceOutOfRange            ReturnCode = (0x34 + ReturnCodeErrorOffset)
	ReturnCodeDeviceInvalidAlignment      ReturnCode = (0x35 + ReturnCodeErrorOffset)
	ReturnCodeDeviceLicensePlatform       ReturnCode = (0x36 + ReturnCodeErrorOffset)
	ReturnCodeDeviceForwardPL             ReturnCode = (0x37 + ReturnCodeErrorOffset)
	ReturnCodeDeviceForwardDL             ReturnCode = (0x38 + ReturnCodeErrorOffset)
	ReturnCodeDeviceForwardRT             ReturnCode = (0x39 + ReturnCodeErrorOffset)

	// Client error codes (0x740 - 0x756)
	ReturnCodeClientError               ReturnCode = (0x40 + ReturnCodeErrorOffset)
	ReturnCodeClientInvalidParameter    ReturnCode = (0x41 + ReturnCodeErrorOffset)
	ReturnCodeClientListEmpty           ReturnCode = (0x42 + ReturnCodeErrorOffset)
	ReturnCodeClientVarUsed             ReturnCode = (0x43 + ReturnCodeErrorOffset)
	ReturnCodeClientDuplicateInvokeID   ReturnCode = (0x44 + ReturnCodeErrorOffset)
	ReturnCodeClientSyncTimeout         ReturnCode = (0x45 + ReturnCodeErrorOffset)
	ReturnCodeClientW32Error            ReturnCode = (0x46 + ReturnCodeErrorOffset)
	ReturnCodeClientTimeoutInvalid      ReturnCode = (0x47 + ReturnCodeErrorOffset)
	ReturnCodeClientPortNotOpen         ReturnCode = (0x48 + ReturnCodeErrorOffset)
	ReturnCodeClientNoAmsAddress        ReturnCode = (0x49 + ReturnCodeErrorOffset)
	ReturnCodeClientSyncInternal        ReturnCode = (0x50 + ReturnCodeErrorOffset)
	ReturnCodeClientAddHash             ReturnCode = (0x51 + ReturnCodeErrorOffset)
	ReturnCodeClientRemoveHash          ReturnCode = (0x52 + ReturnCodeErrorOffset)
	ReturnCodeClientNoMoreSymbols       ReturnCode = (0x53 + ReturnCodeErrorOffset)
	ReturnCodeClientSyncResponseInvalid ReturnCode = (0x54 + ReturnCodeErrorOffset)
	ReturnCodeClientSyncPortLocked      ReturnCode = (0x55 + ReturnCodeErrorOffset)
	ReturnCodeClientRequestCancelled    ReturnCode = (0x56 + ReturnCodeErrorOffset)

	// RTime error codes (0x1000 - 0x101A)
	ReturnCodeRTimeInternal            ReturnCode = 0x1000
	ReturnCodeRTimeBadTimerPeriods     ReturnCode = 0x1001
	ReturnCodeRTimeInvalidTaskPtr      ReturnCode = 0x1002
	ReturnCodeRTimeInvalidStackPtr     ReturnCode = 0x1003
	ReturnCodeRTimePrioExists          ReturnCode = 0x1004
	ReturnCodeRTimeNoMoreTcb           ReturnCode = 0x1005
	ReturnCodeRTimeNoMoreSemas         ReturnCode = 0x1006
	ReturnCodeRTimeNoMoreQueues        ReturnCode = 0x1007
	ReturnCodeRTimeExtIrqAlreadyDef    ReturnCode = 0x100D
	ReturnCodeRTimeExtIrqNotDef        ReturnCode = 0x100E
	ReturnCodeRTimeExtIrqInstallFailed ReturnCode = 0x100F
	ReturnCodeRTimeIrqlNotLessOrEqual  ReturnCode = 0x1010
	ReturnCodeRTimeVmxNotSupported     ReturnCode = 0x1017
	ReturnCodeRTimeVmxDisabled         ReturnCode = 0x1018
	ReturnCodeRTimeVmxControlsMissing  ReturnCode = 0x1019
	ReturnCodeRTimeVmxEnableFails      ReturnCode = 0x101A

	// TCP/Winsock error codes
	ReturnCodeWsaeTimedOut    ReturnCode = 0x274C
	ReturnCodeWsaeConnRefused ReturnCode = 0x274D
	ReturnCodeWsaeHostDown    ReturnCode = 0x2751
)

func (ReturnCode) Error

func (rc ReturnCode) Error() string

Error implements the error interface for ReturnCode, allowing it to be used directly as an error.

func (ReturnCode) String

func (rc ReturnCode) String() string

String returns a human-readable description of the ADS return code. For unknown codes, it returns the hex value.

type SlowDiscoveryConfig added in v1.1.0

type SlowDiscoveryConfig struct {
	// ChunkSize is the number of bytes to download per request.
	// Default: 4096 bytes.
	ChunkSize uint32

	// ChunkDelay is the delay between chunk requests, giving the PLC
	// time to handle its real-time tasks. Default: 100ms.
	ChunkDelay time.Duration
}

SlowDiscoveryConfig configures chunked symbol table download.

type StampHeader

type StampHeader struct {
	Timestamp uint64
	Samples   uint32
}

type States added in v1.1.0

type States struct {
	AdsState    AdsState
	DeviceState uint16
}

ReadStateResponse - ADS command id: 4 States holds the ADS and device state returned by ReadState.

type SumNotificationRequest

type SumNotificationRequest struct {
	Group            uint32
	Offset           uint32
	Length           uint32
	TransmissionMode TransMode
	MaxDelay         time.Duration
	CycleTime        time.Duration
}

SumNotificationRequest represents a single notification add request within a batch.

type SumReadRequest

type SumReadRequest struct {
	Group  uint32
	Offset uint32
	Length uint32
}

SumReadRequest represents a single read request within a sum/batch read.

type SumReadResult

type SumReadResult struct {
	Error ReturnCode
	Data  []byte
}

SumReadResult represents the result of a single read within a sum/batch read.

type SumWriteRequest added in v1.1.0

type SumWriteRequest struct {
	Group  uint32
	Offset uint32
	Data   []byte
}

SumWriteRequest represents a single write request within a sum/batch write.

type SumWriteResult added in v1.1.0

type SumWriteResult struct {
	Error ReturnCode
}

SumWriteResult represents the result of a single write within a sum/batch write.

type Symbol

type Symbol struct {
	FullName          string
	LastUpdateTime    time.Time
	MinUpdateInterval time.Duration
	Name              string
	DataType          string
	Comment           string
	Handle            uint32
	Group             uint32
	Offset            uint32
	Length            uint32
	Changed           bool

	Value       string
	Valid       bool
	ValueParsed bool // true after first successful parse

	Notification chan<- *Update

	Parent   *Symbol
	Children map[string]*Symbol
}

func (*Symbol) GetJSON

func (symbol *Symbol) GetJSON(onlyChanged bool) string

GetJSON (onlyChanged bool) string

type SymbolBrowseEntry added in v1.1.0

type SymbolBrowseEntry struct {
	Name        string // short name (e.g., "motor")
	FullName    string // full path (e.g., "MAIN.motor")
	DataType    string // type name (e.g., "ST_Motor", "INT")
	Size        uint32
	HasChildren bool // true if struct/array (requires LoadDataTypes to expand)
	Comment     string
}

SymbolBrowseEntry represents a browsable symbol or child.

type SymbolUploadDataType

type SymbolUploadDataType struct {
	DatatypeEntry datatypeEntry
	Name          string
	DataType      string
	Comment       string
	Children      map[string]*SymbolUploadDataType
}

type SymbolUploadInfo

type SymbolUploadInfo struct {
	SymbolCount    uint32
	SymbolLength   uint32
	DataTypeCount  uint32
	DataTypeLength uint32
	ExtraCount     uint32
	ExtraLength    uint32
}

type TransMode

type TransMode uint32

TransMode transmission mode for notifications

const (
	TransModeNoTransmission  TransMode = 0
	TransModeClientCycle     TransMode = 1
	TransModeClientOnChange  TransMode = 2
	TransModeServerCycle     TransMode = 3
	TransModeServerOnChange  TransMode = 4
	TransModeServerCycle2    TransMode = 5
	TransModeServerOnChange2 TransMode = 6
	TransModeClient1Request  TransMode = 10
)

func (TransMode) String

func (tm TransMode) String() string

String returns a human-readable name for the transmission mode.

type Update

type Update struct {
	Variable  string
	Value     string
	TimeStamp time.Time
}

Jump to

Keyboard shortcuts

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