--[[
|
编码: WMS-100-03
|
名称: PLC-PLCStateChange
|
作者:HAN
|
入口函数: PLCStateChange
|
|
|
功能说明:
|
新兴项目中的线体PLC状态发生变化后会通过这个可编程接口告诉WMS系统
|
|
发送过来的数据是一个Json包,格式如下:
|
{"device_code":"D001","comm_code":"1001_STUS","value":[1,1,0,1008,0,0,0,100],"time":"2023-09-05 16:16:00"}
|
分别表示下面这些状态
|
(1) 线体状态 0 空闲 1 运行 2 急停 state
|
(2) 光电信号 0 无框 1 有框 with_tray 有托盘
|
(3) 任务号 0~65535 task_no
|
(4) 目标地址 1008 线体编号 target_addr
|
(5) 线体信号 0 无动作 1=允许出框 2=允许进框 signal
|
(6) 任务状态反馈 0 无任务 1=出框完成 2=进框完成 task_state
|
(7) 外形检测 目前没有用
|
(8) 重量 目前没有用
|
|
变更记录:
|
|
--]]
|
wms_dev = require( "wms_devcomm" )
|
wms_eq = require( "wms_equipment" )
|
wms_cntr= require( "wms_container" )
|
wms_wh = require( "wms_wh" )
|
|
-- 创建入库作业
|
-- location 货位 cntr_code 容器编码
|
-- device_code 输送线线体设备编码
|
local function create_warehousing_operation( strLuaDEID, device_code, str_loc_code, cntr_code )
|
local location
|
local nRet
|
-- 判断一下是否已经存在托盘号 = cntr_code 的未完成作业,如果已经存在不需要继续创建作业
|
-- 因为 PLC 这边有 60s 强制通知策略,因此加一个防护
|
nRet, strRetInfo = wms_cntr.InOperation( strLuaDEID, cntr_code )
|
if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "WMS_Container_InOperation失败! " .. strRetInfo) end
|
if (strRetInfo == 'yes') then return end
|
|
-- 获取货位信息
|
nRet, location = wms_wh.Location_GetInfo( strLuaDEID, str_loc_code )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), 'wms_wh.Location_GetInfo 失败!'..location ) end
|
|
-- 创建作业
|
local operation = m3.AllocObject(strLuaDEID,"Operation")
|
operation.start_wh_code = location.wh_code
|
operation.start_area_code = location.area_code
|
operation.start_loc_code = location.code
|
operation.op_type = wms_base.Get_nConst(strLuaDEID, "作业类型-入库")
|
operation.op_def_name = "成品入库"
|
operation.cntr_code = cntr_code
|
operation.ext_data = device_code -- 注意:把线体的编码保存在扩展属性中,在生成任务的时候会用到
|
|
nRet, strRetInfo = m3.CreateDataObj( strLuaDEID, operation )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '创建【作业】失败!'..strRetInfo ) end
|
end
|
|
-- 创建设备动作队列
|
-- device_code -- 输送线设备号 task_code -- 任务号 action_code -- 动作码 action -- 动作 line_seg_code -- 线体段号
|
local function Create_MQAction( strLuaDEID, device_code, task_code, action_code, action, line_seg_code )
|
if ( device_code == nil or device_code == '' ) then lua.Error( strLuaDEID, debug.getinfo(1), '创建【设备动作队列】失败! 设备号必须有值' ) end
|
-- step2 获取车辆基本信息
|
local eq
|
nRet, eq = wms_eq.Equipment_GetInfo( strLuaDEID, device_code )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), eq ) end
|
-- 如果车辆没定义工厂标识返回错误
|
if ( eq.factory == '') then
|
strErr = "设备编号='"..strForkliftNo.."' 没定义工厂标识!"
|
lua.Error( strLuaDEID, debug.getinfo(1), strErr )
|
end
|
|
-- step3 判断当前车辆的动作码是否已经在队列中(MQ_EQAction)
|
local mq_eq_action = m3.AllocObject(strLuaDEID,"MQ_EQAction")
|
mq_eq_action.task_code = task_code
|
mq_eq_action.eq_code = device_code
|
mq_eq_action.action_code = action_code
|
mq_eq_action.action = action
|
mq_eq_action.data = line_seg_code
|
|
-- 线体这里已经存在设备动作记录就不需要继续进行处理
|
local strCondition = "N_ACTION_CODE = "..action_code.." AND S_EQ_CODE = '"..mq_eq_action.eq_code.."' AND ( N_B_STATE = 0 OR N_B_STATE = 1 ) "
|
strCondition = strCondition.." AND S_DATA = '"..line_seg_code.."'"
|
nRet, strRetInfo = mobox.existThisData( strLuaDEID, "MQ_EQAction", strCondition )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), strRetInfo ) end
|
-- 如果该车辆编码的动作已经在队列,返回,不做处理
|
if ( strRetInfo == "yes" ) then return end
|
|
-- step4 把车辆动作写入队列
|
mq_eq_action.factory = eq.factory
|
mq_eq_action.eq_type = eq.type
|
mq_eq_action.eq_type_name = eq.name
|
nRet, strRetInfo = m3.CreateDataObj( strLuaDEID, mq_eq_action )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), strRetInfo ) end
|
end
|
|
-- 主函数
|
-- PLC 状态变化后脚本处理程序
|
function PLCStateChange ( strLuaDEID )
|
local nRet, strRetInfo
|
local input_datajson = {}
|
|
-- step1 获取接口中的Data
|
nRet, input_datajson = m3.GetSysDataJson( strLuaDEID )
|
if ( nRet ~=0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "PLCStateChange 无法获取数据包!"..input_datajson ) end
|
local device_code = lua.Get_StrAttrValue( input_datajson.device_code )
|
local comm_code = lua.Get_StrAttrValue( input_datajson.comm_code )
|
local value = input_datajson.value
|
|
-- step2: 如果线体无框就返回
|
if ( value[wms_base.Get_nConst(strLuaDEID,"输送线-光电信号")] ~= 1 ) then return end
|
|
-- step3 检查从PLC传入的数据进行合法性判断
|
if ( device_code ~= "S7_Line_01") then
|
lua.Warning( strLuaDEID, debug.getinfo(1), "PLC传入的设备号 device_code 不正确,目前只是接收 S7_Line_01 设备的信号接入!" )
|
return
|
end
|
if ( comm_code == '' ) then
|
lua.Warning( strLuaDEID, debug.getinfo(1), "PLC传入的设备通讯项编码不能为空!" )
|
return
|
end
|
if ( value == nil ) then
|
lua.Warning( strLuaDEID, debug.getinfo(1), "PLC传入的设备状态值为 nil! " )
|
return
|
end
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "PLC", input_datajson )
|
|
-- 获取线体编码 line_seg_code
|
-- comm_code 的格式是 1001_XXXX 前面是线体编码
|
local seg = {}
|
local nCount
|
seg = lua.split( comm_code, '_' )
|
nCount = #seg
|
if ( nCount ~= 2 ) then
|
lua.Warning( strLuaDEID, debug.getinfo(1), "PLC传入的设备通讯项编码格式不正确! "..comm_code )
|
return
|
end
|
local line_seg_code = seg[1] -- 线体编码
|
|
-- step4: 通过OIDeviceCommS请求获取设备目前的托盘号 cntr_code
|
local cntr_code = wms_dev.ReadS7PLCCommsData( strLuaDEID, device_code, line_seg_code.."_CNTR" )
|
|
lua.Debug( strLuaDEID, debug.getinfo(1), "cntr_code", cntr_code )
|
|
if ( type(cntr_code) ~= "string" ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "调用OIDeviceCommS接口ReadData返回的容器编码格式不对,必须是字符串类型!" )
|
end
|
|
-- step5: 解析返回的容器号,并且进行容器号合格判断 (容器编码TP1/TP2 开头后面7位数字)
|
local strHeader -- 容器号的前3位字符串
|
nRet, strHeader = XX_CheckCNTRCode( cntr_code )
|
if ( nRet ~= 0 ) then
|
-- 输出 LED 错误信息 这块代码还需要完善
|
-- ???
|
lua.Error( strLuaDEID, debug.getinfo(1), strHeader )
|
end
|
|
-- step6: 判断容器是否存在? 不存在创建
|
if ( wms_cntr.Exist( strLuaDEID, cntr_code ) == false ) then
|
-- 【容器】不存在要先创建【容器】
|
local container = m3.AllocObject(strLuaDEID,"Container")
|
container.code = cntr_code
|
nRet, strRetInfo = m3.CreateDataObj(strLuaDEID, container)
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '创建【容器】对象失败!'..strRetInfo ) end
|
end
|
|
-- step7: 通过信号源所在的线体编号确定是 线体目前是做开始入库还是开始出库,或是开始入库到线体目标位置?
|
-- 根据 设备编号 + 通讯项目编码 获取货位号 及 货位的出入口属性
|
local dev_comms_ext
|
nRet, dev_comms_ext = wms_dev.GetDeviceCommSExtInfo ( device_code, comm_code )
|
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), dev_comms_ext ) end
|
local pos_type = lua.Get_StrAttrValue( dev_comms_ext.pos_type )
|
local str_loc_code = lua.Get_StrAttrValue( dev_comms_ext.loc_code )
|
if ( pos_type == nil or pos_type == '' ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "设备通讯项'"..comm_code.."'的设置不完整,需要设置该通讯项对应线体处所位置的出入口类型!")
|
end
|
if ( str_loc_code == nil or str_loc_code == '' ) then
|
lua.Error( strLuaDEID, debug.getinfo(1), "设备通讯项'"..comm_code.."'的设置不完整,需要设置该通讯项对应线体所处的货位编码!")
|
end
|
|
-- step8: 光电有框处理,根据线体所属的出入口类型确定作业类型(入库还是出库)
|
if ( pos_type == '入库线入口' ) then
|
-- 创建入库作业
|
create_warehousing_operation( strLuaDEID, device_code, str_loc_code, cntr_code )
|
elseif ( pos_type == '出库线入口' ) then
|
-- 创建出库作业(暂时不需要)
|
elseif ( pos_type == '出库线出口' ) then
|
-- 创建出库作业(暂时不需要)
|
-- 根据托盘号获取任务编号 (完整的任务号无法保存到设备里)
|
local task = XX_GetTaskByCNTR( strLuaDEID, device_code, cntr_code )
|
if ( task ~= nil ) then
|
-- 设置动作码和动作名称
|
local action_code = wms_base.Get_nConst(strLuaDEID , "输送线-出库口到货") -- 11
|
local action = "输送线-出库口到货"
|
-- 把线体编码 line_seg_code 作为data保存到 设备队列
|
Create_MQAction( strLuaDEID, device_code, task.code, action_code, action, line_seg_code )
|
else
|
lua.Error( strLuaDEID, debug.getinfo(1), "无法获取任务号! device_code = "..device_code.." cntr_code = "..cntr_code )
|
end
|
elseif ( pos_type == '入库线出口' ) then
|
-- 新增设备动作队列
|
-- 根据托盘号获取任务编号 (完整的任务号无法保存到设备里)
|
local task = XX_GetTaskByCNTR( strLuaDEID, device_code, cntr_code )
|
if ( task ~= nil ) then
|
-- 设置动作码和动作名称
|
local action_code = wms_base.Get_nConst(strLuaDEID , "输送线-入库口到货") -- 10
|
local action = "输送线-入库口到货"
|
-- 把线体编码 line_seg_code 作为data保存到 设备队列
|
Create_MQAction( strLuaDEID, device_code, task.code, action_code, action, line_seg_code )
|
else
|
lua.Error( strLuaDEID, debug.getinfo(1), "无法获取任务号! device_code = "..device_code.." cntr_code = "..cntr_code )
|
end
|
|
else
|
lua.Error( strLuaDEID, debug.getinfo(1), "设备通讯项'"..comm_code.."'的出入口类型设置不正确!")
|
end
|
|
end
|