# 6. 编写IoT应用

# 6.1 总述

本软件支持用户创建IoT应用来运行非实时任务,例如读取IEC全局变量的值,向IEC全局变量中写入值,将IEC全局变量保存到本地日志,设置阈值告警或者计算平均值等等操作。

目前IoT程序支持Python3语言。

用户创建工程后,在'其他逻辑'上鼠标右击,选择应用,在弹出的创建非实时应用对话框中输入应用名,即可添加IoT应用;如下图所示:

创建完IoT应用后,工程界面如图所示,图中myIoT是用户自己键入的应用名,下面只有一个名为main.py的python文件,这个是当前应用的主文件,在当前应用上右击,可以添加其他python文件或者文件夹,如下图所示:

# 6.2 Python编程说明

在点击对应的Python文件,将出现Python代码编辑框,在编辑框里可以编辑相应需要执行的python代码。会出现默认代码以及python编程的一些使用说明。

关于Python代码使用说明:

  • python代码使用python3规范;
  • 本软件提供两个python系统库,分别是smec_logging和iec_runtime,分别用来记录python代码运行日志和与IEC全局变量进行交互(获取或者设置IEC全局变量的值);在创建python文件时,系统会自动导入这两个库,用户无需手动导入。
  • smec_logging为标准日志库,库中包含debug,info,error三个方法,可以打印日志,打印的日志在/var/log/smec路径下:
logger = smec_logging("smec_python_log")  # 在/var/log/smec目录下初始化日志文件名为smec_python_log
logger.debug("This is a DEBUG log")       # debug日志
logger.info("This is an INFO log")        # info日志
logger.error("This is an ERROR log")      # error日志
logger.info("This is an INFO log with number and string format. %d-%s", 123, "string")
1
2
3
4
5
  • iec_runtime为获取IEC地址变量的库,可以向IEC全局变量中写值或者从IEC全局变量中读值,按照下面方式使用:
iec = IecRuntime()
bVar = iec.GetIECVars("gvl.bVar")      # 获取IEC中全局变量GVL中名为bVar的变量,其中GVL名与变量名不区分大小写

# 将值12写入IEC中全局变量GVL中名为iVar1的变量
# 写入成功返回True, 失败返回False,其他错误,抛出ValueError异常
ret = iec.SetIECVars("gvl.iVar1", 12)
1
2
3
4
5
6
  • 关于iec_runtime库有以下几点说明:
  • iec_runtime中有一个名为IecRuntime的类,可以使用一个名为ip的参数初始化,ip即为runtime所在设备的IP地址,默认的ip值为"127.0.0.1",即本机IP,例如iec = IecRuntime()或者iec = IecRuntime(ip="192.168.10.238"),后者代表访问下载到IP为 192.168.10.238 的IEC全局变量。
  • IecRuntime类提供两个方法:获取全局变量的值GetIECVars()和设置全局变量的值SetIECVars()
  1. GetIECVars()只有一个参数,只能是字符串、字符串列表、或字符串元组。
  • 当参数为字符串时,代表只获取一个全局变量的值,返回当前获取的全局变量值。例如bVar = iec.GetIECVars("gvl.bVar")
  • 当参数为字符串列表或者字符串元组时,代表只获取一组全局变量的值,返回当前获取的全局变量值列表。例如(arrVar, strVar) = iec.GetIECVars(["gvl.arrVar", "gvl.structVar"])可以同时获取"gvl.arrVar"和"gvl.structVar"两个全局变量的值,分别赋值给 arrVar 和 strVar 变量。
  1. SetIECVars()函数有两个参数,第一个参数为IEC全局变量名,只能是字符串、字符串列表、或字符串元组。第二个参数为全局变量对应需要设置的值,当第一个参数为列表或者元组时,第二个参数也必须是列表或者元组,且其长度要相同。表示设置多个变量的值。设置成功返回True,失败返回False
  • IEC与Python数据类型的对应关系,如下
IEC数据类型 Python数据类型 说明
BOOL bool True或者False
SINT, INT, INT, LINT, USINT, UINT,
UDINT, ULINT, REAL, LREAL
Number 数值类型
STRING String 字符串类型
自定义数组 列表 所有自定义数组都被存放在Python一维列表中,Python列表下表从0开始,元素个数与IEC数组总元素个数相同,
注意:数组元素的值都是字符串表示形式,使用时需要根据实际数据类型做转换,因为Python拿不到数组实际数据类型
自定义结构体 字典 所有自定义结构体存放在Python字典中,字典中的key为IEC结构体元素名,且必须全部大写,字典中value对应IEC结构体元素的值。
注意:结构体元素的值都是字符串表示形式,使用时需要根据实际数据类型做转换,因为Python拿不到结构体元素的实际数据类型
TIME String "T#%dd%dh%dm%ds%gms"格式
DATE String "D#%d-%2.2d-%2.2d"
TOD String "TOD#%2.2d:%2.2d:%2.2d" 或者 "TOD#%2.2d:%2.2d:%09.6f" 格式
DT String "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%2.2d" 或者 "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%09.6f"格式
  • 用户可以使用自己的python库,直接添加其他python文件即可
  • 用户可以自己安装python包,注意:安装python包需要自己在设备上操作,且python包必须用root用户安装
  • 代码可以使用print打印变量,运行时会将其内容返回给IDE, 需要print将实时刷新设置为True,例如:print("Test", flush = True)

# 6.3 下载执行

编写完IoT应用程序后,用户可以选择下载执行,选择当前设备与IoT应用,然后连接设备,然后点击下载按钮即可下载程序,下载完成后即可执行应用。

注意: 连接上设备后,程序就不可更改了,若要更改程序,需要先断开连接。

若有print打印的话,在对应的输出栏中将会看到输出结果。

# 6.4 IoT编程样例

下面这个样例,每隔1s获取当前设备运行的IEC程序的全局变量GVL.iVar的值,并且打印最近十次获得的值的最大值和最近十次值的和,100秒后结束,即获取100个数字,代码如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import time

def CalIecAverageAndMax():
    pointList = []
    iec = IecRuntime()
    for i in range(0, 100):
      iecIntVar = iec.GetIECVars("gvl.iVar")
      time.sleep(1)
      print(i, "-- Get gvl.iVar=", iecIntVar, flush = True)
      if len(pointList) >= 10:
          pointList.pop(0)
      pointList.append(iecIntVar)
      print(i, "-- Max value in last 10 numbers is ", max(pointList))
      sum = 0
      for e in pointList:
          sum = sum + e
      print(i, "-- Sum of the latest 10 numbers is ", sum)

if __name__ == "__main__":
    CalIecAverageAndMax()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23