Skip to content

plc.cloud_* — 云平台通信 ​

模块名:plc(云功能是 plc 模块的一组 cloud_ 前缀函数,不是独立模块)

把 PLC 软元件绑定成云端数据点,实现远程监控和远程控制。云连接参数(服务器、设备密钥)由上位机写进 config.lua 后由固件的引导脚本自动 cloud_bind,脚本里通常只需要处理业务数据。

CLOUD_UP / CLOUD_DOWN / CLOUD_AUTO 三种绑定方向对比

函数总览 ​

函数作用
plc.cloud_bind(bind_table)把软元件批量绑定为云端数据点
plc.cloud_publish(...)手动上报若干「名称=值」数据
plc.cloud_subscribe(...)订阅云端数据点
plc.cloud_reg(message_type, callback_function)注册云事件回调
plc.cloud_compute(json_string)把任务交给云服务器执行(如发邮件)
plc.cloud_status读当前的云连接状态(有没有连上、上次心跳多久前)

常量 ​

数据类型(用于 cloud_bind 的 type 字段)

常量值说明
plc.BITE0位(只能绑 X/Y/M/S/T 触点/C 触点)
plc.S16116 位有符号整数
plc.S32232 位有符号整数
plc.FLOAT3单精度浮点

同步方向(用于 cloud_bind 的 mode 字段)

常量值说明
plc.CLOUD_UP0仅上传:本地数据变化时发布到云
plc.CLOUD_DOWN1仅下发:只接收云端写入,不上报
plc.CLOUD_AUTO2双向自动同步(mode 省略时的默认值)

事件类型(用于 cloud_reg 的第一个参数)

常量说明
plc.PUBLISH数据发布成功
plc.SUBSCRIBE订阅成功
plc.COMPUTE云端计算结果返回

plc.cloud_bind ​

lua
plc.cloud_bind(bind_list)

批量把软元件绑定成云端数据点。绑定后由固件按 mode 自动同步,脚本不需要再手动上报。

参数

#参数类型必填默认值说明
1bind_listtable是—数组,每个元素是一条绑定描述,字段见下表

bind_list 每个元素的字段:

字段类型必填默认值说明
namestring是—云端数据点名称
regstring是—软元件地址字符串,如 "D100"、"M0"、"X10"、"C200",大小写均可
typeinteger是—plc.BITE / plc.S16 / plc.S32 / plc.FLOAT
modeinteger否plc.CLOUD_AUTO同步方向

返回值

无返回值。地址非法的条目会被静默跳过,不报错。

示例

lua
plc.cloud_bind({
    { name = "temperature", reg = "D100", type = plc.FLOAT, mode = plc.CLOUD_UP   },
    { name = "humidity",    reg = "D102", type = plc.S16,   mode = plc.CLOUD_UP   },
    { name = "run_flag",    reg = "M0",   type = plc.BITE,  mode = plc.CLOUD_AUTO },
    { name = "setpoint",    reg = "D200", type = plc.S16,   mode = plc.CLOUD_DOWN },
})

说明

  • reg 里的 X/Y 编号按八进制换算("X10" 是十进制编号 8 的输入点),这与函数式 plc.x(10)(十进制,第 10 号)不一致。绑定 X/Y 时应按面板丝印的八进制编号填写。
  • type 与元件必须匹配,否则该条被跳过:BITE 只能用于 X/Y/M/S/T 触点/C 触点;D/R 不能用 BITE。
  • 各元件在绑定路径下的上限:X/Y ≤ 255、M ≤ 8511、S ≤ 4095、T 触点 ≤ 511、T 当前值 16 位 ≤ 511 / 32 位 ≤ 510、C 触点 ≤ 255、C 当前值 16 位 ≤ 199 / 32 位 200-255、D ≤ 8511。
  • 每处理完一条就会触发一次「完成绑定」,所以一次传完整的列表比多次调用更高效。

plc.cloud_publish ​

lua
plc.cloud_publish(name1, value1, [name2, value2, ...])

手动上报数据点,参数成对出现。适合上报不是直接来自寄存器的计算结果。

参数

#参数类型必填默认值说明
1, 3, 5…namestring是—数据点名称。空串会导致该对被丢弃
2, 4, 6…valueany是"0"数据值,内部统一转成字符串上报

返回值

无返回值。

示例

lua
timer.start(5000, function()
    local t = plc.df(100)
    plc.cloud_publish("temperature", t, "status", t > 80 and "alarm" or "ok")
end)

说明

  • 参数个数为奇数时,最后一个落单的参数被忽略(内部按 参数总数 / 2 取整成对处理)。

实用例程 ​

lua
--订阅云服务器上的两个数据,如果多个在后面增加及可
--当订阅的数据在服务器上有变化时会自动订阅订阅数据的回调函数
plc.cloud_subscribe("stll_3177567_d7000")


ds1= timer.start(5000,function()
sjs=math.random() / 10  --产生一个动态的随机数(变化)
stll =plc.df(7000)+0.95+sjs --0.95为闸门泄放的生态流量,以后闸修复后,重新计算一个值(闸门宽4m有2个闸门共8米)

plc.df(50,stll)
 print ("D50:",plc.df(50))
print ("D10:",plc.dd(10))		
end)
--发布数据,这里模拟定时发送数据到云服务器
--i=0
--j=true;
--定时器=timer.start(2000,function()--定时2秒执行一次
--	if i==0 then i=1
--	elseif i==1 then i=0 end
--	j=not(j)
--	plc.cloud_publish("y1",j)--发布数据,如果多个在后面增加及可 
--end
--)

把上面的地址、主题、引脚替换成你项目里的即可。

plc.cloud_subscribe ​

lua
plc.cloud_subscribe(name1, [name2, ...])

向云端订阅一个或多个数据点。订阅到的值通过绑定关系写入软元件,或在回调里处理。

参数

#参数类型必填默认值说明
1…namestring是—要订阅的数据点名称,个数不限

返回值

无返回值。

示例

lua
plc.cloud_subscribe("setpoint", "alarm_threshold", "remote_cmd")

实用例程 ​

lua
--注册订阅数据回调:另一个PLC (SN3177567)为发电机发电流量+翻坝流量
plc.cloud_reg(plc.SUBSCRIBE,function(name,value)
	print(name,value)
	if name=="stll_3177567_d7000" then plc.df(7000,value) end--如果"y0"数据在服务器上变化,写入到Y0
   print ("D7000:",plc.df(7000))
end
)
--订阅云服务器上的两个数据,如果多个在后面增加及可
--当订阅的数据在服务器上有变化时会自动订阅订阅数据的回调函数
plc.cloud_subscribe("stll_3177567_d7000")


ds1= timer.start(5000,function()
sjs=math.random() / 10  --产生一个动态的随机数(变化)
stll =plc.df(7000)+0.95+sjs --0.95为闸门泄放的生态流量,以后闸修复后,重新计算一个值(闸门宽4m有2个闸门共8米)

plc.df(50,stll)
 print ("D50:",plc.df(50))
print ("D10:",plc.dd(10))		
end)
--发布数据,这里模拟定时发送数据到云服务器
--i=0
--j=true;

把上面的地址、主题、引脚替换成你项目里的即可。

plc.cloud_reg ​

lua
plc.cloud_reg(event, callback)

注册云事件回调。

参数

#参数类型必填默认值说明
1eventinteger是—plc.PUBLISH / plc.SUBSCRIBE / plc.COMPUTE
2callbackfunction是—事件回调。类型不是 function 会直接报错

返回值

无返回值。

示例

lua
plc.cloud_reg(plc.PUBLISH, function(data)
    print("上报成功:", data)
end)

plc.cloud_reg(plc.COMPUTE, function(data)
    print("云计算结果:", data)
end)

说明

  • 回调在 Lua 主线程的消息循环中执行,不要在里面做长阻塞操作。
  • 每种事件只保留最后一次注册的回调。

实用例程 ​

lua
--注册订阅数据回调:另一个PLC (SN3177567)为发电机发电流量+翻坝流量
plc.cloud_reg(plc.SUBSCRIBE,function(name,value)
	print(name,value)
	if name=="stll_3177567_d7000" then plc.df(7000,value) end--如果"y0"数据在服务器上变化,写入到Y0
   print ("D7000:",plc.df(7000))
end
)
--订阅云服务器上的两个数据,如果多个在后面增加及可
--当订阅的数据在服务器上有变化时会自动订阅订阅数据的回调函数
plc.cloud_subscribe("stll_3177567_d7000")


ds1= timer.start(5000,function()
sjs=math.random() / 10  --产生一个动态的随机数(变化)
stll =plc.df(7000)+0.95+sjs --0.95为闸门泄放的生态流量,以后闸修复后,重新计算一个值(闸门宽4m有2个闸门共8米)

plc.df(50,stll)
 print ("D50:",plc.df(50))
print ("D10:",plc.dd(10))		
end)
--发布数据,这里模拟定时发送数据到云服务器

把上面的地址、主题、引脚替换成你项目里的即可。

plc.cloud_compute ​

lua
plc.cloud_compute(json_string)

把一段 JSON 任务提交给云服务器执行,结果通过 plc.cloud_reg(plc.COMPUTE, ...) 的回调返回。

服务器按 JSON 中的 cmd 字段查找对应的处理函数,使用的命令表与云平台网页调用的是同一套。设备脚本因此可以直接调用服务器端功能,其中最常用的是发送邮件(cmd = "mail_send")。

参数

#参数类型必填默认值说明
1json_stringstring是—JSON 字符串,必须是对象且带 cmd 字段

通用字段:

字段必填说明
cmd是任务命令名,如 "mail_send"、"server_version"
id否任务标识。填写后服务器在回执中原样带回,用于区分对应的任务

返回值

无返回值(异步,结果走回调)。

示例

lua
plc.cloud_reg(plc.COMPUTE, function(jsonstring)
    local ok, resp = pcall(json.decode, jsonstring)
    if ok and resp.cmdreq == "ok" then
        print("任务完成", resp.id)
    else
        print("任务失败", jsonstring)
    end
end)

-- 查云服务版本
plc.cloud_compute(json.encode({ cmd = "server_version" }))

-- 发一封邮件
plc.cloud_compute(json.encode({
    id       = "alarm1",
    cmd      = "mail_send",
    to       = "you@example.com",
    subject  = "现场报警",
    body     = "1号泵房水位超限",
    username = "yourbox@163.com",   -- 发信邮箱
    password = "SMTP授权码",         -- 不是邮箱登录密码
}))

说明

  • 回执 JSON 中的 cmdreq 为 "ok" 表示成功,否则其内容即服务器返回的错误描述。
  • 设备必须已连接云服务。云连接断开时任务被丢弃,不排队补发,调用本身也不会返回失败。
  • 服务器不做去重和限频,判断和限频需在脚本中自行实现。
  • 完整的发邮件教程(含 SMTP 字段、限频写法、常见问题)见 快速入门 · 让设备自己发报警邮件。

例程 ​

每个例程都是可直接下载运行的完整脚本:注册完绑定/定时器后脚本就结束,固件自动进入消息泵。 云连接参数(服务器、设备密钥)由上位机写进 config.lua、固件启动时自动 cloud_bind,脚本里通常只处理业务数据。 统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。

例程 1:绑定寄存器自动上云,云端下发设定值写回 D ​

适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 / 上位机 | 依赖模块:plc(cloud_*)| 难度:★☆☆

场景:把现场温度(浮点 D100)、运行标志(M0)自动上报到云;云端页面改 setpoint 时,值要自动写回 D200 让梯形图当目标值用。绑定之后固件按 mode 自动同步,脚本不用再手动轮询上报。

完整代码(可直接下载运行):

lua
-- 上报方向:D100 浮点温度、M0 运行标志
plc.cloud_bind({
    { name = "temp",    reg = "D100", type = plc.FLOAT, mode = plc.CLOUD_UP   },
    { name = "running", reg = "M0",   type = plc.BITE,  mode = plc.CLOUD_UP   },
})

-- 下发方向:云端改 setpoint 会自动写进 D200
plc.cloud_bind({
    { name = "setpoint", reg = "D200", type = plc.S16, mode = plc.CLOUD_DOWN },
})
plc.cloud_subscribe("setpoint")

-- 此后梯形图直接读 D200 当目标值,Lua 不必再管

要点:

  • 绑定一次传完整列表比多次调用更高效(每处理完一条都会触发一次「完成绑定」)。
  • mode 决定同步方向:CLOUD_UP 只上报、CLOUD_DOWN 只接收、CLOUD_AUTO(省略时默认)双向。
  • 绑定 X/Y 时 reg 用八进制丝印编号:"X10" 是第 8 个输入点,和函数式 plc.x(10)(十进制第 10 号)语义不一样,这是最容易踩的坑。
  • 地址非法或类型不匹配的条目被静默跳过,不报错 —— 上线前在云平台页面核对数据点是否都出现。

验证方法:

  1. 上位机配好 config.lua 的云参数、下载本脚本,设备连上云。
  2. 云平台数据点列表出现 temp / running / setpoint 三项;本地改 D100 浮点,temp 随即更新;置 M0,running 翻 ON。
  3. 在云端把 setpoint 改成 350:设备侧 D200 变成 350,梯形图读到新目标值。

注意事项:

  • cloud_bind 里 X/Y 编号是八进制、函数式 plc.x/y 是十进制,混用会把值绑到错误的点。
  • BITE 只能绑 X/Y/M/S/T 触点/C 触点,给 D/R 写 BITE 会被跳过;想绑 D 用 S16/S32/FLOAT。
  • CLOUD_UP 是「变化时才上报」,别指望它按固定周期推送(需要定时快照看例程 2)。

例程 2:定时把计算结果快照上报(cloud_publish + 定时器) ​

适用:同上 | 依赖模块:plc timer json | 难度:★☆☆

场景:云平台要看「每 5 秒一条」的曲线,但 CLOUD_UP 是变化才上报、平时不动就不发。做法是定时器里用 cloud_publish 主动成对上报,连「不是直接来自寄存器」的派生值(如状态字符串)也能一并带上。

完整代码(可直接下载运行):

lua
-- 每 5 秒主动上报一次温度快照 + 状态串
timer.start(5000, function()
    local t = plc.df(100)
    plc.cloud_publish(
        "temperature", t,
        "status",     t > 80 and "alarm" or "ok"
    )
end)

要点:

  • cloud_publish 参数成对出现(名称, 值, 名称, 值…);个数为奇数时最后一个落单的被忽略。
  • 值为 any,内部统一转字符串报上去;所以这里能把 t > 80 and "alarm" or "ok" 这种字符串也一起发。
  • 它适合上报「计算结果」;纯寄存器镜像优先用 cloud_bind,别两个都绑同一项(重复上报)。
  • 周期由 timer 决定,固件不替您兜底节奏,别写 while true + sleep。

验证方法:

  1. 下载后云平台每 5 秒收到一条 temperature 快照;把 D100 浮点改成 81,同一条里 status 变 alarm。
  2. 故意写成 plc.cloud_publish("a", 1, "b") 奇数个参数:日志/云端只收到 a,b 被丢弃(验证成对规则)。

注意事项:

  • 想靠 CLOUD_UP 出定时曲线会失望:值不变就不发,曲线断断续续。
  • cloud_publish 没有返回值,上报是否成功只能靠 cloud_reg(plc.PUBLISH, …) 的回调感知。
  • 参数个数为奇数时最后一个被静默丢弃,不是报错,调试时容易漏数据。

例程 3:云端下发命令触发本地动作 + 报警时发邮件 ​

适用:同上 | 依赖模块:plc json timer | 难度:★★☆

场景:云端下发的 remote_cmd 为一台泵的启停指令,Lua 收到后写 Y0 并回 ACK;一旦本地温度超 80,除了云上报警还通过 cloud_compute 调云端发一封邮件。关键是:云连接参数不在脚本里,邮件的 SMTP 密码是授权码不是登录密码,且回执里 cmdreq == "ok" 才算成功。

完整代码(可直接下载运行):

lua
-- 订阅云端命令点
plc.cloud_subscribe("remote_cmd")

plc.cloud_reg(plc.SUBSCRIBE, function(name, value)
    if name == "remote_cmd" then
        plc.y(0, tonumber(value) or 0)      -- 下发值写 Y0(启停泵)
        print("远端命令执行: Y0 =", plc.y(0))
    end
end)

plc.cloud_reg(plc.PUBLISH, function(data) print("上报成功:", data) end)

-- 温度超阈值 → 上报 + 云端发邮件
timer.start(2000, function()
    if plc.df(100) > 80 then
        plc.cloud_publish("temp_alarm", plc.df(100))
        plc.cloud_compute(json.encode({
            id       = "alarm1",
            cmd      = "mail_send",
            to       = "you@example.com",
            subject  = "现场报警",
            body     = "1号泵房温度超限",
            username = "yourbox@163.com",     -- 发信邮箱
            password = "SMTP授权码",          -- 注意:是 SMTP 授权码,不是邮箱登录密码
        }))
    end
end)

-- 收云端计算回执
plc.cloud_reg(plc.COMPUTE, function(jsonstring)
    local ok, resp = pcall(json.decode, jsonstring)
    if ok and resp.cmdreq == "ok" then
        print("邮件已发出,任务 id:", resp.id)
    else
        print("邮件任务失败:", jsonstring)
    end
end)

要点:

  • cloud_subscribe 订阅后,值会写回绑定软元件,也能在 cloud_reg(plc.SUBSCRIBE, …) 回调里拿到(入参 name, value)。
  • cloud_compute 是异步的,结果走 cloud_reg(plc.COMPUTE, …) 回调;回执 JSON 里 cmdreq == "ok" 才成功,否则 cmdreq 是错误描述。
  • 邮件的 password 是邮箱的 SMTP 授权码,不是网页登录密码,填错会认证失败。
  • 云连接断开时 cloud_compute 的任务被丢弃且不排队补发,调用本身也不返回失败;限频、去重要在脚本里自己做。

验证方法:

  1. 云端把 remote_cmd 设为 1:设备 Y0 吸合,日志 远端命令执行: Y0 = 1。
  2. 把 D100 浮点改成 81:云平台出现 temp_alarm,同时 yourbox@163.com 收到报警邮件。
  3. 故意把 password 写成邮箱登录密码:回执 cmdreq 非 ok,日志打印失败信息(验证授权码要求)。
  4. 把 cmdreq == "ok" 判据删掉重跑:即使失败也会误判成功,凸显这个判断的必要性。

注意事项:

  • cloud_compute 回调里不判 cmdreq == "ok" 会「假成功」(失败也被当成完成)。
  • 邮件限频要自己写(脚本里加个最小间隔或计数),云端不做去重和限频。
  • cloud_reg 每种事件只保留最后一次注册的回调,重复注册会覆盖前面那个。

注意事项 ​

  • 绑定 X/Y 用八进制编号("X10" = 第 8 点),这一点和 plc.x(10) 的十进制语义不同,最容易出错。
  • 绑定条目地址或类型不合法时不会报错,只是那一条不生效。上线前用云平台页面核对数据点是否都出现了。
  • CLOUD_UP 是「变化时上报」,不要指望它按固定周期推送;需要定时快照请用 cloud_publish 配合 timer。
  • 云连接参数不在这里配置,由上位机写入 config.lua,固件启动时自动完成连接。

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研