2019年12月9日
Thingworx的非官方扩展
我们知道PTC提供了官方商城: https://marketplace.ptc.com/
我们从官方商城可以下载很多常用的扩展,如JDBC Connector Extension、PTC ThingWorx-to-Windchill Connector、QRCode等。
这些扩展通常由PTC官方提供,也有一些是第三方的应用或解决方案如Callisto Digital Work Instructions。
但是官方商城的扩展很少。
PTC技术人员在论坛上推荐了另一个非官方扩展下载地址: https://github.com/ptc-iot-sharing
这是发布在github上的,大部分是开源包,基于Java或JavaScript开发,如有很多基于D3引擎开发的图形化数据展示工具。
大家可以尝试一下,当然稳定性方面可能和官方扩展有所差距。
2019年11月13日
Thingworx中的SPC计算工具
Thingworx提供了两个SPC计算工具: StatisticalCalculationThingShape,和StatisticalMonitoringThingShape,但前提条件是需要DescriptiveAnalytics平台。
大致步骤是:
1. 购买安装DescriptiveAnalytics。
2. 建立Thing,配置Data Shape和Value Stream,设置数值属性logged。
3. 调用StatisticalCalculationThingShape.QueryTimedValuesForProperty生成TimedValues类型的InfoTable。
4. 调用StatisticalCalculationThingShape.CalculateMeanValue等函数生成具体的SPC数值。
这种方式适用于工艺参数采集,即Thing和Property均已事先定义的情况下。
如果不采用DescriptiveAnalytics平台,或者说数据不适合用Value Stream记录(比如直接从拧紧枪数据库查询数据),那么就需要自己计算SPC了。
具体步骤为:
1. 经由数据库查询等方式生成InfoTable类型的数据集。
2. 调用infotable for loop方法,逐行读取并分析数据,计算最大值、最小值、平均值。
3. 利用数组暂存数据,然后读取数组,计算标准方差。不用数组的话,也可以将InfoTable重新读取一次。
4. 输出InfoTable类型的数据集。
以下是参考代码:
------------------------------------------------
// Get USL&LSL
var USL = spcTable.rows[0].USL;
var LSL = spcTable.rows[0].LSL;
//logger.info("USL="+USL);
//logger.info("LSL="+LSL);
// Get Sum
var sum = 0.0;
var spc1 = []; // array of spc1
var tableLength = spcTable.rows.length;
//logger.info("tableLength="+tableLength);
for (var x=0; x < tableLength; x++) {
var row = spcTable.rows[x];
spc1[x] = row.SPC1;
//logger.info("spc1="+row.SPC1);
sum = sum + row.SPC1;
}
//logger.info("x="+x);
//logger.info("sum="+sum);
//var result = sum;
// Get Average
var u = sum / tableLength;
//logger.info("u="+u);
// Get SD
var sd = 0;
for (x=0; x < tableLength; x++) {
sd = sd + (spc1[x]-u) * (spc1[x]-u);
}
sd = sd/(tableLength-1);
sd = Math.sqrt(sd);
//logger.info("sd="+sd);
// Get CPU
var cpu = (USL-u)/(3*sd);
//logger.info("cpu="+cpu);
// Get CPL
var cpl = (u-LSL)/(3*sd);
//logger.info("cpl="+cpl);
// Get CPK
var cpk = 0;
if(cpu < cpl) {
cpk = cpu;
} else {
cpk = cpl;
}
//logger.info("cpk="+cpk);
// Output data
var params = {
infoTableName : "InfoTable",
dataShapeName : "DS_SPC_CPK_OUT"
};
// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(DS_SPC_CPK_OUT)
var spcOut = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params);
spcOut.AddRow({Sum:sum, Avg:u, SD:sd, USL:USL, LSL:LSL, CPU:cpu, CPL:cpl, CPK:cpk, Qty:tableLength});
var result = spcOut;
------------------------------------------------
2019年11月4日
关于SQL SERVER的两个备忘
最近在用SQL SERVER做数据的后台自动处理,然后利用Thingworx展现。
这其中碰到两个问题,觉得较有代表性,在此做个备忘。
1. 关于游标内调用其它游标
我之前做过很多项目采用ORACLE数据库,其动态游标、物化视图、数组的功能非常NB,给我留下了深刻的印象。
但是我没想到在使用SQL SERVER游标时却踩到了坑。
SQL SERVER有一个全局变量@@FETCH_STATUS用来表示游标的状态,0表示尚未结束,-1表示已结束。
但是关键@@FETCH_STATUS是全局变量,这就意味着当第一个游标尚未结束时,当第二个游标的状态=-1时,也会将第一个游标强行结束。
解决的办法是用一个本地的变量,把@@FETCH_STATUS的值赋给此变量后再进行检查。
但是此办法逻辑上并不完备,如果有大量的并发,则可能会造成冲突。
因此如果需要配置后台任务,应该尽可能在时间上分散开来,以避免并发。
下面是相关的参考代码:
---------------------------------------------------------------------------
-- Normally, we use system variable @@FETCH_STATUS to check Cursor loop
DECLARE myCursor CURSOR FOR
SELECT fields FROM Table;
OPEN myCursor;
FETCH NEXT FROM myCursor INTO @myVar;
WHILE @@FETCH_STATUS = 0
BEGIN
--DO somthing;
END
CLOSE myCursor;
DEALLOCATE myCursor;
-- But @@FETCH_STATUS is global variable
-- So if we use another Cursor within the loop, when inner loop is completed, @@FETCH_STATUS = -1, so the outer loop will also be closed.
-- Fixing method is to use local variable instead of @@FETCH_STATUS
DECLARE myCursor CURSOR FOR
SELECT fields FROM Table;
OPEN myCursor;
FETCH NEXT FROM myCursor INTO @myVar;
SET @Outer_loop = @@FETCH_STATUS;
WHILE @Outer_loop = 0
BEGIN
--inner loop here
DECLARE myCursor2 CURSOR FOR
SELECT fields FROM Table2;
OPEN myCursor2;
FETCH NEXT FROM myCursor2 INTO @myVar2;
SET @Inner_loop = @@FETCH_STATUS;
WHILE @Inner_loop = 0
BEGIN
--Inner loop function
FETCH NEXT FROM myCursor2 INTO @myVar2;
SET @Inner_loop = @@FETCH_STATUS;
END
CLOSE myCursor2;
DEALLOCATE myCursor2;
FETCH NEXT FROM myCursor INTO @myVar;
SET @Outer_loop = @@FETCH_STATUS;
END
CLOSE myCursor;
DEALLOCATE myCursor;
---------------------------------------------------------------------------
2. 关于关联字符集
由于数据库权限方面的限制,我在一个项目中需要对两个数据库中的表进行关联查询,然后碰到了字符集不匹配的报错。
具体的情况是这样的: 数据库DB1采用了GB字符集,数据库DB2采用了LATIN字符集,两个库的表T1和T2通过step_id进行JOIN,而step_id的数据类型是NVARCHAR,因此JOIN失败。
这是因为对于字符串类对象,虽然表示同样的值,当采用不同的字符集时,其存储时的值是不同的。
这个CASE给我的启示是,任何可能用于JOIN或外部引用的对象,要尽可能采用整型数据类型。
事实上,对于数据库来说,整型和日期型数据的检索速度是最快的,当有JOIN、分组查询、外部引用时,要尽可能使用整型数据。
2019年10月15日
Thingworx中跑马灯和自动换页效果的实现
我们知道,在传统SCADA中,跑马灯和自动换页都是常用的功能。
跑马灯可以显示长的消息,还可以起到醒目的效果。
自动换页可以轮流显示不同区域的画面,也可以在正常和异常画面之间进行切换。
但是在Thingworx中并没有对应的widget,但是我们可以通过变通的方式实现,下面讲讲具体方法。
1. 跑马灯
从8.4版本开始,Thingworx Mashup支持keyframes效果,如以下Custom CSS代码:
-----------------------------------------------
@keyframes marquee {
0% { left: 0; }
100% { left: -100%; }
}
#root_label-3 {
animation: marquee 5s linear infinite;
background-color: #eee;
color: red;
}
#root_valuedisplay-4 {
animation: marquee 10s linear infinite;
background-color: #eee;
color: red;
}
-----------------------------------------------
上述代码表示Label-3及Valuedisplay-4 widget的跑马灯效果,包括时间、颜色等设置。
需要说明的是,时间长度指的是所有字符显示的长度。
Label及Valuedisplay均支持背景色定义。
Label的前景色定义无效,而Valuedisplay的前景色定义有效。
2. 自动换页
Tabs widget支持在不同Tab上显示不同的内容,我们可以利用此特性实现自动换页。
SelectedTabValue和SelectedTabName这两个属性都可以用来操作Tab的选择。
我们可以编写一个计数器(自加1及重置),并配合Auto Refresh widget来得到TabValue。
简要的步骤为:
1) 编写计数器Service。
2) 用Auto Refresh触发计数器。
3) 把计数器的值绑定给SelectedTabValue。
此外,针对正常/异常画面切换,我们可以通过编写Service或Expression的方法来给SelectedTabValue赋值。
跑马灯可以显示长的消息,还可以起到醒目的效果。
自动换页可以轮流显示不同区域的画面,也可以在正常和异常画面之间进行切换。
但是在Thingworx中并没有对应的widget,但是我们可以通过变通的方式实现,下面讲讲具体方法。
1. 跑马灯
从8.4版本开始,Thingworx Mashup支持keyframes效果,如以下Custom CSS代码:
-----------------------------------------------
@keyframes marquee {
0% { left: 0; }
100% { left: -100%; }
}
#root_label-3 {
animation: marquee 5s linear infinite;
background-color: #eee;
color: red;
}
#root_valuedisplay-4 {
animation: marquee 10s linear infinite;
background-color: #eee;
color: red;
}
-----------------------------------------------
上述代码表示Label-3及Valuedisplay-4 widget的跑马灯效果,包括时间、颜色等设置。
需要说明的是,时间长度指的是所有字符显示的长度。
Label及Valuedisplay均支持背景色定义。
Label的前景色定义无效,而Valuedisplay的前景色定义有效。
2. 自动换页
Tabs widget支持在不同Tab上显示不同的内容,我们可以利用此特性实现自动换页。
SelectedTabValue和SelectedTabName这两个属性都可以用来操作Tab的选择。
我们可以编写一个计数器(自加1及重置),并配合Auto Refresh widget来得到TabValue。
简要的步骤为:
1) 编写计数器Service。
2) 用Auto Refresh触发计数器。
3) 把计数器的值绑定给SelectedTabValue。
此外,针对正常/异常画面切换,我们可以通过编写Service或Expression的方法来给SelectedTabValue赋值。
2019年10月12日
使用Thingworx监控Kepware OPC和PLC连接状态
PTC Thingworx是当前流行的IoT平台,可以很方便地建立和Kepware OPC Server的通信,在绑定Tag后,也很容易对PLC进行读写。
Manufacturing Apps工具包自带的Controls Advisor,能够监控OPC的实时状态,但遗憾的是,不能监控Device(如PLC)级别的状态。
但是我们可以利用Thingworx平台已有的功能,通过自建Thing和Mashup进行监控,下面进行简单的说明。
1. 监控Kepware OPC Server:
1) 在Controls Advisor中,新建Gateway Server。
2) Thingworx将自动创建同名的Industrial Thing,template = PTC.Factory.KepServerThingTemplate。
3) Thingworx也将自动创建Industrial Connection,文件名后缀增加-GW, template = IndustrialGateway。
4) 我们可以利用这两个Thing的isConnected属性来监控Kepware。
2. 监控设备Device(PLC):
1) 在Controls Advisor,点击"Discover Devices",完成以后,Thingworx将为每个设备自动创建一个Thing,
名称 = Gateway名称 + "_" + Channel名称 + "." + Device名称,
template = PTC.Factory.DeviceThingTemplate,
IndustrialThing属性 = Thingworx自动创建的Industrial Connection,
OPCDAThingName属性 = Controls Advisor中创建的Gateway Server
(IndustrialThing只能绑定用户创建的Tag, OPCDAThingName能够绑定系统Tag)
2) Enabled属性表示设备已启用,ErrorState属性表示设备出错,
Enabled = device._System._Enabled
ErrorState = device._System._Error
Manufacturing Apps工具包自带的Controls Advisor,能够监控OPC的实时状态,但遗憾的是,不能监控Device(如PLC)级别的状态。
但是我们可以利用Thingworx平台已有的功能,通过自建Thing和Mashup进行监控,下面进行简单的说明。
1. 监控Kepware OPC Server:
1) 在Controls Advisor中,新建Gateway Server。
2) Thingworx将自动创建同名的Industrial Thing,template = PTC.Factory.KepServerThingTemplate。
3) Thingworx也将自动创建Industrial Connection,文件名后缀增加-GW, template = IndustrialGateway。
4) 我们可以利用这两个Thing的isConnected属性来监控Kepware。
2. 监控设备Device(PLC):
1) 在Controls Advisor,点击"Discover Devices",完成以后,Thingworx将为每个设备自动创建一个Thing,
名称 = Gateway名称 + "_" + Channel名称 + "." + Device名称,
template = PTC.Factory.DeviceThingTemplate,
IndustrialThing属性 = Thingworx自动创建的Industrial Connection,
OPCDAThingName属性 = Controls Advisor中创建的Gateway Server
(IndustrialThing只能绑定用户创建的Tag, OPCDAThingName能够绑定系统Tag)
2) Enabled属性表示设备已启用,ErrorState属性表示设备出错,
Enabled = device._System._Enabled
ErrorState = device._System._Error
2019年7月30日
ThingWorx Service: InfoTable2CSV
编写了一个通用程序,能够将InfoTable转换成CSV格式,用于Dygraph展示数据。
----------------------------------------------------------------------
// InfoTable2CSV: Service to convert InfoTable to CSV, to display data into Dygraph widget
// Input: myInfoTable:InfoTable without DataShape
// Output: TEXT
// Note 1: The name of Datetime field is always 'TIME', which is 1st field for Dygraph
// Note 2: TIME values will be converted into dateFormatISO to match Dygraph requirement
var iLF;
var tmp = 'TIME';
var i = 0;
var fd = []; // array to store Fields
fd[0] = 'TIME';
// Get CSV Header
if ((myInfoTable.dataShape===null)||(myInfoTable.dataShape===undefined)) {
iLF = myInfoTable.ToJSON().dataShape.fieldDefinitions;
} else {
iLF = myInfoTable.dataShape.fields;
}
for (var key in iLF) {
if(key != 'TIME') {
i = i + 1;
fd[i] = key; // Store field sequence
tmp = tmp + ',' + key;
}
//Logger.info("Field Name "+key+" baseType: "+iLF[key].baseType);
}
tmp = tmp + ' \n';
// Get CSV Data
var tableLength = myInfoTable.rows.length;
for (var x=0; x < tableLength; x++) {
var row = myInfoTable.rows[x];
tmp = tmp + dateFormatISO(row.TIME); // Get TIME Value
var fd2 = []; // To output data in sequence
for (var property in row) {
tmp2 = property; //row property
tmp3 = row[property]; //row value
var j = fd.indexOf(tmp2);
fd2[j] = tmp3;
}
for (var k=1; k
tmp = tmp + ',' + fd2[k];
}
tmp = tmp + ' \n';
}
var result = tmp;
----------------------------------------------------------------------
2019年7月26日
ThingWorx Dygraph研究
ThingWorx Manufacturing Apps的trending and troubleshooting功能提供了趋势分析工具,能够将根据时间序列存储的数据予以动态展示。
此功能在Mashup中对应的Widget是Dygraph Widget,是基于开源的dygraphs实现的。
下面说一下在ThingWorx中应用Dygraph的注意事项。
1.
Dygraph的数据源即JSONData
此属性有一定的误导性,说是JSONData,但其实是csv格式的长字符串。
Csv格式就是带分隔符的文本文件,通常用“,”或”;”分隔;第一行定义表头,从第二行开始定义数据。
一些注意事项:
1)
表头的字段之间用”,”分隔,以“\n”换行;
2)
第一个字段必须是时间,对应于Dygraph的横坐标;
3)
其它的字段对应DataLabel1~DataLebel6;
4) 从第二行开始,即数据存储区,字段之间以“,”分隔,最后以”\n”换行。
2.
如果数据的原始格式是InfoTable,则必须先转换成csv
比如我们想从外部的实时数据库抽取数据,则必须在查询后进行转换才能使用。
通常在ThingWorx中,查询输出的格式是InfoTable,而InfoTable的实际格式是JSON。
对于此类数据,则必须自己编写Service进行转换,之后才能bind给Dygraph使用。
在编写Service时,注意Output类型是TEXT。
转换代码示例:
------------------------------------------------------
var tmp = 'TIME,OEE \n'; //表头
var tmp1 = ''; //存储第1个字段
var tmp2 = ''; //存储第2个字段
var tableLength = IT1.rows.length; //IT1是输入的InfoTable
for (var x=0; x < tableLength; x++) { //从InfoTable中逐行取值
var row = IT1.rows[x];
tmp1 = dateFormatISO(row.TIME); //转换时间格式,这里TIME是第1个字段名称
tmp2 = row.OEE; //这里OEE是第2个字段名称
tmp = tmp + tmp1 + ',' + tmp2 + ' \n'; //生成一行数据记录
}
var result = tmp;
------------------------------------------------------
3.
时间序列的类型必须是ISO TIME
ISO TIME包含了日期、时间、时区的信息,如2019-07-26T01:30:00.000+08:00。
我们可以利用dateFormatISO函数将DateTime类型转换成String类型。
4.
关于取值范围
如果从数据库中查询,然后转换成CSV使用,则要在Service Info中配置Max Rows,即返回的查询结果记录数,对应于SQL中的TOP/LIMIT条件,默认值是500。
5.
更多Dygraph信息参考
可参考ThingWorx Apps自定义指南的第21章-Dygraph小组件。
2019年7月10日
ThingWorx的大数据分析工具
ThingWorx是目前较为流行的工业物联网数据集成、分析、开发平台。
在业务方面,工艺实时数据有较大的分析价值,也符合大数据的分析特点。
本文介绍一下其大数据分析工具。
1.
数据存储
要对实时数据进行大数据分析,需要在创建Thing的时候满足以下条件:
1)
为Thing指定Value Stream
Value Stream是存储数据的实体,其配置的Persistence Provider对应物理数据库,可以是内置的ProgreSQL数据库,也可以是支持ODBC的其它主流数据库。
2)
对于要追踪的属性打勾Logged选项
此选项在属性的值发生变化时,自动向Value Stream插入记录。
在PostgreSQL中使用以下SQL可以查询数据:
---------------------------------------------------------------------
SELECT * FROM value_stream
WHERE ENTITY_ID =
'ValueString_KBSZ_MM' -- Value
Stream Name
AND source_id =
'KBSZ_DEMO_MM21_THING' -- Thing
Name
AND PROPERTY_NAME =
'Main_Speed' -- Property Name
AND TIME >
to_timestamp(EXTRACT(EPOCH FROM NOW())- 2*24*3600) -- 2 days earlier till now
ORDER BY time --DESC
---------------------------------------------------------------------
2.
数据分析工具之Time Series Chart
要将Thing的Property数值传递给Mashup,通常通过这2个Service:GetProperties和QueryPropertyHistory,前者传递当前值,后者传递历史数据。
QueryPropertyHistory有以下几个输入参数:
-
startDate,起始时间
-
endDate,结束时间
-
maxItems,记录数,相当于SQL中的TOP/LIMIT
-
oldestFirst,排序方式,相当于ORDER BY TIME ASC
-
query,过滤条件,相当于追加WHERE语句
然后把输出条件中的All Data绑定到Time Series Chart的DataSource,然后设定:
-
NumberOfSeries,参数个数
-
DataSourceX.DataFieldX,纵坐标,选择对应的Property
-
DataSourceX.XAxisFieldX,横坐标,选择timestamp
需要说明的是,QueryPropertyHistory返回的是符合条件的查询结果数据集,因此结果集越大,查询越慢。
此外,Time Series Chart加载了QueryPropertyHistory结果集的所有数据,因此结果集越大,显示越慢。
因此,要慎重设定查询参数,特别是startDate/endDate/maxItems。
3.
数据分析工具之Dygraph Chart
PTC ThingWorx Manufacturing Apps提供了PTC.Factory.TrendManagementUtils,其GetJSONStringTrendHistory方法可以将属性的历史值转换成JSON格式。
然后配合Dygraph Chart,可以实现数据的动态加载。
具体实现方式为:
1)
在Manufacturing App的trending and troubleshooting设定追踪项,记录Trend
Name。
2)
在Mashup中加载GetJSONStringTrendHistory方法,将displayId设为步骤1的Trend Name。并设置startDate/endDate等其它参数。
3)
在Mashup中将GetJSONStringTrendHistory绑定到dygraphchartwidget,将Data映射为JSONData,将TrendNameX映射为DataLabelX。
我们注意到,在GetJSONStringTrendHistory方法中并没有maxItems参数,在dygraphchartwidget中也不可设置时间。
这是因为GetJSONStringTrendHistory查询得到了所有符合条件的数据集,此数据集以JSON字符串的形式予以输出。
而dygraphchartwidget得到JSON数据后,根据数据的特点动态地予以展示,因此数据集的大小不会影响显示的时间。
我们从PTC的文档可以看到,Dygraph
Chart采用了开源的JavaScript库dygraphs,具体使用可参考ThingWorx Apps自定义指南的第21章。
2019年7月2日
谈谈840D机床的联网
SINUMERIK 840D(SL)是西门子广受好评的CNC自动化控制系统,它和SINAMICS S120内置式变频器组合,广泛应用于高端机床和加工中心。
近几年来,随着工业互联网和工业4.0的发展,对机床联网以实现监控和数采的需求也越来越多。
本文试谈谈840D机床的联网。
一、硬件
840D(SL)的控制单元(Control
Unit)包括:NCU、PCU、TCU。
NCU即Numeric Control
Unit(数控单元),是控制系统的核心。
NCU又包含了Linux内核、PLC CPU、PLC通信卡(840D
SL)等模块。
其中Linux内核从CF卡加载,PLC CPU采用S7-300标准PLC,PLC通信卡即CP343-1系列通信模块。
PCU即PC Client
Unit(PC客户端),采用工业PC,内置Windows或Linux操作系统。
TCU即Thin Client
Unit(瘦客户端),通过VNC软件远程运行Linux内核程序。
二、联网
840D包含了MPI、ProfiBus等接口。其中ProfiBus又包括DP Integrated、DP Master接口。DP Integrated是内核与SINAMICS S120通信的专用接口,DP Master用于连接外围设备如PCU、TCU、远程I/O等。MPI是编程专用接口。
除了以上接口外,840D SL还增加了ProfiNet(X150)、EtherNet(X120/X127/X130)接口。
ProfiNet可连接工业交换机、远程I/O等,其默认IP地址是192.168.0.1。
X120用于连接PCU、TCU,其默认IP地址是192.168.214.1。
X127用于连接工程师电脑,来进行PLC组态及下载,其默认IP地址是192.168.215.1。
X130用于连接工厂网络(IT网络),通常接到IT交换机上,由IT交换机分配IP地址。
因此对于840D SL,我们可以直接将X130接入IT网络,以实现机床的联网。
而840D NCU并没有提供以太网口,要联网可以采用以下两种方式。
方式1:增加CP343-1通信模块。
CP343-1是S7-300系列PLC的以太网通信模块,在组态后,可以为PLC CPU分配一个以太网IP地址。此模块性能好非常稳定,但是需要组态及下载PLC,价格也较高,单价1万多。
方式2:增加MPI-EtherNet转换头。
德国Hilscher公司提供了NetLink商标的MPI-EtherNet转换头,能够将MPI协议转换成S7 TCP/IP协议,且无须组态,价格约4000元。NetLink提供了一个网页服务器,用于配置MPI参数和IP地址。替代产品有德国Deltalogic的NetLink和国内大连德嘉的ETH-MPI(DP)。
三、应用
从840D(SL)的硬件我们可以看出,机床的控制分为文件控制和逻辑控制两大块,文件控制通过Windows/Linux操作系统实现,逻辑控制通过PLC实现。
因此,IT系统在与机床联网时,可以进行针对性的设计。
如果我们要向机床传加工程序,或者采集加工日志,则可以通过操作系统实现,比如文件共享、FTP、串口连接等。
如果我们要采集机床的状态、故障、工艺参数,则可以通过PLC实现,比如通过Kepware连接NCU PLC,或者通过OPC Client连接机床内置的OPC-UA服务器。
2019年3月7日
ThingWorx开发小结
最近一段时间尝试了下用ThingWorx做开发,下面是一些心得和小结。
1、ThingWorx作为IoT平台(Connectivity+Thing)
ThingWorx整合了Kepware,作为ThingWorx Connectivity部署。
Kepware的PLC驱动可以快速配置,实现和主流PlC的双向通信。
Kepare的IoT Gateway提供了Rest Server/Rest Client/MQTT Client这3种代理,实现和IT系统的通信。
ThingWorx内置了一个OPC Client,叫做Industrial Connection,可以通过Discover工具实现对OPC目录和TAG的浏览和绑定,非常方便。
由于Kepware同是PTC的产品,因此和ThingWorx的整合是相当深入的,只需要在Kepware中做一些简单的配置,就可以在ThingWorx中调用OPC,这一点比起其它SCADA产品方便得多。
最大的缺点是不支持对OPC TAG的动态名称调用。
我们知道OPC TAG是一个字符串形式的内存变量,可以通过拼接的形式得到完整的TAG名称,象GE Cimplicity和Ignition都支持对OPC TAG的动态读写,这样可以通过编写服务来重复调用、简化代码。
而ThingWorx的核心是Thing这个对象,OPC TAG是作为一个绑定的远程变量附加到某一个属性上的,因此每一个TAG都是独立管理的。
从PTC ThingWorx Manufacturing Apps的代码(Controller.UpdateProperty)我们也可以看出,ThingWorx是作为REST Client来实现动态回写OPC的(与Kepware的Rest Server通信)。
2、ThingWorx作为数据展示平台(Mashup)
展示方面,ThingWorx提供了Mashup、Gadgets、Style、State等工具。
其优点是美观、现代化,IT工程师开发起来顺手。
相比较而言,ThingWorx适用IT工程师开发,而传统SCADA适合控制工程师开发。
为什么这么说呢?
一个重要的原因是,ThingWorx是基于JAVA开发的,因此有大量的配置、继承。
比如Menu菜单、Media图片、Style样式、State数据规划,这些都是独立的对象,Mashup只能引用。
举个简单的例子,你想要把字体放大一号,你必须新建一个Style,然后在Mashup中引用。
这些对于JAVA工程师来说不以为怪,但是对于工控工程师来说就很头大了。
此外,ThingWorx自带的一些Widgets也不是很成熟,如:Label的字体最小号是9px,饼图不能显示数值和百分比,柱状图的文字长度受限等。
3、ThingWorx作为客户端(Mashup)
ThingWorx是B/S架构的,因此其客户端相当于运行一个Mashup实例。
但是Mashup本身不具备任何的逻辑处理能力,只有基本的复位数据等固定功能。
在ThingWorx中,只有Thing是真正的逻辑实体,所有业务逻辑都是通过Service传递给Mashup的。
因此,任何客户端的业务逻辑,都必须绑定远程的Thing.Service来予以实现。
举个简单的例子,客户端采集到条码后要进行有效性校验,但是客户端不能执行校验逻辑,必须调用服务端的逻辑实现,其路径是:JavaScript/Query --> Service --> Thing --> Mashup.
目前JAVA和B/S能在互联网大行其道,一个重要原因是允许客户端JavaScript的执行,甚至衍生出了前端程序员这个工种。
但是ThingWorx不支持客户端JavaScript调用,是其一个较大的局限。
4、ThingWorx作为集成开发环境(Platform)
我们可以把ThingWorx作为一个简化的集成开发环境,它对JavaScript/SQL的支持非常好,开发也非常方便。
下面谈几点短板。
我们知道,和JAVA相比,.Net是一个半C/S、半B/S的架构,因为.Net客户端可以通过.Net Framework来调用系统dll,从而得到OS操作权限及实现分布式架构。
比如,.Net客户端可以调用本地opc client直接和opc server通信,这样通信的链路就分散开来,减少了服务端专用opc client的阻塞和性能需求。
而ThingWorx基于Java开发,是典型的B/S架构。而JAVA基于安全的考虑,服务器是不具备操作系统权限的。
以文件操作为例,ThingWorx定义了一个文件存储的根目录,所有ThingWorx管理的文件必须在此目录下。因此,ThingWorx不能处理服务器上其它目录的文件,也不能处理局域网内通过文件夹共享的文件。
因此,我们必须通过MQTT、FTP等方式来处理远程文件。
ThingWorx提供了一个FTP Client扩展,但是坑爹的是只提供文件读、写功能,不能执行删除操作。
那么假设我们需要从某台设备PC采集文件数据,怎么操作比较方便呢?我们需要在ThingWorx上建立一个FTP SERVER,然后把ThingWorx文件子系统映射成FTP虚拟子目录,然后在设备PC上通过FTP CLIENT上传数据; 然后在ThingWorx文件子系统进行文件的读写。
ThingWorx还有一个缺点是对项目的管理不是很完善。比如说,我们有很多Media/Style/State,会需要在许多项目中使用,但是这些对象只能绑定到一个Project,这就不是很合理了。
此外,Service的调试是不支持中断的,要调试代码,必须自己写LOG,然后在Monitoring中查看日志。
订阅:
评论 (Atom)





