Тема: AHK: Class Snap7 Client
Класс для удобной работы с библиотекой Snap7 в режиме клиента.
В прикрепленном архиве: файл класса, файлы DLL, простенький скрипт для теста.
/*
;Класс Snap7 - адаптация библиотеки Snap7 для Autohotkey.
;В классе реализованы все функции библиотеки в режиме клиента кроме асинхронных
;(смотри мануал для подробностей или комментарий рядом с нужной функцией)
;для работы класса требуются DLL файлы библиотеки snap7x64.dll, snap7x86.dll
;Как использовать:
;Необходимо создать объект
;Параметры создания объекта: (IP="",Rack=0,Slot=3,ConnectionType=0x02,AutoReconnect=true,ReconnectTime=10000)
; IP - указать IP контроллера к которому нужно подключиться
; Rack - указать Rack прописаный в конфигураторе железа в Step7
; Slot - указать Slot в котором стоит PLC
;Таблица из мануала
; Rack Slot
; S7 300 CPU 0 2 Always
; S7 400 CPU Not fixed Follow the hardware configuration.
; WinAC CPU Not fixed Follow the hardware configuration.
; S7 1200 CPU 0 0 Or 0, 1
; S7 1500 CPU 0 0 Or 0, 1
; CP 343 0 0 Or follow Hardware configuration.
; CP 443 Not fixed Follow the hardware configuration.
; WinAC IE 0 0 Or follow Hardware configuration.
; ConnectionType - тип подключения
; можно использовать переменные класса:
; Snap7.PG
; Snap7.OP
; Snap7.S7_Basic[1] .. Snap7.S7_Basic[14]
; AutoReconnect - использовать функцию автоматических попыток подключения в случае ошибок связи с PLC
; ReconnectTime - период автоматических попыток в миллисекундах
; Пример
s7Obj:=new Snap7("192.168.0.15", 0, 3, Snap7.OP, true, 10000)
; далее обращаясь к этому классу можно вызывать функции как описано в мануале
; за исключением того что не нужно указывать первый параметр во всех функциях (S7Object Client) он уже прописан в классе Snap7.
; Например:
s7Obj.Cli_GetConnected(Var)
msgbox,% "Cli_GetConnected = " Var
; Добавленны свои функции для удобства работы в autohotkey.
Var:=s7Obj.Connected ; возвращает текущее состояние подключения. 0 - не подключен, любое значение - подключен
msgbox,% "Connected = " Var
; Можно отключить\включить функцию автоподключения в любой момент
s7Obj.AutoReconnect:=true
; Также изменить период
s7Obj.ReconnectTime:=5000
; Поумолчанию включено обображение ошибок в виде отдельного окна
; чтобы выключить:
s7Obj.ShowErrors:=false
; в этом случае придется обрабатывать ошибки самостоятельно
; для этого предусмотренны свойства класса:
Var:=s7Obj.LastError ; возвращает номер последней ошибки при выполнении функций
msgbox,% "LastError = " Var
Var:=s7Obj.LastErrors ; возвращает массив из 3х элементов - разделяет ошибку на состовляющие
msgbox,% "TCP_IP_Error = " Var[1] ; TCP_IP_Error
msgbox,% "ISO_TCP_Error = " Var[2] ; ISO_TCP_Error
msgbox,% "Client_Error = " Var[3] ; Client_Error
Var:=s7Obj.LastErrorText ; возвращает полный текст ошибки с подробным описанием
msgbox,% "LastErrorText = `n`n" Var
Var:=s7Obj.Cli_LastErrorText ; возвращает текст ошибки предоставляемый самой библиотекой
msgbox,% "Cli_LastErrorText = " Var
; данную функцию можно вызывать напрямую из класса Snap7 без создания объекта
Snap7.Msg("Текст сообщения") ; выводит отдельное окно сообщения с указанным текстом
info:=s7Obj.GetOrderCode() ; упрощеный вариант стандартной функции библиотеки Cli_GetOrderCode
msgbox,% "Code = " info.Code
msgbox,% "V1 = " info.V1
msgbox,% "V2 = " info.V2
msgbox,% "V3 = " info.V3
msgbox,% "Version = " info.Version
info:=s7Obj.GetCpuInfo() ; упрощеный вариант стандартной функции библиотеки Cli_GetCpuInfo
msgbox,% "ModuleTypeName = " info.ModuleTypeName
msgbox,% "SerialNumber = " info.SerialNumber
msgbox,% "ASName = " info.ASName
msgbox,% "Copyright = " info.Copyright
msgbox,% "ModuleName = " info.ModuleName
info:=s7Obj.GetCpInfo() ; упрощеный вариант стандартной функции библиотеки Cli_GetCpInfo
msgbox,% "MaxPduLengt = " info.MaxPduLengt
msgbox,% "MaxConnections = " info.MaxConnections
msgbox,% "MaxMpiRate = " info.MaxMpiRate
msgbox,% "MaxBusRate = " info.MaxBusRate
varsetcapacity(Data,20,0x30) ; подготовка переменной для демонстрации следующих функций
numput(0x31,Data,4,"uchar")
numput(0x32,Data,5,"uchar")
numput(0x33,Data,6,"uchar")
numput(0x34,Data,7,"uchar")
; данную функцию можно вызывать напрямую из класса Snap7 без создания объекта
var:=Snap7.GetStr(Data,2,8) ; возвращает ASCII строку из памяти по указанному смещению
; Параметры (byref Data,Start,Size)
; Data - переменная из памяти которой брать строку
; Start - начальная позиция строки
; Size - количество символов
msgbox,% "GetStr = " var
; данную функцию можно вызывать напрямую из класса Snap7 без создания объекта
Snap7.SwapData(Data,4,4) ; разворачивает чередование байтов в памяти переменной по указанным координатам
; Параметры (byref pVar,Size,Offset=0)
; pVar - переменная в которой необходимо развернуть байты
; Size - размер в байтах
; Offset - начальная позиция в памяти
var:=Snap7.GetStr(Data,2,8)
msgbox,% "GetStr swapped = " var
Var:=s7Obj.DBRead(1,0,"Real") ; читает из DB контроллера по указанному адресу указанный тип данных
; Параметры (DBNumber,Start=0,DataType="Int")
; DBNumber - номер DB из которого читать данные
; Start - начальная позиция
; DataType - тип данных
; поддержываемые типы данных: Byte, Int, Word, DInt, DWord, Real
msgbox,% "DBRead = " var
Var:=s7Obj.DBWrite(12.34,1,0,"Real") ; пишет в DB контроллера по указанному адресу указанный тип данных
; Параметры (Value,DBNumber,Start=0,DataType="Int")
; Value - значение которое небходимо записать в DB
; DBNumber - номер DB в который писать данные
; Start - начальная позиция
; DataType - тип данных
; поддержываемые типы данных: Byte, Int, Word, DInt, DWord, Real
Var:=s7Obj.DBRead(1,0,"Real")
msgbox,% "DBRead after write = " var
*/
/*
Snap7 Reference manual
Administrative functions
These functions allow controlling the behavior a Client Object.
Function Purpose
Cli_Create Creates a Client Object.
Cli_Destroy Destroys a Client Object.
Cli_ConnectTo Connects a Client Object to a PLC.
Cli_SetConnectionType Sets the connection type (PG/OP/S7Basic)
Cli_ConnectionParamst Sets Address, Local and Remote TSAP for the connection.
Cli_Connect Connects a Client Object to a PLC with implicit parameters.
Cli_Disconnect Disconnects a Client.
Cli_GetParam Reads an internal Client parameter.
Cli_SetParam Writes an internal Client Parameter.
Data I/O functions
These functions allow the Client to exchange data with a PLC.
Function Purpose
Cli_ReadArea Reads a data area from a PLC.
Cli_WriteArea Writes a data area into a PLC.
Cli_DBRead Reads a part of a DB from a PLC.
Cli_DBWrite Writes a part of a DB into a PLC.
Cli_ABRead Reads a part of IPU area from a PLC.
Cli_ABWrite Writes a part of IPU area into a PLC.
Cli_EBRead Reads a part of IPI area from a PLC.
Cli_EBWrite Writes a part of IPI area into a PLC.
Cli_MBRead Reads a part of Merkers area from a PLC.
Cli_MBWrite Writes a part of Merkers area into a PLC.
Cli_TMRead Reads timers from a PLC.
Cli_TMWrite Write timers into a PLC.
Cli_CTRead Reads counters from a PLC.
Cli_CTWrite Write counters into a PLC.
Cli_ReadMultiVars Reads different kind of variables from a PLC simultaneously.
Cli_WriteMultiVars Writes different kind of variables into a PLC simultaneously.
Directory functions
These functions give you detailed information about the blocks present in a PLC.
Function Purpose
Cli_ListBlocks Returns the AG blocks amount divided by type.
Cli_ListBlocksOfType Returns the AG blocks list of a given type.
Cli_GetAgBlockInfo Returns detailed information about a block present in AG.
Cli_GetPgBlockInfo Returns detailed information about a block loaded in memory.
Block oriented functions
Function Purpose
Cli_FullUpload Uploads a block from AG with Header and Footer infos.
Cli_Upload Uploads a block from AG.
Cli_Download Download a block into AG.
Cli_Delete Delete a block into AG.
Cli_DBGet Uploads a DB from AG using DBRead.
Cli_DBFill Fills a DB in AG with a given byte.
Date/Time functions
These functions allow to read/modify the date and time of a PLC.
Imagine a production line in which each PLC saves the data with date/time field inside,
it is very important that the date be up to date.
Both CP X43 and internal PN allow to synchronize date and time but you need an NTP
server, and in some cases (old hardware or CP343-1 Lean or old firmware release)
this doesn’t work properly.
Snap7 Client, using the same method of S7 Manager, always works.
Function Purpose
Cli_GetPlcDateTime Returns the PLC date/time.
Cli_SetPlcDateTime Sets the PLC date/time with a given value.
Cli_SetPlcSystemDateTime Sets the PLC date/time with the host (PC) date/time.
System info functions
these functions access to SZL ( or SSL - System Status List) to give you all the same
information that you can get from S7 Manager.
Function Purpose
Cli_ReadSZL Reads a partial list of given ID and Index.
Cli_ReadSZLList Reads the list of partial lists available in the CPU.
Cli_GetOrderCode Returns the CPU order code.
Cli_GetCpuInfo Returns some information about the AG.
Cli_GetCpInfo Returns some information about the CP (communication processor).
PLC control functions
With these control function it’s possible to Start/Stop a CPU and perform some other
maintenance tasks.
Function Purpose
Cli_PlcHotStart Puts the CPU in RUN mode performing an HOT START.
Cli_PlcColdStart Puts the CPU in RUN mode performing a COLD START.
Cli_PlcStop Puts the CPU in STOP mode.
Cli_CopyRamToRom Performs the Copy Ram to Rom action.
Cli_Compress Performs the Compress action.
Cli_GetPlcStatus Returns the CPU status (running/stopped).
Security functions
With these functions is possible to know the current protection level, and to set/clear
the current session password.
The correct name of the below functions Cli_SetSessionPassword and
Cli_ClearSessionPassword, would have to be Cli_Login and Cli_Logout to avoid
misunderstandings about their scope.
Especially because, if you look at the source code, there is an encoding function that
translates the plain password before send it to the PLC.
PASSWORD HACKING IS VERY FAR FROM THE AIM OF THIS PROJECT, MOREOVER
YOU NEED TO KNOW THE CORRECT PASSWORD TO MEET THE CPU SECURITY
LEVEL.
Detailed information about the protection level can be found in §33.19 of "System
Software for S7-300/400 System and Standard Functions".
Function Purpose
Cli_SetSessionPassword Send the password to the PLC to meet its security level.
Cli_ClearSessionPassword Clears the password set for the current session (logout).
Cli_GetProtection Gets the CPU protection level info.
Low level functions
Snap7 hides the IsoTCP underlying layer. With this function however, it’s possible to
exchange an IsoTCP telegram with a PLC.
Function Purpose
Cli_IsoExchangeBuffer Exchanges a given S7 PDU (protocol data unit) with the CPU.
Miscellaneous functions
These are utility functions.
Function Purpose
Cli_GetExecTime Returns the last job execution time in milliseconds.
Cli_GetLastError Returns the last job result.
Cli_GetPduLength Returns info about the PDU length (requested and negotiated).
Cli_ErrorText Returns a textual explanation of a given error number.
Cli_GetConnected Returns the connection status of the client.
Asynchronous functions
These functions are executed in a separate thread simultaneously to the execution of
the caller program.
Function Purpose
Cli_AsReadArea Reads a data area from a PLC.
Cli_AsWriteArea Writes a data area into a PLC.
Cli_AsDBRead Reads a part of a DB from a PLC.
Cli_AsDBWrite Writes a part of a DB into a PLC.
Cli_AsABRead Reads a part of IPU area from a PLC.
Cli_AsABWrite Writes a part of IPU area into a PLC.
Cli_AsEBRead Reads a part of IPI area from a PLC.
Cli_AsEBWrite Writes a part of IPI area into a PLC.
Cli_AsMBRead Reads a part of Merkers area from a PLC.
Cli_AsMBWrite Writes a part of Merkers area into a PLC.
Cli_AsTMRead Reads timers from a PLC.
Cli_AsTMWrite Write timers into a PLC.
Cli_AsCTRead Reads counters from a PLC.
Cli_AsCTWrite Write counters into a PLC.
Cli_AsListBlocksOfType Returns the AG blocks list of a given type.
Cli_AsReadSZL Reads a partial list of given ID and Index.
Cli_AsReadSZLList Reads the list of partial lists available in the CPU.
Cli_AsFullUpload Uploads a block from AG with Header and Footer infos.
Cli_AsUpload Uploads a block from AG.
Cli_AsDownload Download a block into AG.
Cli_AsDBGet Uploads a DB from AG using DBRead.
Cli_AsDBFill Fills a DB in AG with a given byte.
Cli_AsCopyRamToRom Performs the Copy Ram to Rom action.
Cli_AsCompress Performs the Compress action.
*/
class Snap7
{
static PG:=0x01
static OP:=0x02
static S7_Basic:=[0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10] ; 0x03..0x10
; Area
static S7AreaPE:=0x81 ; Process Inputs.
static S7AreaPA:=0x82 ; Process Outputs.
static S7AreaMK:=0x83 ; Merkers.
static S7AreaDB:=0x84 ; DB
static S7AreaCT:=0x1C ; Counters.
static S7AreaTM:=0x1D ; Timers
static AreaList:= {0x81:"Process Inputs"
,0x82:"Process Outputs"
,0x83:"Merkers"
,0x84:"DB"
,0x1C:"Counters"
,0x1D:"Timers"}
; WordLen
static S7WLBit:=0x01 ; Bit (inside a word)
static S7WLByte:=0x02 ; Byte (8 bit)
static S7WLWord:=0x04 ; Word (16 bit)
static S7WLDWord:=0x06 ; Double Word (32 bit)
static S7WLReal:=0x08 ; Real (32 bit float)
static S7WLCounter:=0x1C ; Counter (16 bit)
static S7WLTimer:=0x1D ; Timer (16 bit)
static WordLenList:= {0x01:"Bit (inside a word)"
,0x02:"Byte (8 bit)"
,0x04:"Word (16 bit)"
,0x06:"Double Word (32 bit)"
,0x08:"Real (32 bit float)"
,0x1C:"Counter (16 bit)"
,0x1D:"Timer (16 bit)"}
static WordLen:= {Snap7.S7WLBit:1
,Snap7.S7WLByte:1
,Snap7.S7WLWord:2
,Snap7.S7WLDWord:4
,Snap7.S7WLReal:4
,Snap7.S7WLCounter:2
,Snap7.S7WLTimer:2}
; BlockType
static Block_OB:=0x38 ; OB
static Block_DB:=0x41 ; DB
static Block_SDB:=0x42 ; SDB
static Block_FC:=0x43 ; FC
static Block_SFC:=0x44 ; SFC
static Block_FB:=0x45 ; FB
static Block_SFB:=0x46 ; SFB
static BlockTypeList:={0x38:"OB"
,0x41:"DB"
,0x42:"SDB"
,0x43:"FC"
,0x44:"SFC"
,0x45:"FB"
,0x46:"SFB"}
static StatusList:= {0x00:"The CPU status is unknown."
,0x08:"The CPU is running."
,0x04:"The CPU is stopped."}
static dll:=a_scriptdir "\" (A_Is64bitOS ? "snap7x64.dll":"snap7x86.dll")
static hModule:=Dllcall("LoadLibrary","Str",Snap7.dll,"Ptr")
static hCli_Create:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Create","Ptr")
static hCli_Destroy:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Destroy","Ptr")
static hCli_SetConnectionType:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetConnectionType","Ptr")
static hCli_ConnectTo:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ConnectTo","Ptr")
static hCli_SetConnectionParams:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetConnectionParams","Ptr")
static hCli_Connect:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Connect","Ptr")
static hCli_Disconnect:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Disconnect","Ptr")
static hCli_GetParam:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetParam","Ptr")
static hCli_SetParam:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetParam","Ptr")
static hCli_ReadArea:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ReadArea","Ptr")
static hCli_WriteArea:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_WriteArea","Ptr")
static hCli_DBRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_DBRead","Ptr")
static hCli_DBWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_DBWrite","Ptr")
static hCli_ABRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ABRead","Ptr")
static hCli_ABWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ABWrite","Ptr")
static hCli_EBRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_EBRead","Ptr")
static hCli_EBWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_EBWrite","Ptr")
static hCli_MBRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_MBRead","Ptr")
static hCli_MBWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_MBWrite","Ptr")
static hCli_TMRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_TMRead","Ptr")
static hCli_TMWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_TMWrite","Ptr")
static hCli_CTRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_CTRead","Ptr")
static hCli_CTWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_CTWrite","Ptr")
static hCli_ReadMultiVars:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ReadMultiVars","Ptr")
static hCli_WriteMultiVars:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_WriteMultiVars","Ptr")
static hCli_ListBlocks:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ListBlocks","Ptr")
static hCli_ListBlocksOfType:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ListBlocksOfType","Ptr")
static hCli_GetAgBlockInfo:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetAgBlockInfo","Ptr")
static hCli_GetPgBlockInfo:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetPgBlockInfo","Ptr")
static hCli_FullUpload:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_FullUpload","Ptr")
static hCli_Upload:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Upload","Ptr")
static hCli_Download:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Download","Ptr")
static hCli_Delete:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Delete","Ptr")
static hCli_DBGet:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_DBGet","Ptr")
static hCli_DBFill:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_DBFill","Ptr")
static hCli_GetPlcDateTime:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetPlcDateTime","Ptr")
static hCli_SetPlcDateTime:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetPlcDateTime","Ptr")
static hCli_SetPlcSystemDateTime:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetPlcSystemDateTime","Ptr")
static hCli_ReadSZL:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ReadSZL","Ptr")
static hCli_ReadSZLList:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ReadSZLList","Ptr")
static hCli_GetOrderCode:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetOrderCode","Ptr")
static hCli_GetCpuInfo:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetCpuInfo","Ptr")
static hCli_GetCpInfo:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetCpInfo","Ptr")
static hCli_PlcHotStart:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_PlcHotStart","Ptr")
static hCli_PlcColdStart:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_PlcColdStart","Ptr")
static hCli_PlcStop:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_PlcStop","Ptr")
static hCli_CopyRamToRom:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_CopyRamToRom","Ptr")
static hCli_Compress:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_Compress","Ptr")
static hCli_GetPlcStatus:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetPlcStatus","Ptr")
static hCli_SetSessionPassword:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetSessionPassword","Ptr")
static hCli_ClearSessionPassword:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ClearSessionPassword","Ptr")
static hCli_GetProtection:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetProtection","Ptr")
static hCli_IsoExchangeBuffer:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_IsoExchangeBuffer","Ptr")
static hCli_GetExecTime:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetExecTime","Ptr")
static hCli_GetLastError:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetLastError","Ptr")
static hCli_GetPduLength:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetPduLength","Ptr")
static hCli_ErrorText:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_ErrorText","Ptr")
static hCli_GetConnected:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_GetConnected","Ptr")
static hCli_SetAsCallback:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_SetAsCallback","Ptr")
static hCli_CheckAsCompletion:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_CheckAsCompletion","Ptr")
static hCli_WaitAsCompletion:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_WaitAsCompletion","Ptr")
static hCli_AsReadArea:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsReadArea","Ptr")
static hCli_AsWriteArea:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsWriteArea","Ptr")
static hCli_AsDBRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsDBRead","Ptr")
static hCli_AsDBWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsDBWrite","Ptr")
static hCli_AsABRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsABRead","Ptr")
static hCli_AsABWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsABWrite","Ptr")
static hCli_AsEBRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsEBRead","Ptr")
static hCli_AsEBWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsEBWrite","Ptr")
static hCli_AsMBRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsMBRead","Ptr")
static hCli_AsMBWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsMBWrite","Ptr")
static hCli_AsTMRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsTMRead","Ptr")
static hCli_AsTMWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsTMWrite","Ptr")
static hCli_AsCTRead:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsCTRead","Ptr")
static hCli_AsCTWrite:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsCTWrite","Ptr")
static hCli_AsListBlocksOfType:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsListBlocksOfType","Ptr")
static hCli_AsReadSZL:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsReadSZL","Ptr")
static hCli_AsReadSZLList:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsReadSZLList","Ptr")
static hCli_AsFullUpload:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsFullUpload","Ptr")
static hCli_AsUpload:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsUpload","Ptr")
static hCli_AsDownload:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsDownload","Ptr")
static hCli_AsDBGet:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsDBGet","Ptr")
static hCli_AsDBFill:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsDBFill","Ptr")
static hCli_AsCopyRamToRom:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsCopyRamToRom","Ptr")
static hCli_AsCompress:=DllCall("GetProcAddress","Ptr",Snap7.hModule,"AStr","Cli_AsCompress","Ptr")
static ISOTCPErrorTable:= {0x1:"Iso Connection error."
,0x2:"Iso Disconnection error."
,0x3:"Malformatted PDU suppled."
,0x4:"Bad Datasize passed to send/recv function."
,0x5:"Null pointer supplied."
,0x6:"A short packet received."
,0x7:"Too many packets without EoT flag (>64)"
,0x8:"The sum of fragments data exceeds the maximum packet size."
,0x9:"An error occurred during send."
,0xA:"An error occurred during recv."
,0xB:"Invalid TSAP params supplied."
,0xC:"Reserved (unused)"
,0xD:"Reserved (unused)"
,0xE:"Reserved (unused)"
,0xF:"Reserved (unused)"}
static ClientErrorsTable:= {0x001:"Error during PDU negotiation."
,0x002:"Invalid param(s) supplied to the current function."
,0x003:"A Job is pending : there is an async function in progress."
,0x004:"More than 20 items where passed to a MultiRead/Write area function."
,0x005:"Invalid Wordlen param supplied to the current function."
,0x006:"Partial data where written : The target area is smaller than the DataSize supplied."
,0x007:"A MultiRead/MultiWrite function has datasize over the PDU size."
,0x008:"Invalid answer from the PLC."
,0x009:"An address out of range was specified."
,0x00A:"Invalid Transportsize parameter was supplied to a Read/WriteArea function."
,0x00B:"Invalid datasize parameter supplied to the current function."
,0x00C:"Item requested was not found in the PLC."
,0x00D:"Invalid value supplied to the current function."
,0x00E:"PLC cannot be started."
,0x00F:"PLC is already in RUN stare."
,0x010:"PLC cannot be stopped."
,0x011:"Cannot copy RAM to ROM : the PLC is running or doesn’t support this function."
,0x012:"Cannot compress : the PLC is running or doesn’t support this function."
,0x013:"PLC is already in STOP state."
,0x014:"Function not available."
,0x015:"Block upload sequence failed."
,0x016:"Invalid data size received from the PLC."
,0x017:"Invalid block type supplied to the current function."
,0x018:"Invalid block supplied to the current function."
,0x019:"Invalid block size supplied to the current function."
,0x01A:"Block download sequence failed."
,0x01B:"Insert command (implicit command sent after a block download) refused."
,0x01C:"Delete command refused."
,0x01D:"This operation is password protected."
,0x01E:"Invalid password supplied."
,0x01F:"There is no password to set or clear : the protection is OFF."
,0x020:"Job timeout."
,0x021:"Partial data where read : The source area is greater than the DataSize supplied."
,0x022:"The buffer supplied is too small."
,0x023:"Function refused by the PLC."
,0x024:"Invalid param number suppilied to Get/SetParam."
,0x025:"Cannot perform : the client is destroying."
,0x026:"Cannot change parameter because connected."}
LastError[]
{
get
{
return format("0x{:08x}",this.Err)
}
set
{
return this.Err:=value
}
}
LastErrors[]
{
get
{
TCP_IP_Error:= format("0x{:04X}",(this.Err & 0x0000FFFF))
ISO_TCP_Error:=format("0x{:01X}",(this.Err & 0x000F0000) >> 16)
Client_Error:= format("0x{:03X}",(this.Err & 0xFFF00000) >> 20)
return [TCP_IP_Error,ISO_TCP_Error,Client_Error]
}
}
LastErrorText[]
{
get
{
TCP_IP_Error:= format("0x{:04X}",(this.Err & 0x0000FFFF))
ISO_TCP_Error:=format("0x{:X}",(this.Err & 0x000F0000) >> 16)
Client_Error:= format("0x{:03X}",(this.Err & 0xFFF00000) >> 20)
txt.="IP " this.IP "`tRack " this.Rack "`tSlot " this.Slot "`n"
txt.="Error`t" (this.Err=""?"NULL":(format("0x{:08X}",this.Err))) "`n`n"
txt.="TCP/IP Error = " (TCP_IP_Error?TCP_IP_Error:"None") "`t"
txt.=(TCP_IP_Error?"(" (format("{:u}",TCP_IP_Error)) ")":"") "`n"
txt.="`t" (TCP_IP_Error?"For TCP/IP code please refer to your OS reference.":"") "`n"
txt.="ISO TCP Error = " (ISO_TCP_Error?ISO_TCP_Error:"None") "`n"
txt.="`t" (Snap7.ISOTCPErrorTable[ISO_TCP_Error]) "`n"
txt.="Client Error = " (Client_Error?Client_Error:"None") "`n"
txt.="`t" (Snap7.ClientErrorsTable[Client_Error]) "`n`n"
txt.=this.MsgAddText
return txt
}
}
Cli_LastErrorText[]
{
get
{
this.Cli_ErrorText(this.LastError,Text)
return Text
}
}
Msg(Msg)
{
this.SaveDefaultGui:=A_DefaultGui
try Gui,% this.hGui . ":Destroy"
Gui,new:+HwndhGui -sysmenu +AlwaysOnTop
this.hGui:=hGui
try Gui,%hGui%:font,s10
try Gui,%hGui%:add,text,,%Msg%
try Gui,%hGui%:add,button,+hwndhOkB,Ok
obm:=ObjBindMethod(this,"OkButton")
try GuiControl,+g,% hOkB,% obm
try Gui,%hGui%:show,% "noactivate x" a_screenwidth/3 " y" a_screenheight/3 ,Snap7
try Gui,% this.SaveDefaultGui . ":Default"
}
OkButton()
{
try Gui,% this.hGui . ":Destroy"
}
_sub()
{
this.MsgAddText:=this.AddText
this.AddText:=""
if this.ShowErrors
this.Msg(this.LastErrorText)
Err:=this.LastErrors
if Err[1]
this.Cli_Disconnect()
if this.AutoReconnect and Err[1] and !this.TryingConnect
{
this.TryingConnect:=true
obm:=this.ReconnectTimer
settimer,% obm,% this.ReconnectTime
}
}
Reconnect()
{
this.Cli_Disconnect()
this.Cli_Connect()
if this.Connected
{
obm:=this.ReconnectTimer
settimer,% obm,Off
this.TryingConnect:=false
}
}
__New(IP="",Rack=0,Slot=3,ConnectionType=0x02,AutoReconnect=true,ReconnectTime=10000)
{
this.Err:=0
this.ShowErrors:=true
this.IP:=IP
this.Rack:=Rack
this.Slot:=Slot
this.ConnectionType:=ConnectionType
this.AutoReconnect:=AutoReconnect
this.ReconnectTime:=ReconnectTime
this.ReconnectTimer:=ObjBindMethod(this,"Reconnect")
if this.Cli_Create()
return ""
this.Cli_SetConnectionType(ConnectionType)
if IP
this.Cli_ConnectTo(IP,Rack,Slot)
}
__Delete()
{
this.Cli_Destroy()
try Gui,% this.hGui . ":Destroy"
}
; Creates a Client and returns its handle, which is the reference that you have to use
; every time you refer to that client.
; The maximum number of clients that you can create depends only on the system
; memory amount
Cli_Create()
{
; S7Object Cli_Create();
this._obj:=DllCall(Snap7.hCli_Create,"Ptr")
if !this._obj
{
this.Err:=-1
this.Msg("No S7Object.`n`nDll are not found.")
}
return this.Err
}
; Destroy a Client of given handle.
; Before destruction the client is automatically disconnected if it was.
Cli_Destroy()
{
; void Cli_Destroy( S7Object *Client );
DllCall(Snap7.hCli_Destroy,"ptr",this._obj)
this._obj:=""
}
; Sets the connection resource type, i.e the way in which the Clients connects to a PLC.
; Connection Type Value
; PG 0x01
; OP 0x02
; S7 Basic 0x03..0x10
Cli_SetConnectionType(ConnectionType)
{
this.ConnectionType:=ConnectionType
if !this._obj
return this.LastError
; int Cli_SetConnectionType(S7Object Client, word ConnectionType);
this.Err:=DllCall(Snap7.hCli_SetConnectionType
,"Ptr",this._obj
,"Int",ConnectionType)
if (this.Err!=0)
{
Text:=this.LastErrorText
Text.="Cli_SetConnectionType function`n"
if this.ShowErrors
this.Msg(Text)
}
return this.Err
}
; Connects the client to the hardware at (IP, Rack, Slot) Coordinates.
; Rack and Slot
; In addition to the IP Address, that we all understand, there are two other parameters
; that index the unit : Rack (0..7) and Slot (1..31) that you find into the hardware
; configuration of your project, for a physical component, or into the Station
; Configuration manager for WinAC.
; There is however some special cases for which those values are fixed or can work with
; a default as you can see in the next table.
; Rack Slot
; S7 300 CPU 0 2 Always
; S7 400 CPU Not fixed Follow the hardware configuration.
; WinAC CPU Not fixed Follow the hardware configuration.
; S7 1200 CPU 0 0 Or 0, 1
; S7 1500 CPU 0 0 Or 0, 1
; CP 343 0 0 Or follow Hardware configuration.
; CP 443 Not fixed Follow the hardware configuration.
; WinAC IE 0 0 Or follow Hardware configuration.
; In the worst case, if you know the IP address, run ClientDemo, set 0 as Rack and try
; to connect with different values of Slot (1..31).
Cli_ConnectTo(Address,Rack,Slot)
{
this.IP:=Address
this.Rack:=Rack
this.Slot:=Slot
this.Cli_Disconnect()
if !this._obj
return this.LastError
VarSetCapacity(addr,40,0)
loop,parse,Address
numput(asc(a_loopfield),addr,a_index-1,"Char")
; int Cli_ConnectTo(S7Object Client, const char *Address, int Rack, int Slot);
this.Err:=DllCall(Snap7.hCli_ConnectTo
,"ptr",this._obj
,"ptr",&addr
,"int",Rack
,"int",Slot)
if (this.Err!=0)
{
Text:=this.LastErrorText
Text.="Cli_ConnectTo function`n"
if this.ShowErrors
this.Msg(Text)
}
Err:=this.LastErrors
if Err[1]
this.Cli_Disconnect()
if this.AutoReconnect and Err[1]
{
this.TryingConnect:=true
obm:=this.ReconnectTimer
settimer,% obm,% this.ReconnectTime
}
return this.Err
}
;int Cli_SetConnectionParams(S7Object Client, const char *Address, word LocalTSAP, word RemoteTSAP);
; Connects the client to the PLC with the parameters specified in the previous call of
; Cli_ConnectTo() or Cli_SetConnectionParams().
; Remarks
; This function can be called only after a previous of Cli_ConnectTo()or
; Cli_SetConnectionParams() which internally sets Address and TSAPs.
Cli_Connect()
{
; int Cli_Connect(S7Object Client);
this.Err:=DllCall(Snap7.hCli_Connect
,"Ptr",this._obj)
if (this.Err!=0)
{
Text:=this.LastErrorText
Text.="Cli_Connect function`n"
if this.ShowErrors
this.Msg(Text)
}
return this.Err
}
; Disconnects “gracefully” the Client from the PLC.
; Remarks
; If Client parameter is a valid handle, this function returns always 0, it can be called
; safely multiple times.
; This function is called internally by Cli_Destroy() too.
Cli_Disconnect()
{
; int Cli_Disconnect(S7Object Client);
DllCall(Snap7.hCli_Disconnect
,"Ptr",this._obj)
; if (this.Err!=0)
; {
; if this.ShowErrors
; this.Msg(this.LastErrorText)
; }
; return this.Err
}
;int Cli_GetParam(S7Object Client, int ParamNumber, void *pValue);
;int Cli_SetParam(S7Object Client, int ParamNumber, void *pValue);
; This is the main function to read data from a PLC.
; With it you can read DB, Inputs, Outputs, Merkers, Timers and Counters.
; Area table
; Value Mean
; S7AreaPE 0x81 Process Inputs.
; S7AreaPA 0x82 Process Outputs.
; S7AreaMK 0x83 Merkers.
; S7AreaDB 0x84 DB
; S7AreaCT 0x1C Counters.
; S7AreaTM 0x1D Timers
;
; WordLen table
; Value Mean
; S7WLBit 0x01 Bit (inside a word)
; S7WLByte 0x02 Byte (8 bit)
; S7WLWord 0x04 Word (16 bit)
; S7WLDWord 0x06 Double Word (32 bit)
; S7WLReal 0x08 Real (32 bit float)
; S7WLCounter 0x1C Counter (16 bit)
; S7WLTimer 0x1D Timer (16 bit)
;
; Remarks
; As said, every data packet exchanged with a PLC must fit in a PDU, whose size is fixed
; and varies from 240 up to 960 bytes.
; This function completely hides this concept, the data that you can transfer in
; a single call depends only on the size available of the data area (i.e. obviously,
; you cannot read 1024 bytes from a DB whose size is 300 bytes).
; If this data size exceeds the PDU size, the packet is automatically split across more
; subsequent transfers.
; If either S7AreaCT or S7AreaTM is selected, WordLen must be either S7WLCounter
; or S7WLTimer (However no error is raised and the values are internally fixed).
; Your buffer should be large enough to receive the data.
; Particularly:
; Buffer size (byte) = Word size * Amount
; Where:
; Word size
; S7WLBit 1
; S7WLByte 1
; S7WLWord 2
; S7WLDWord 4
; S7WLReal 4
; S7WLCounter 2
; S7WLTimer 2
; Notes
; If you need a large data transfer you may consider to use the asynchronous
; counterpart Cli_AsReadArea.
; (2) When WordLen=S7WLBit the Offset (Start) must be expressed in bits.
; Ex. The Start for DB4.DBX 10.3 is (10*8)+3 = 83.
Cli_ReadArea(Area,DBNumber,Start,Amount,WordLen,byref pUsrData)
{
if !this.Connected
return this.LastError
; int Cli_ReadArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_ReadArea
,"Ptr",this._obj
,"Int",Area
,"Int",DBNumber
,"Int",Start
,"Int",Amount
,"Int",WordLen
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_ReadArea function`n"
this.AddText.="Area`t`t" Snap7.AreaList[Area] "`nDBNumber`t" DBNumber "`nStart`t`t" Start
this.AddText.="`nAmount`t`t" Amount "`nWordLen`t" Snap7.WordLenList[WordLen]
this._sub()
}
return this.Err
}
; This is the main function to write data into a PLC. It’s the complementary function of
; Cli_ReadArea(), the parameters and their meanings are the same.
; The only difference is that the data is transferred from the buffer pointed by pUsrData
; into PLC.
; Remarks
; If you need a large data transfer you may consider to use the asynchronous
; counterpart Cli_AsWriteArea.
Cli_WriteArea(Area,DBNumber,Start,Amount,WordLen,byref pUsrData)
{
if !this.Connected
return this.LastError
; int Cli_WriteArea( S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_WriteArea
,"Ptr",this._obj
,"Int",Area
,"Int",DBNumber
,"Int",Start
,"Int",Amount
,"Int",WordLen
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_WriteArea function`n"
this.AddText.="Area`t`t" Snap7.AreaList[Area] "`nDBNumber`t" DBNumber "`nStart`t`t" Start
this.AddText.="`nAmount`t`t" Amount "`nWordLen`t" Snap7.WordLenList[WordLen]
this._sub()
}
return this.Err
}
; This is a lean function of Cli_ReadArea() to read PLC DB.
; It simply internally calls Cli_ReadArea() with
; Area = S7AreaDB.
; WordLen = S7WLBytes.
Cli_DBRead(DBNumber,Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_DBRead( S7Object Client, int DBNumber, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_DBRead
,"Ptr",this._obj
,"Int",DBNumber
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_DBRead function`n"
this.AddText.="DBNumber`t" DBNumber "`nStart`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_WriteArea() to Write PLC DB.
; It simply internally calls Cli_WriteArea() with
; Area = S7AreaDB.
; WordLen = S7WLBytes.
Cli_DBWrite(DBNumber,Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_DBWrite( S7Object Client, int DBNumber, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_DBWrite
,"Ptr",this._obj
,"Int",DBNumber
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_DBWrite function`n"
this.AddText.="DBNumber`t" DBNumber "`nStart`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_ReadArea() to read PLC process outputs .
; It simply internally calls Cli_ReadArea() with
; Area = S7AreaPA.
; WordLen = S7WLBytes.
Cli_ABRead(Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_ABRead( S7Object Client, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_ABRead
,"Ptr",this._obj
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_ABRead function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_WriteArea() to Write PLC process outputs.
; It simply internally calls Cli_WriteArea() with
; Area = S7AreaPA.
; WordLen = S7WLBytes.
Cli_ABWrite(Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_ABWrite( S7Object Client, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_ABWrite
,"Ptr",this._obj
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_ABWrite function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_ReadArea() to read PLC process inputs .
; It simply internally calls Cli_ReadArea() with
; Area = S7AreaPE.
; WordLen = S7WLBytes.
Cli_EBRead(Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_EBRead( S7Object Client, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_EBRead
,"Ptr",this._obj
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_EBRead function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_WriteArea() to Write PLC process inputs .
; It simply internally calls Cli_WriteArea() with
; Area = S7AreaPE.
; WordLen = S7WLBytes.
Cli_EBWrite(Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_EBWrite( S7Object Client, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_EBWrite
,"Ptr",this._obj
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_EBWrite function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_ReadArea() to read PLC Merkers .
; It simply internally calls Cli_ReadArea() with
; Area = S7AreaMK.
; WordLen = S7WLBytes.
Cli_MBRead(Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_MBRead(S7Object Client, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_MBRead
,"Ptr",this._obj
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_MBRead function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_WriteArea() to Write PLC Merkers.
; It simply internally calls Cli_WriteArea() with
; Area = S7AreaMK.
; WordLen = S7WLBytes.
Cli_MBWrite(Start,Size,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_MBWrite(S7Object Client, int Start, int Size, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_MBWrite
,"Ptr",this._obj
,"Int",Start
,"Int",Size
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_MBWrite function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nSize`t`t" Size
this._sub()
}
return this.Err
}
; This is a lean function of Cli_ReadArea() to read PLC Timers .
; It simply internally calls Cli_ReadArea() with
; Area = S7AreaTM.
; WordLen = S7WLTimer.
; Buffer size (bytes) needed is Amount * 2.
Cli_TMRead(Start,Amount,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_TMRead(S7Object Client, int Start, int Amount, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_TMRead
,"Ptr",this._obj
,"Int",Start
,"Int",Amount
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_TMRead function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nAmount`t`t" Amount
this._sub()
}
return this.Err
}
; This is a lean function of Cli_WriteArea() to Write PLC Timers .
; It simply internally calls Cli_WriteArea() with
; Area = S7AreaTM.
; WordLen = S7WLTimer.
; Buffer size (bytes) needed is Amount * 2.
Cli_TMWrite(Start,Amount,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_TMWrite(S7Object Client, int Start, int Amount, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_TMWrite
,"Ptr",this._obj
,"Int",Start
,"Int",Amount
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_TMWrite function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nAmount`t`t" Amount
this._sub()
}
return this.Err
}
; This is a lean function of Cli_ReadArea() to read PLC Counters.
; It simply internally calls Cli_ReadArea() with
; Area = S7AreaCT.
; WordLen = S7WLCounter.
; Buffer size (bytes) needed is Amount * 2.
Cli_CTRead(Start,Amount,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_CTRead(S7Object Client, int Start, int Amount, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_CTRead
,"Ptr",this._obj
,"Int",Start
,"Int",Amount
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_CTRead function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nAmount`t`t" Amount
this._sub()
}
return this.Err
}
; This is a lean function of Cli_WriteArea() to Write PLC Counters.
; It simply internally calls Cli_WriteArea() with
; Area = S7AreaCT.
; WordLen = S7WLCounter.
; Buffer size (bytes) needed is Amount * 2.
Cli_CTWrite(Start,Amount,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_CTWrite(S7Object Client, int Start, int Amount, void *pUsrData);
this.Err:=DllCall(Snap7.hCli_CTWrite
,"Ptr",this._obj
,"Int",Start
,"Int",Amount
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_CTWrite function`n"
this.AddText.="Start`t`t" Start
this.AddText.="`nAmount`t`t" Amount
this._sub()
}
return this.Err
}
; This is function allows to read different kind of variables from a PLC in a single call.
; With it you can read DB, Inputs, Outputs, Merkers, Timers and Counters.
; PS7DataItem struct
; Type Dir.
; Area integer 32 In Area identifier.
; Wordlen integer 32 In Word size
; Result integer 32 Out Item operation result (2)
; DBNumber integer 32 In DB Number if Area = S7AreaDB, otherwise is ignored.
; Start integer 32 In Offset to start
; Amount integer 32 In Amount of words to read (1)
; pData Pointer In Address of user buffer.
; (1) Note the use of the parameter name “amount”, it means quantity of words, not byte size.
; Remarks
; Due the different kind of variables involved , there is no split feature available for this
; function, so the maximum data size must not exceed the PDU size. Thus there
; isn't an asynchronous counterpart of this function.
; The advantage of this function becomes big when you have many small noncontiguous
; variables to be read.
Cli_ReadMultiVars(byref Item,ItemsCount)
{
if !this.Connected
return this.LastError
;int Cli_ReadMultiVars(S7Object Client, PS7DataItem Item, int ItemsCount);
this.Err:=DllCall(Snap7.hCli_ReadMultiVars
,"Ptr",this._obj
,"Ptr",&Item
,"Int",ItemsCount)
if (this.Err!=0)
{
this.AddText.="Cli_ReadMultiVars function`n"
this.AddText.="ItemsCount`t" ItemsCount "`n"
this._sub()
}
return this.Err
}
; This is function allows to write different kind of variables into a PLC in a single call.
; With it you can write DB, Inputs, Outputs, Merkers, Timers and Counters.
; It’s the complementary function of Cli_ReadMultiVars(), the parameters and their
; meanings are the same.
; See Cli_ReadMultiVars() for parameters and remarks.
Cli_WriteMultiVars(Item,ItemsCount)
{
if !this.Connected
return this.LastError
;int Cli_WriteMultiVars(S7Object Client, PS7DataItem Item, int ItemsCount);
this.Err:=DllCall(Snap7.hCli_WriteMultiVars
,"Ptr",this._obj
,"Ptr",&Item
,"Int",ItemsCount)
if (this.Err!=0)
{
this.AddText.="Cli_WriteMultiVars function`n"
this.AddText.="ItemsCount`t" ItemsCount "`n"
this._sub()
}
return this.Err
}
; This function returns the AG blocks amount divided by type.
; TS7BlocksList struct
; Type Dir.
; OBCount integer 32 Out OB amount in AG
; FBCount integer 32 Out FB amount in AG
; FCCount integer 32 Out FC amount in AG
; SFBCount integer 32 Out SFB amount in AG
; SFCCount integer 32 Out SFC amount in AG
; DBCount integer 32 Out DB amount in AG
; SDBCount integer 32 Out SDB amount in AG
Cli_ListBlocks(byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_ListBlocks(S7Object Client, TS7BlocksList *pUsrData);
this.Err:=DllCall(Snap7.hCli_ListBlocks
,"Ptr",this._obj
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_ListBlocks function`n"
this._sub()
}
return this.Err
}
; This function returns the AG list of a specified block type.
; BlockType values
; Value Type
; Block_OB 0x38 OB
; Block_DB 0x41 DB
; Block_SDB 0x42 SDB
; Block_FC 0x43 FC
; Block_SFC 0x44 SFC
; Block_FB 0x45 FB
; Block_SFB 0x46 SFB
; TS7BlocksOfType, by default, is defined as a packed array of 8192 16-bit word.
; typedef word TS7BlocksOfType[0x2000];
; 8192 is the maximum number of blocks that a CPU S7417-4 can hold.
; ItemsCount
; In input indicates the user buffer capacity, in output how many items were found.
; The function reads the list into the internal buffer, if ItemsCount is smaller than the
; data uploaded, only ItemsCount elements are copied into the user buffer and
; errCliPartialDataRead is returned.
; The minimum expected value for ItemsCount is 1, otherwise
; errCliInvalidBlockSize error is returned.
Cli_ListBlocksofType(BlockType,byref pUsrData,ItemsCount)
{
if !this.Connected
return this.LastError
varsetcapacity(pItemsCount,8)
numput(ItemsCount,pItemsCount,0,"Int")
;int Cli_ListBlocksofType (S7Object Client, int BlockType, TS7BlocksOfType *pUsrData, int *ItemsCount);
this.Err:=DllCall(Snap7.hCli_ListBlocksofType
,"Ptr",this._obj
,"Int",BlockType
,"Ptr",&pUsrData
,"Ptr",&pItemsCount)
if (this.Err!=0)
{
this.AddText.="Cli_ListBlocksofType function`nBlockType`t" Snap7.BlockTypeList[BlockType]
this._sub()
}
return this.Err
}
; Returns detailed information about an AG given block.
; This function is very useful if you need to read or write data in a DB which you do not
; know the size in advance (see MC7Size field)
; This function is used internally by Cli_DBGet().
; BlockType values
; Value Type
; Block_OB 0x38 OB
; Block_DB 0x41 DB
; Block_SDB 0x42 SDB
; Block_FC 0x43 FC
; Block_SFC 0x44 SFC
; Block_FB 0x45 FB
; Block_SFB 0x46 SFB
Cli_GetAgBlockInfo(BlockType,BlockNum,byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_GetAgBlockInfo(S7Object Client, int BlockType, int BlockNum, TS7BlockInfo *pUsrData);
this.Err:=DllCall(Snap7.hCli_GetAgBlockInfo
,"Ptr",this._obj
,"Int",BlockType
,"Int",BlockNum
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_GetAgBlockInfo function`nBlockType`t" Snap7.BlockTypeList[BlockType] "`nBlockNum`t" BlockNum
this._sub()
}
return this.Err
}
; Returns detailed information about a block present in a user buffer.
; This function is usually used in conjunction with Cli_FullUpload().
; An uploaded a block saved to disk, could be loaded in a user buffer and checked with
; this function.
; Remarks
; For a detailed description of TS7BlockInfo see Cli_GetAgBlockInfo
; With this function in conjunction with block oriented functions it’s possible to create a
; “backup manager”.
; The rich demo ClientDemo shows how to upload/download/delete and get detailed
; block information.
Cli_GetPgBlockInfo(byref pBlock,byref pUsrData, size)
{
if !this.Connected
return this.LastError
;int Cli_GetPgBlockInfo(S7Object Client, void *pBlock, TS7BlockInfo *pUsrData, int size);
this.Err:=DllCall(Snap7.hCli_GetPgBlockInfo
,"Ptr",this._obj
,"Ptr",&pBlock
,"Ptr",&pUsrData
,"Int",size)
if (this.Err!=0)
{
this.AddText.="Cli_GetPgBlockInfo function`nsize`t" size
this._sub()
}
return this.Err
}
; Uploads a block from AG.
; The whole block (including header and footer) is copied into the user buffer.
; BlockType values
; Value Type
; Block_OB 0x38 OB
; Block_DB 0x41 DB
; Block_SDB 0x42 SDB
; Block_FC 0x43 FC
; Block_SFC 0x44 SFC
; Block_FB 0x45 FB
; Block_SFB 0x46 SFB
; The function is performed into the internal buffer, if size is smaller than the data
; uploaded, only size bytes are copied and errCliPartialDataRead is returned.
Cli_FullUpload(BlockType,BlockNum,byref pUsrData,byref Size)
{
if !this.Connected
return this.LastError
;int Cli_FullUpload( S7Object Client, int BlockType, int BlockNum, void *pUsrData, int *Size);
this.Err:=DllCall(Snap7.hCli_FullUpload
,"Ptr",this._obj
,"Int",BlockType
,"Int",BlockNum
,"Ptr",&pUsrData
,"Ptr",&Size)
Size:=numget(Size,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_FullUpload function`nBlockType`t" Snap7.BlockTypeList[BlockType] "`nBlockNum`t" BlockNum "`nSize" Size
this._sub()
}
return this.Err
}
; Uploads a block body from AG.
; Only the block body (but header and footer) is copied into the user buffer.
; BlockType values
; Value Type
; Block_OB 0x38 OB
; Block_DB 0x41 DB
; Block_SDB 0x42 SDB
; Block_FC 0x43 FC
; Block_SFC 0x44 SFC
; Block_FB 0x45 FB
; Block_SFB 0x46 SFB
; The function reads the block data into the internal buffer, if size is smaller than the
; data uploaded, only size bytes are copied into the user buffer and
; errCliPartialDataRead is returned.
Cli_Upload(BlockType,BlockNum,byref pUsrData,byref Size)
{
if !this.Connected
return this.LastError
;int Cli_Upload( S7Object Client, int BlockType, int BlockNum, void *pUsrData, int *Size);
this.Err:=DllCall(Snap7.hCli_Upload
,"Ptr",this._obj
,"Int",BlockType
,"Int",BlockNum
,"Ptr",&pUsrData
,"Ptr",&Size)
Size:=numget(Size,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_Upload function`nBlockType`t" Snap7.BlockTypeList[BlockType] "`nBlockNum`t" BlockNum "`nSize" Size
this._sub()
}
return this.Err
}
; Downloads a block into AG.
; A whole block (including header and footer) must be available into the user buffer.
; Remarks
; A block ready to be downloaded already contains info about block type and block
; number.
; If the parameter BlockNum is -1, the block number is not changed used else the block
; is downloaded with a different number (just like a “Download As…”).
Cli_Download(BlockNum,byref pUsrData,Size)
{
if !this.Connected
return this.LastError
;int Cli_Download( S7Object Client, int BlockNum, void *pUsrData, int *Size);
this.Err:=DllCall(Snap7.hCli_Download
,"Ptr",this._obj
,"Int",BlockNum
,"Ptr",&pUsrData
,"Ptr",Size)
if (this.Err!=0)
{
this.AddText.="Cli_Download function`nBlockNum`t" BlockNum "`nSize" Size
this._sub()
}
return this.Err
}
; Deletes a block into AG.
; BlockType values
; Value Type
; Block_OB 0x38 OB
; Block_DB 0x41 DB
; Block_SDB 0x42 SDB
; Block_FC 0x43 FC
; Block_SFC 0x44 SFC
; Block_FB 0x45 FB
; Block_SFB 0x46 SFB
Cli_Delete(BlockType,BlockNum)
{
if !this.Connected
return this.LastError
;int Cli_Delete( S7Object Client, int BlockType, int BlockNum);
this.Err:=DllCall(Snap7.hCli_Delete
,"Ptr",this._obj
,"Int",BlockType
,"Int",BlockNum)
if (this.Err!=0)
{
this.AddText.="Cli_Delete function`nBlockType`t" Snap7.BlockTypeList[BlockType] "`nBlockNum`t" BlockNum
this._sub()
}
return this.Err
}
; Uploads a DB from AG.
; This function is equivalent to Cli_Upload() with BlockType = Block_DB but it uses a
; different approach so it’s not subject to the security level set.
; Only data is uploaded.
; Remarks
; This function first gathers the DB size via Cli_GetAgBlockInfo then calls Cli_DBRead.
Cli_DBGet(DBNumber,byref pUsrData,byref Size)
{
if !this.Connected
return this.LastError
;int Cli_DBGet( S7Object Client, int DBNumber, void *pUsrData, int *Size);
this.Err:=DllCall(Snap7.hCli_DBGet
,"Ptr",this._obj
,"Int",DBNumber
,"Ptr",&pUsrData
,"Ptr",&Size)
Size:=numget(Size,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_DBGet function`nDBNumber`t" DBNumber "`nSize" Size
this._sub()
}
return this.Err
}
; Fills a DB in AG with a given byte without the need of specifying its size.
; Remarks
; Fillchar is an integer for efficiency reasons, only the lowest byte is used.
Cli_DBFill(DBNumber,FillChar)
{
if !this.Connected
return this.LastError
;int Cli_DBFill( S7Object Client, int DBNumber, int FillChar);
this.Err:=DllCall(Snap7.hCli_DBFill
,"Ptr",this._obj
,"Int",DBNumber
,"Int",FillChar)
if (this.Err!=0)
{
this.AddText.="Cli_DBFill function`nDBNumber`t" DBNumber "`nFillChar" FillChar
this._sub()
}
return this.Err
}
; Reads PLC date and time.
; Struct tm is C++ specific, if you use the wrappers provided, you don’t need to care
; about it, since tm is internally converted to the native date/time format.
Cli_GetPlcDateTime(byref DateTime)
{
if !this.Connected
return this.LastError
;int Cli_GetPlcDateTime(S7Object Client, tm *DateTime);
this.Err:=DllCall(Snap7.hCli_GetPlcDateTime
,"Ptr",this._obj
,"Ptr",&DateTime)
if (this.Err!=0)
{
this.AddText.="Cli_GetPlcDateTime function`n"
this._sub()
}
return this.Err
}
; Sets the PLC date and time.
; Struct tm is C++ specific, if you use the wrappers provided, you don’t need to care
; about it, since tm is internally converted to the native date/time format.
Cli_SetPlcDateTime(byref DateTime)
{
if !this.Connected
return this.LastError
;int Cli_SetPlcDateTime(S7Object Client, tm *DateTime);
this.Err:=DllCall(Snap7.hCli_SetPlcDateTime
,"Ptr",this._obj
,"Ptr",&DateTime)
if (this.Err!=0)
{
this.AddText.="Cli_SetPlcDateTime function`n"
this._sub()
}
return this.Err
}
; Sets the PLC date and time in accord to the PC system Date/Time.
Cli_SetPlcSystemDateTime()
{
if !this.Connected
return this.LastError
;int Cli_SetPlcSystemDateTime(S7Object Client);
this.Err:=DllCall(Snap7.hCli_SetPlcSystemDateTime
,"Ptr",this._obj)
if (this.Err!=0)
{
this.AddText.="Cli_SetPlcSystemDateTime function`n"
this._sub()
}
return this.Err
}
; Reads a partial list of given ID and INDEX.
; The function is performed into the internal buffer, if size is smaller than the data
; uploaded, only size bytes are copied and errCliPartialDataRead is returned.
; Remarks
; LENTHDR and N_DR are HI-LOW order swapped, the data buffer is unchanged.
; TS7SZL struct
; // See §33.1 of "System Software for S7-300/400 System and
; // Standard Functions"
; // and see SFC51 description too
; typedef struct {
; word LENTHDR;
; word N_DR;
; } SZL_HEADER, *PSZL_HEADER;
; typedef struct {
; SZL_HEADER Header;
; byte Data[0x4000-4];
; } TS7SZL, *PS7SZL;
;
; Type Dir. Mean
; LENTHDR unsigned Integer 16 Out Length of a data record of the partial list in bytes
; N_DR unsigned Integer 16 Out Number of data records contained in the partial list.
Cli_ReadSZL(ID,Index,byref pUsrData,byref Size)
{
if !this.Connected
return this.LastError
;int Cli_ReadSZL( S7Object Client, int ID, int Index, TS7SZL *pUsrData, int *Size);
this.Err:=DllCall(Snap7.hCli_ReadSZL
,"Ptr",this._obj
,"Int",ID
,"Int",Index
,"Ptr",&pUsrData
,"Ptr",&Size)
Size:=numget(Size,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_ReadSZL function`nID" ID "`nIndex`t" Index "`nSize`t" Size
this._sub()
}
return this.Err
}
; Reads the directory of the partial lists.
; TS7SZLList struct
; // See §33.1 of "System Software for S7-300/400 System and
; // Standard Functions"
; // and see SFC51 description too
; typedef struct {
; word LENTHDR;
; word N_DR;
; } SZL_HEADER, *PSZL_HEADER;
; typedef struct {
; SZL_HEADER Header;
; word List[0x2000-2]; // HI-LO Swapped
; } TS7SZLList, *PS7SZLList;
;
; Type Dir.
; LENTHDR unsigned Integer 16 Out Length of a data record of the partial list in bytes
; N_DR unsigned Integer 16 Out Number of data records contained in the partial list.
Cli_ReadSZLList(byref pUsrData,byref ItemsCount)
{
if !this.Connected
return this.LastError
;int Cli_ReadSZLList( S7Object Client, TS7SZLList *pUsrData, int *ItemsCount);
this.Err:=DllCall(Snap7.hCli_ReadSZLList
,"Ptr",this._obj
,"Ptr",&pUsrData
,"Ptr",&ItemsCount)
ItemsCount:=numget(ItemsCount,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_ReadSZLList function`nItemsCount`t" ItemsCount
this._sub()
}
return this.Err
}
; Gets CPU order code and version info.
; TS7OrderCode struct
; typedef struct {
; char Code[21]; // Order Code
; byte V1; // Version V1.V2.V3
; byte V2;
; byte V3;
; } TS7OrderCode, *PS7OrderCode;
Cli_GetOrderCode(byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_GetOrderCode( S7Object Client, TS7OrderCode *pUsrData);
this.Err:=DllCall(Snap7.hCli_GetOrderCode
,"Ptr",this._obj
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_GetOrderCode function`n"
this._sub()
}
return this.Err
}
GetOrderCode()
{
varsetcapacity(pUsrData,25)
Err:=this.Cli_GetOrderCode(pUsrData)
if (Err!=0)
return
Code:=Snap7.GetStr(pUsrData,0,21)
V1:=numget(pUsrData,21,"UChar")
V2:=numget(pUsrData,22,"UChar")
V3:=numget(pUsrData,23,"UChar")
return {Code:Code,V1:V1,V2:V2,V3:V3,Version:(V1 "." V2 "." V3)}
}
; Gets CPU module name, serial number and other info.
; TS7CpuInfo struct
; typedef struct {
; char ModuleTypeName[33];
; char SerialNumber[25];
; char ASName[25];
; char Copyright[27];
; char ModuleName[25];
; } TS7CpuInfo, *PS7CpuInfo;
Cli_GetCpuInfo(byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_GetCpuInfo( S7Object Client, TS7CpuInfo *pUsrData);
this.Err:=DllCall(Snap7.hCli_GetCpuInfo
,"Ptr",this._obj
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_GetCpuInfo function`n"
this._sub()
}
return this.Err
}
GetCpuInfo()
{
varsetcapacity(pUsrData,33+25+25+27+25)
Err:=this.Cli_GetCpuInfo(pUsrData)
if (Err!=0)
return
ModuleTypeName:=Snap7.GetStr(pUsrData,0,33)
SerialNumber:=Snap7.GetStr(pUsrData,33,25)
ASName:=Snap7.GetStr(pUsrData,33+25,25)
Copyright:=Snap7.GetStr(pUsrData,33+25+25,27)
ModuleName:=Snap7.GetStr(pUsrData,33+25+25+27,25)
return {ModuleTypeName:ModuleTypeName,SerialNumber:SerialNumber,ASName:ASName,Copyright:Copyright,ModuleName:ModuleName}
}
; Gets CP (communication processor) info.
; TS7CpInfo struct
; typedef struct {
; int MaxPduLengt;
; int MaxConnections;
; int MaxMpiRate;
; int MaxBusRate;
; } TS7CpInfo, *PS7CpInfo;
Cli_GetCpInfo(byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_GetCpInfo( S7Object Client, TS7CpInfo *pUsrData);
this.Err:=DllCall(Snap7.hCli_GetCpInfo
,"Ptr",this._obj
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_GetCpInfo function`n"
this._sub()
}
return this.Err
}
GetCpInfo()
{
varsetcapacity(pUsrData,4*4)
Err:=this.Cli_GetCpInfo(pUsrData)
if (Err!=0)
return
MaxPduLengt:=numget(pUsrData,0,"Int")
MaxConnections:=numget(pUsrData,4,"Int")
MaxMpiRate:=numget(pUsrData,8,"Int")
MaxBusRate:=numget(pUsrData,12,"Int")
return {MaxPduLengt:MaxPduLengt,MaxConnections:MaxConnections,MaxMpiRate:MaxMpiRate,MaxBusRate:MaxBusRate}
}
; Puts the CPU in RUN mode performing an HOT START.
; Remarks
; This function is subject to the security level set.
Cli_PlcHotStart()
{
if !this.Connected
return this.LastError
;int Cli_PlcHotStart( S7Object Client);
this.Err:=DllCall(Snap7.hCli_PlcHotStart
,"Ptr",this._obj)
if (this.Err!=0)
{
this.AddText.="Cli_PlcHotStart function`n"
this._sub()
}
return this.Err
}
; Puts the CPU in RUN mode performing a COLD START.
; Remarks
; This function is subject to the security level set.
Cli_PlcColdStart()
{
if !this.Connected
return this.LastError
;int Cli_PlcColdStart( S7Object Client);
this.Err:=DllCall(Snap7.hCli_PlcColdStart
,"Ptr",this._obj)
if (this.Err!=0)
{
this.AddText.="Cli_PlcColdStart function`n"
this._sub()
}
return this.Err
}
; Puts the CPU in STOP mode.
; Remarks
; This function is subject to the security level set.
Cli_PlcStop()
{
if !this.Connected
return this.LastError
;int Cli_PlcStop( S7Object Client);
this.Err:=DllCall(Snap7.hCli_PlcStop
,"Ptr",this._obj)
if (this.Err!=0)
{
this.AddText.="Cli_PlcStop function`n"
this._sub()
}
return this.Err
}
; Performs the Copy Ram to Rom action.
; Remarks
; Not all CPUs support this operation.
; The CPU must be in STOP mode.
Cli_CopyRamToRom(Timeout)
{
if !this.Connected
return this.LastError
;int Cli_CopyRamToRom(S7Object Client, int Timeout);
this.Err:=DllCall(Snap7.hCli_CopyRamToRom
,"Ptr",this._obj
,"Int",Timeout)
if (this.Err!=0)
{
this.AddText.="Cli_CopyRamToRom function`nTimeout`t" Timeout
this._sub()
}
return this.Err
}
; Performs the Memory compress action.
; Remarks
; Not all CPUs support this operation.
; The CPU must be in STOP mode.
Cli_Compress(Timeout)
{
if !this.Connected
return this.LastError
;int Cli_Compress(S7Object Client, int Timeout);
this.Err:=DllCall(Snap7.hCli_Compress
,"Ptr",this._obj
,"Int",Timeout)
if (this.Err!=0)
{
this.AddText.="Cli_Compress function`nTimeout`t" Timeout
this._sub()
}
return this.Err
}
; Returns the CPU status (running/stopped).
; Status values
; Value
; S7CpuStatusUnknown 0x00 The CPU status is unknown.
; S7CpuStatusRun 0x08 The CPU is running.
; S7CpuStatusStop 0x04 The CPU is stopped.
Cli_GetPlcStatus(byref Status)
{
if !this.Connected
return this.LastError
VarSetCapacity(Status,8,0)
;int Cli_GetPlcStatus(S7Object Client, int *Status);
this.Err:=DllCall(Snap7.hCli_GetPlcStatus
,"Ptr",this._obj
,"Ptr",&Status)
Status:=numget(Status,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_GetPlcStatus function`n"
this._sub()
}
return this.Err
}
; Send the password to the PLC to meet its security level.
; Remarks
; A password accepted by a PLC is an 8 chars string, a greater password will be
; trimmed, and a smaller one will be "right space padded".
Cli_SetSessionPassword(Password)
{
if !this.Connected
return this.LastError
StringLeft,Password,Password,8
VarSetCapacity(Pass,8,0)
loop,parse,Password
numput(asc(a_loopfield),Pass,a_index-1,"Char")
;int Cli_SetSessionPassword(S7Object Client, char *Password);
this.Err:=DllCall(Snap7.hCli_SetSessionPassword
,"Ptr",this._obj
,"Ptr",&Pass)
if (this.Err!=0)
{
this.AddText.="Cli_SetSessionPassword function`n"
this._sub()
}
return this.Err
}
; Clears the password set for the current session (logout).
Cli_ClearSessionPassword(Password)
{
if !this.Connected
return this.LastError
;int Cli_ClearSessionPassword(S7Object Client);
this.Err:=DllCall(Snap7.hCli_ClearSessionPassword
,"Ptr",this._obj)
if (this.Err!=0)
{
this.AddText.="Cli_ClearSessionPassword function`n"
this._sub()
}
return this.Err
}
; Gets the CPU protection level info.
; TS7Protection struct
; typedef struct {
; word sch_schal;
; word sch_par;
; word sch_rel;
; word bart_sch;
; word anl_sch;
; } TS7Protection, *PS7Protection;
;
; S7Protection Values
; Values
; sch_schal 1, 2, 3 Protection level set with the mode selector.
; sch_par 0, 1, 2, 3 Password level, 0 : no password
; sch_rel 0, 1, 2, 3 Valid protection level of the CPU
; bart_sch 1, 2, 3, 4 Mode selector setting (1:RUN, 2:RUN-P, 3:STOP, 4:MRES, 0:undefined or cannot be determined)
; anl_sch 0, 1, 2 Startup switch setting (1:CRST, 2:WRST, 0:undefined, does not exist of cannot be determined)
Cli_GetProtection(byref pUsrData)
{
if !this.Connected
return this.LastError
;int Cli_GetProtection( S7Object Client, TS7Protection *pUsrData);
this.Err:=DllCall(Snap7.hCli_GetProtection
,"Ptr",this._obj
,"Ptr",&pUsrData)
if (this.Err!=0)
{
this.AddText.="Cli_GetProtection function`n"
this._sub()
}
return this.Err
}
; Exchanges a given S7 PDU (protocol data unit) with the CPU.
; Remarks
; The S7 PDU supplied is encapsulated into an IsoTCP telegram then is sent to the CPU.
; Finally, the S7 PDU is extracted from the reply telegram and is copied into the user
; buffer.
; Look at S7_types.h for more info about S7 PDU.
; No size check is performed : use a large enough buffer.
Cli_IsoExchangeBuffer(byref pUsrData,byref Size)
{
if !this.Connected
return this.LastError
;int Cli_IsoExchangeBuffer(S7Object Client, void *pUsrData, int *Size);
this.Err:=DllCall(Snap7.hCli_IsoExchangeBuffer
,"Ptr",this._obj
,"Ptr",&pUsrData
,"Ptr",&Size)
Size:=numget(Size,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_IsoExchangeBuffer function`nSize`t" Size
this._sub()
}
return this.Err
}
; Returns the last job execution time in milliseconds.
Cli_GetExecTime(byref Time)
{
if !this.Connected
return this.LastError
;int Cli_GetExecTime(S7Object Client, int *Time);
this.Err:=DllCall(Snap7.hCli_GetExecTime
,"Ptr",this._obj
,"Ptr",&Time)
Time:=numget(Time,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_GetExecTime function`nTime`t" Time
this._sub()
}
return this.Err
}
; Returns the last job result.
Cli_GetLastError(byref LastError)
{
;int Cli_GetLastError(S7Object Client, int *LastError);
varsetcapacity(LastError,8)
DllCall(Snap7.hCli_GetLastError
,"Ptr",this._obj
,"Ptr",&LastError)
LastError:=numget(LastError,0,"Int")
; if (this.Err!=0)
; {
; this.AddText.="Cli_GetLastError function`n"
; if this.ShowErrors
; this.Msg(this.LastErrorText)
; }
; return this.Err
}
; Returns info about the PDU length.
; Remarks
; During the S7 connection Client and Server (the PLC) negotiate the PDU length.
; PDU requested can be modified with Cli_SetParam().
; It’s useful to know the PDU negotiated when we need to call Cli_ReadMultivar() or
; Cli_WriteMultiVar().
; All other data transfer functions handle by themselves this information and split
; automatically the telegrams if needed.
Cli_GetPduLength(byref Requested,byref Negotiated)
{
;int Cli_GetPduLength(S7Object Client, int *Requested, int *Negotiated);
this.Err:=DllCall(Snap7.hCli_GetPduLength
,"Ptr",this._obj
,"Ptr",&Requested
,"Ptr",&Negotiated)
Requested:=numget(Requested,0,"Int")
Negotiated:=numget(Negotiated,0,"Int")
if (this.Err!=0)
{
this.AddText.="Cli_GetPduLength function`n"
if this.ShowErrors
this.Msg(this.LastErrorText)
}
return this.Err
}
; Returns a textual explanation of a given error number.
; Remarks
; This is a translation function, so there is no need of a client handle.
; The messages are in (internet) English, all they are in s7_text.cpp.
Cli_ErrorText(Error,byref Text)
{
;int Cli_ErrorText(int Error, char *Text, int TextLen);
VarSetCapacity(Text,1024)
DllCall(Snap7.hCli_ErrorText
,"Int",Error
,"Ptr",&Text
,"Int",1024)
while(code:=numget(Text,a_index-1,"char"))
tmpText.=Chr(code)
Text:=tmpText
; if (this.Err!=0)
; {
; this.AddText.="Cli_ErrorText function`n"
; if this.ShowErrors
; this.Msg(this.LastErrorText)
; }
; return this.Err
}
; Returns the connection status
; Remarks
; IsConnected is 0 if the client is not connected otherwise contains an integer !=0.
Cli_GetConnected(byref IsConnected)
{
;int Cli_GetConnected(S7Object Client, int *IsConnected);
varsetcapacity(IsConnected,8)
DllCall(Snap7.hCli_GetConnected
,"Ptr",this._obj
,"Ptr",&IsConnected)
IsConnected:=numget(IsConnected,0,"Int")
; if (this.Err!=0)
; {
; this.MsgAddText:="Cli_GetPduLength function`n"
; if this.ShowErrors
; this.Msg(this.LastErrorText)
; Err:=this.LastErrors
; if Err[1]
; this.Cli_Disconnect()
; }
; return this.Err
}
Connected[]
{
get
{
this.Cli_GetConnected(state)
return state
}
}
;int Cli_SetAsCallback(S7Object Client, pfn_CliCompletion pCompletion, void *usrPtr);
;int Cli_CheckAsCompletion(S7Object Client, int *opResult);
;int Cli_WaitAsCompletion(S7Object Client, int Timeout);
;int Cli_AsReadArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);
;int Cli_AsWriteArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);
;int Cli_AsDBRead( S7Object Client, int DBNumber, int Start, int Size, void *pUsrData);
;int Cli_AsDBWrite( S7Object Client, int DBNumber, int Start, int Size, void *pUsrData);
;int Cli_AsABRead( S7Object Client, int Start, int Size, void *pUsrData);
;int Cli_AsABWrite( S7Object Client, int Start, int Size, void *pUsrData);
;int Cli_AsEBRead( S7Object Client, int Start, int Size, void *pUsrData);
;int Cli_AsEBWrite( S7Object Client, int Start, int Size, void *pUsrData);
;int Cli_AsMBRead( S7Object Client, int Start, int Size, void *pUsrData);
;int Cli_AsMBWrite( S7Object Client, int Start, int Size, void *pUsrData);
;int Cli_AsTMRead(S7Object Client, int Start, int Amount, void *pUsrData);
;int Cli_AsTMWrite(S7Object Client, int Start, int Amount, void *pUsrData);
;int Cli_AsCTRead(S7Object Client, int Start, int Amount, void *pUsrData);
;int Cli_AsCTWrite(S7Object Client, int Start, int Amount, void *pUsrData);
;int Cli_AsListBlocksofType(S7Object Client, int BlockType, TS7BlocksOfType *pUsrData, int *ItemsCount);
;int Cli_AsReadSZL( S7Object Client, int ID, int Index, TS7SZL *pUsrData, int *Size);
;int Cli_AsReadSZLList( S7Object Client, TS7SZLList *pUsrData, int *ItemsCount);
;int Cli_AsFullUpload( S7Object Client, int BlockType, int BlockNum, void *pUsrData, int *Size);
;int Cli_AsUpload( S7Object Client, int BlockType, int BlockNum, void *pUsrData, int *Size);
;int Cli_AsDownload( S7Object Client, int BlockNum, void *pUsrData, int *Size);
;int Cli_AsDBGet( S7Object Client, int DBNumber, void *pUsrData, int *Size);
;int Cli_AsDBFill( S7Object Client, int DBNumber, int FillChar);
;int Cli_AsCopyRamToRom(S7Object Client, int Timeout);
;int Cli_AsCompress(S7Object Client, int Timeout);
GetStr(byref Data,Start,Size)
{
loop,% Size
str.=Chr(numget(&Data,Start+a_index-1,"Char"))
return str
}
SwapData(byref pVar,Size,Offset=0)
{
varsetcapacity(tmpvar,Size+Offset)
loop,% Size
numput(numget(&pVar,Offset+a_index-1,"uchar"),tmpvar,Offset+Size-a_index,"uchar")
loop,% Size
numput(numget(tmpvar,Offset+a_index-1,"uchar"),&pVar,Offset+a_index-1,"uchar")
}
DBRead(DBNumber,Start=0,DataType="Int")
{
switch DataType
{
case "Byte":
Amount:=2
aType:="UChar"
case "Int":
Amount:=2
aType:="Short"
case "Word":
Amount:=2
aType:="UShort"
case "DInt":
Amount:=4
aType:="Int"
case "DWord":
Amount:=4
aType:="UInt"
case "Real":
Amount:=4
aType:="Float"
default: ; Int
Amount:=2
aType:="Short"
}
VarSetCapacity(UsrData,Amount)
Err:=this.Cli_ReadArea(Snap7.S7AreaDB,DBNumber,Start,Amount,Snap7.S7WLByte,UsrData)
if (Err!=0)
return
Snap7.SwapData(UsrData,Amount)
return NumGet(UsrData,0,aType)
}
DBWrite(Value,DBNumber,Start=0,DataType="Int")
{
switch DataType
{
case "Byte":
Amount:=2
aType:="UChar"
case "Int":
Amount:=2
aType:="Short"
case "Word":
Amount:=2
aType:="UShort"
case "DInt":
Amount:=4
aType:="Int"
case "DWord":
Amount:=4
aType:="UInt"
case "Real":
Amount:=4
aType:="Float"
default: ; Int
Amount:=2
aType:="Short"
}
VarSetCapacity(UsrData,Amount)
NumPut(Value,UsrData,0,aType)
Snap7.SwapData(UsrData,Amount)
Err:=this.Cli_WriteArea(Snap7.S7AreaDB,DBNumber,Start,Amount,Snap7.S7WLByte,UsrData)
return Err
}
}