一:特殊要注意
1.安装程序要安装到C盘;
2.项目新建要C盘;
3.项目创建时语言要选英文跟简体中文(按住shift可实现多选),且要选择Use NGA;
4.工程名称要规范,要按照结构来,如:FMCS_JM_CR
FMCS_JM_OCC…
5.驼峰式命名:string getValue;float setPoint; float getCurrentValue;…;
4.模版panel传参 System1:d1 系统名+:+变量名;
5.滑块使用时要将滑块属性/扩展/tracking的值变成false,优化性能,实现停止拖动再去执行动作;
6.创建了库文件需要重载;修改了脚本文件需要重启Control Manager
7.LIB319/tools/PT.xml保存到本地后,修改代码行
//修改前
string folderPath = getPath(PANELS_REL_PATH) + gs_sys_path + "/";
//修改后
string folderPath = getPath(PANELS_REL_PATH) + gs_sys_path + "/"; 为
7.配置文件LIB319需要在下面 CN319在上面
二:常用快捷键
ctrl+D 快速注释代码
ctrl+shift+D 快速解开注释
ctrl+E 查看panel的脚本代码
三:常用函数
1.截取字符串
string name= dpSubStr(dpe,DPSUB_SYS_DP); //DPSUB_SYS_DP(dpe);截取
2.DP值读写
//读dp
dpGet(subName + ".response.actvalue", actValue);
//写dp
dpSet(subName + ".response.actvalue", actValue);
3,监听某个值变化
//添加监听方法
dpConnect("doMethord","System1:d1.command.setpoint");
//回调函数
doMethord(string dpe,float setPoint)
{
DebugN("setPoint:"+setPoint);
DebugN("dpe:"+dpe);
string pname= dpSubStr(dpe,DPSUB_SYS_DP); //DPSUB_SYS_DP(dpe);
DebugN("subName:"+pname);
float actVal;
//先将actValue值取出来
dpGet(pname+".response.actvalue",actVal);
DebugN("actVal:"+actVal);
//设置run的值为false
dpSet("System1:d1.response.state.run",true);
while((int)actVal<(int)setPoint)
{
//如果当前值小于设定值,则将当前值++,增加开度
actVal++;
dpSet(pname+".response.actvalue",actVal);
delay(0.25);
}
while((int)actVal>(int)setPoint)
{
//如果当前值小于设定值,则将当前值--,减小开度
actVal--;
dpSet(pname+".response.actvalue",actVal);
delay(0.25);
}
dpSet("System1:d1.response.state.run",false);
}
4.获取dpe的描述
string dpname = $DP;
string desc;
//获取描述,后面必须有那个点
desc= dpGetDescription(dpname+".");
DebugN(desc);
this.text=desc;
四:多线程使用
//1.定义一个线程对象
global mapping threadId;
/**
添加了manager后如果要修改这个文件,必须要重启manager,不然修改内容不会生效!!!!
*/
main()
{
string sql = "SELECT '_original.._value' FROM '*.command.setpoint'";
//第一个参数:回调函数; 第二个参数是否需要应答默认true(不要加双引号) 第三个参数:默认 anything 第四个参数:sql语句
dpQueryConnectSingle("doMethordAnsy", true, "anything", sql);
}
//多线程方法
//多个点通过查询遍历操作(单线程)
// userData: 默认anything dyn:一维动态数组,例如: dyn_string(string类型的数组) dyn_dyn_ 二维动态 ,如果不知道是什么类型后面跟anytype
doMethordAnsy(string userData, dyn_dyn_anytype table)
{
DebugN("开始多线程回调");
string key;
//注:此次计数是从1开始的,第一行是title,第二行才是数据[行跟列都是从1开始计数]
for (int i = 2; i <= dynlen(table) ; i++)
{
float setPoint = table[i][2];
key = dpSubStr(table[i][1], DPSUB_SYS_DP);
synchronized(threadId)
{
if (mappingHasKey(threadId, key))
{
stopThread(threadId[key]);
}
//(跟培训不一样)此处验证过,不需要传userdata 只传有用参数即可
threadId[key] = startThread("repeat", setPoint, key);
}
}
DebugN("结束多线程回调");
}
repeat(float setPoint, string key)
{
DebugN("进入到多线程内部");
//DebugN("userData:" + userData);
DebugN("setpoint:" + setPoint);
DebugN("key:" + key);
float actValue;
dpGet(key + ".response.actvalue", actValue);
DebugN("actValue:" + actValue);
while ((int)actValue < (int)setPoint)
{
//如果当前值小于设定值,则将当前值++,增加开度
actValue++;
dpSet(key + ".response.actvalue", actValue);
delay(1);
}
while ((int)actValue > (int)setPoint)
{
//如果当前值小于设定值,则将当前值--,减小开度
actValue--;
dpSet(key + ".response.actvalue", actValue);
delay(1);
}
synchronized(threadId)
{
mappingRemove(threadId,key);
DebugN("终止线程");
}
DebugN("结束多线程内部处理");
}
五:用户权限
1.首先需要创建用户组,在用户组中添加组权限;其中权限有32个位可以用,1-5为系统默认使用。
2.创建用户,将用户添加到用户组中;
3.修改代码,添加按钮权限判断
main()
{
//在页面初始化时判断用户是否存在按钮点击权限
//之所以用dpConnect是因为需要判断用户变化时就要修改权限;方式切换用户导致权限只判断一次
dpConnect("checkPermission",myUiDpName()+".UserName");
}
checkPermission(string dp,string username)
{
btnopen.enabled = getUserPermission(6);
btnclose.enabled = getUserPermission(6);
}
六: 报警等级创建与配置
1.打开DP配置,选择【内部DP】,找到【AlertClass】,右键【创建DP】,输入名称【disaster】后确定;
2.右键【插入配置】,选择【报警类】后点击确定;
3.找到【_alert_class】双击打开编辑面板,如下图进行配置4.找到主DP下的DPE(例如 alarm下的travelimit与tmp),
****4.1 选择travelimit(bool类型)右键【插入配置】,选择【报警/报警可调整:报警类】,点击确定。然后按下图配置即可
***4.2 选择tmpfloat类型)右键【插入配置】,选择【报警/3段报警】,点击确定。然后按下图配置即可
5.将报警信息同步到拓扑图
找到模版panel,选中报警的组件,选中Acknowledge,点击那个小星星,然后将报警点添加,将前缀改为$DP。如下图所示6.打开DP配置/内部DP/SumAlertPanel。这里面就是存在报警的界面的集合,如下图
7.如果步骤6中没有出现报警树,则 打开面板拓扑,点击全部树节点后即可实现汇集到拓扑页面中。
8.添加报警汇总(例:汇总alarm下的报警)
**8.1 找到主DP的alarm,右键【插入配置】,选择【报警/Sumalert汇总报警】后点击确定。
**8.2 不需要设置范围,直接点击报警选项,先选择DP列表找到alarm的地址,然后复制,取消DP列表,将复制内容复制到DP模式后面的输入框,在alarm后面加上【.】表示查询alarm下面所有的报警。然后点击【激活报警】即可。9.将alarm汇总报警关联至页面
打开模版页添加Initialize事件,点击小星星按顺序依次配置,,配置完成后不要忘记修改地址前缀如下图所示
七: 放大缩小到一定比例后显示某内容
不要忘记修改图层
## 七: 放大缩小到一定比例后显示某内容
常用疑问QA
1.Q:在一个panel中存在多个通用模版panel时,如何修改其中某个小属性?
A:点击如图按钮即可对模版中的对象进行操作
2.Q:当多个DP下的DPE要修改,需要一个个修改非常麻烦怎么办?
A:需要创建一个主DP。
1.打开DP配置,找到需要操作的DP,右键选择创建主DP,找到要操作的DPE,右键插入PowerConfig,选择默认值【其中默认值的下拉框选项要选择“默认值”而不是固定,如果选择了固定,子DP的默认值就无法修改】与wincc oa取值范围。
3.Q:如果主DP的配置未应用到子DP中,可以选中主DP的DPE后右键批量应用,如下入所示;
八: 新建库文件(即通用方法库)
1.找到库文件,右键新建CTRL库,如 randomValue.ctl
2.添加一个方法。rand是0-32767,方法实现0-100随机变换
void getRandomValue(string dpe)
{
DebugN("进入到getRandomValue:"+dpe);
float val = rand()/327.67;
dpSet(dpe,val);
DebugN("结束getRandomValue:"+dpe);
}
3.引用库文件,方法
#uses "randomValue.ctl"
main()
{
while (true)
{
DebugN("*******进入到while自动获取random*********");
getRandomValue("System1:d1.command.setpoint");
delay(1);
}
}
4.修改了库文件需要重载一下,不然不生效。