通过CTAPI和Citect SCADA软件进行数据通讯
官方文档
Citect SCADA 7.20 Technical Reference
参考文献
基于Citect远程控制的变流量堆料控制系统 【王玉增,顾英妮,王维 济南大学,机械工程学院 ,Citect,CTAPI】
正文
组态软件内部变量支持的数据类型

Citect组态软件已被施耐德收购。通过软件提供的API,可以通过高级语言编程和组态软件内部数据点通讯。
下面是一个Python的例子,暂未测试:
https://github.com/mitchyg/Random/blob/master/pyctapi/src/pyctapi.py
#! /usr/bin/python
#
# File: pyctapi.py
# Author: Mitchell Gayner
# Date: 06/08/2009
#
# Desc:
# Wrapper for Citect CTAPI dll
# Compatible with Citect V6.1 DLLs
#
# You must have the following DLLs:
# - CiDebugHelp.dll
# - Ct_ipc.dll
# - CtApi.dll
# - CtEng32.dll
# - CtRes32.DLL
# - CtUtil32.dll
#
import platform
from ctypes import *
import sys if platform.system() != "Windows":
raise OSError class pyCtApi:
def __init__(self, dllPath_ = "C:/citect/bin/"):
#Load required DLLs
CDLL(dllPath_ + '/CiDebugHelp')
CDLL(dllPath_ + '/CtUtil32')
CDLL(dllPath_ + '/Ct_ipc')
self.__libc = CDLL(dllPath_ + '/CtApi')
self.__cn = None # Create connection object def Open(self, address_, username_, password_, mode_ = 0):
"Open connection to running citect process"
if self.__cn != None:
print "Already connected"
return
self.__cn = windll.CtApi.ctOpen(address_, username_, password_, 2) def Close(self):
"Close connection to running citect process"
ct = windll.CtApi.ctClose(self.__cn)
self.__cn = None def Connected(self):
if self.__ExecCicode("Version(0)") != "":
return True
return False def TagReadInt(self, tagName_):
"Read tag from Citect and covert to int"
str = self.__TagRead(tagName_)
#try:
return int(str)
#except:
return -1 def TagReadFloat(self, tagName_):
"Read tag from Citect and covert to float"
str = self.__TagRead(tagName_)
#try:
return float(str)
#except:
return -1 def TagReadStr(self, tagName_):
"Read tag from Citect and covert to string"
str = self.__TagRead(tagName_)
return str def TagWrite(self, tagName_, value_):
"Write value to Citect tag"
ok = self.__TagWrite(tagName_, str(value_))
return ok def ExecuteCicode(self, function_):
return self.__ExecCicode(function_) def __TagRead(self, tagName_):
"PRIVATE: Read tag from Citect tag"
f = create_string_buffer('\000' * 32)
ok = windll.CtApi.ctTagRead(self.__cn, tagName_, byref(f), sizeof(f))
return f.value def __TagWrite(self, tagName_, value_):
"PRIVATE: Write value to Citect tag"
ok = windll.CtApi.ctTagWrite(self.__cn, tagName_, value_)
return ok def __ExecCicode(self, function_, hWin_=0, nMode_=0):
f = create_string_buffer('\000' * 32)
ok = windll.CtApi.ctCicode(self.__cn, function_, hWin_, nMode_, byref(f), sizeof(f), None)
return f.value # TODO LIST:
'''DONE extern HANDLE CTAPICALL ctOpen(LPCSTR,LPCSTR,LPCSTR,DWORD); /* Open CTAPI interface */'''
# extern BOOL CTAPICALL ctOpenEx(LPCSTR,LPCSTR,LPCSTR,DWORD,HANDLE);
# extern HANDLE CTAPICALL ctClientCreate();
# extern BOOL CTAPICALL ctClientDestroy(HANDLE);
'''DONE extern BOOL CTAPICALL ctClose(HANDLE); /* Close CTAPI interface */'''
# extern BOOL CTAPICALL ctCloseEx(HANDLE, BOOL);
# extern BOOL CTAPICALL ctCancelIO(HANDLE,CTOVERLAPPED*); /* cancel pending I/O */
'''DONE extern DWORD CTAPICALL ctCicode(HANDLE,LPCSTR,DWORD,DWORD,LPSTR,DWORD,CTOVERLAPPED*); /* execute cicode */'''
# extern BOOL CTAPICALL ctPointWrite(HANDLE,HANDLE,void*,DWORD,CTOVERLAPPED*); /* write to point handle */
# extern BOOL CTAPICALL ctPointRead(HANDLE,HANDLE,void*,DWORD,CTOVERLAPPED*); /* read from point handle */
# extern HANDLE CTAPICALL ctTagToPoint(HANDLE,LPCSTR,DWORD,CTOVERLAPPED*); /* convert tag into point handle*/
# extern BOOL CTAPICALL ctPointClose(HANDLE,HANDLE); /* free a point handle */
# extern HANDLE CTAPICALL ctPointCopy(HANDLE); /* copy a point handle */
# extern BOOL CTAPICALL ctPointGetProperty(HANDLE,LPCTSTR,void*,DWORD,DWORD*,DWORD); /* get point property */
# extern DWORD CTAPICALL ctPointDataSize(HANDLE); /* size of point data buffer */
# extern DWORD CTAPICALL ctPointBitShift(HANDLE); /* calculate bit shift offset */
# extern BOOL CTAPICALL ctPointToStr(HANDLE,BYTE*,DWORD,BYTE*,DWORD,DWORD); /* format point data to string */
# extern BOOL CTAPICALL ctStrToPoint(HANDLE,LPCSTR,DWORD,BYTE*,DWORD,DWORD); /* format string data into point*/
'''DONE extern BOOL CTAPICALL ctTagWrite(HANDLE,LPCSTR,LPCSTR); /* write to tag */'''
'''DONE extern BOOL CTAPICALL ctTagRead(HANDLE,LPCSTR,LPSTR,DWORD); /* read from tag */'''
# extern BOOL CTAPICALL ctEngToRaw(double*,double,CTSCALE*,DWORD); /* scale from eng to raw */
# extern BOOL CTAPICALL ctRawToEng(double*,double,CTSCALE*,DWORD); /* scale from raw to eng */
# extern BOOL CTAPICALL ctGetOverlappedResult(HANDLE,CTOVERLAPPED*,DWORD*,BOOL); /* get overlapped result */
# extern BOOL CTAPICALL ctEngToRaw(double*,double,CTSCALE*,DWORD); /* scale from eng to raw */
# extern BOOL CTAPICALL ctRawToEng(double*,double,CTSCALE*,DWORD); /* scale from raw to eng */
# extern HANDLE CTAPICALL ctFindFirst(HANDLE,LPCTSTR,LPCTSTR,HANDLE*,DWORD); /* initiate a search */
# extern BOOL CTAPICALL ctFindNext(HANDLE,HANDLE*); /* get the next search item */
# extern BOOL CTAPICALL ctFindPrev(HANDLE,HANDLE*); /* get the prev search item */
# extern DWORD CTAPICALL ctFindScroll(HANDLE,DWORD,LONG,HANDLE*); /* scroll to search item */
# extern BOOL CTAPICALL ctFindClose(HANDLE); /* close a search */
# extern LONG CTAPICALL ctFindNumRecords(HANDLE); /* get the total number of records in the search */
# extern BOOL CTAPICALL ctGetProperty(HANDLE,LPCTSTR,void*,DWORD,DWORD*,DWORD); /* get a named property */
# extern HANDLE CTAPICALL ctListNew(HANDLE,DWORD); /* create poll list */
# extern BOOL CTAPICALL ctListFree(HANDLE); /* free poll list */
# extern HANDLE CTAPICALL ctListAdd(HANDLE,LPCSTR); /* add tag to poll list */
# extern BOOL CTAPICALL ctListDelete(HANDLE); /* delete tag from poll list */
# extern BOOL CTAPICALL ctListRead(HANDLE,CTOVERLAPPED*); /* read poll list */
# extern BOOL CTAPICALL ctListWrite(HANDLE,LPCSTR,CTOVERLAPPED*); /* write poll list item */
# extern BOOL CTAPICALL ctListData(HANDLE,void*,DWORD,DWORD); /* get list data */
# extern HANDLE CTAPICALL ctListEvent(HANDLE,DWORD); /* get list event */
# extern BOOL CTAPICALL ctGetNumberOfLicenses(HANDLE, SHORT*, BYTE); /* Key Check CTAPI interface */
Python代码
通过CTAPI和Citect SCADA软件进行数据通讯的更多相关文章
- SCADA软件整体架构
SCADA软件整体框架如下所示: 1.免费版本可以支持的IO容量为2048点,无运行时间限制. 2.免费版本仅支持本地Runtime运行,CLServer服务器只能运行24小时. 3.免费版本支持的驱 ...
- 1-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(来看一下怎么样监听网络数据,监听电脑上位机软件的数据)
首先安装网络监听软件 运行这个软件 这个软件安装到电脑上,默认是监听咱电脑上的网络通信 咱们先监听电脑的软件的网络通信数据,然后再说怎么监听Wi-Fi和APP的软件的网络通信数据 咱就监听咱基础篇的 ...
- R软件导入数据_r语言怎么导入数据_R软件导入数据
R软件导入数据_r语言怎么导入数据_R软件导入数据 R软件导入数据 1.Rcmdr安装包导入数据: 1.安装Rcmdr包,输入: install.packages("Rcmdr") ...
- WinCE数据通讯之SqlCE数据同步篇
上一篇总结了WinCE通过WebService进行数据通讯的交互方式,今天整理个SqlCE数据同步方式的内容.先说下软件环境:终端平台使用WinCE5.0+SqlCE2.0,服务器使用Windows ...
- 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(二)
我们上一篇<基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)>主要讲解了如何搭建一个实时数据通讯服务器,客户端与服务端是如何通讯的,相信通过上一篇的讲解,再配 ...
- 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)
今天没有延续上一篇讲的内容,穿插一段小插曲,WebSocket 实时数据通讯同步的问题,今天我们并不是很纯粹地讲 WebSocket 相关知识,我们通过 WebGL 3D 拓扑图来呈现一个有趣的 De ...
- 通过 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(二)
我们上一篇<基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)>主要讲解了如何搭建一个实时数据通讯服务器,客户端与服务端是如何通讯的,相信通过上一篇的讲解,再配 ...
- 【cocos2d-x + Lua(2) C++和lua数据通讯之间的互调】
我们主要解决如下几个问题: 转载注明出处:http://www.cnblogs.com/zisou/p/cocos2dx-lua2.html 1,C++如何获取Lua里面的一个变量值? 2,C++如何 ...
- [转]WINDOW进程间数据通讯以及共享内存
1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...
随机推荐
- 【AOS应用基础平台】完好了AOS标签库,和标准标签库完美兼容了
[金码坊AOS开发平台]今天①完好了AOS标签库,和标准标签库完美兼容了.②新开发了依据子页面动态生成主页面的二级导航菜单功能.#AOS开发平台#
- careercup-栈与队列 3.5
3.5 实现一个MyQueue类,该类用两个栈来实现一个队列. 解答 队列是先进先出的数据结构(FIFO),栈是先进后出的数据结构(FILO), 用两个栈来实现队列的最简单方式是:进入队列则往第一个栈 ...
- ubuntu中安装samba 分类: linux 学习笔记 ubuntu 2015-07-07 16:14 46人阅读 评论(0) 收藏
为了方便的和Windows之间进行交互,samba必不可少. 当然,他的安装使用也很简单: 安装: sudo apt-get install samba sudo apt-get install sm ...
- Android(java)学习笔记187:Android中操作XML数据(使用Pull解析器)
1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...
- JavaScript 应用开发 #4:切换任务的完成状态
在勾选了任务项目左边的对号(复选框)以后,会将任务的状态标记为已完成,取消勾选的话,又会把任务的状态标记为未完成.所以, 我们需要一个可以切换任务完成状态的方法.在任务模型里面,表示任务状态的属性是 ...
- System Operations on AWS - Lab 3W - Managing Storage (Windows)
创建一个名叫Processor的EC2实例,登陆到CommandHost实例,通过AWS CLI对Processor实例的EBS卷做snapshot,设置周期性snapshot的计划任务, 登陆到Pr ...
- USB开发——内核USB驱动+libusb开发方法
linux内核已经具备usb驱动,所以一些设备使用可以免驱,libusb是针对linux内核中ubs驱动的一套api,会自行调用usb驱动接口,并为应用提供api接口,将usb设备开发减少为应用层开发 ...
- JS0热身运动
热身热身小知识点: JS中如何获取元素: 1 通过ID名称来获取:document get element by id -->document.getElementById() 2 .... ...
- MySQL数字类型中的三种常用种类
数字类型 MySQL数字类型按照我的分类方法分为三类:整数类.小数类和数字类. MySQL数字类型之一我所谓的“数字类” 就是指 DECIMAL 和 NUMERIC,它们是同一种类型.它严格的说不是一 ...
- MSSQL存储过程(好久的笔记,翻出来怀念下)
语法结构: create proc 名称 参数列表 as 代码段 调用: exec 存储过程名称 参数列表 要点: .可以使用output修饰参数 .可以使用默认值,注意需要将最后的参数设置成默认值 ...