串口外接设备支持--编程说明
本篇基础:BOS平台的二开编程(论坛),C#编程(ms),python语法,VistualStudio2012(up)工具(ms),串口基础知识
原帖位置 【http://club.kingdee.com/home.php ... 7&do=blog&id=118322】
【https://vip.kingdee.com/article/39852】
串口控件的应用场景是外接串口或USB模拟串口输入设备,比如IC卡输入,慢速按键读取设备等。
(下面是场景适用分析,提供参考)
串口控件是本地硬件的实时通讯端口,如果要用于远程直连的条件是该设备是慢速的或人工按钮触发方式,否则会堵塞服务的端口。
实时设备交互都是毫秒ms级别,而客户端服务器交互都是秒s级别,差距1000倍以上,因此不能用实时串口直连服务器,会堵塞服务器。尤其是多台实时设备同时直连,就更容易会导致服务的服务被堵塞。
使用方法:(特别注意的是,串口控件目前仅支持到GUI端,IE端暂不支持)
1、在BOSIDE中,新建动态表单。
在【通用控件】中找到【串口控件】,拖入表单即可。
2、设置串口控件基础属性。
端口名称PortName:默认COM2,依据实际设备的接入端口设置;
数据编码格式EncodingName :按实际设备说明输入,如果没有说明默认设置为ASCII码制;
速率Rate :默认9600bps;
奇偶校验Parity :None=0 不奇偶校验, Odd=1奇数,Event=2偶数, Mark=3预留校验位为1, Space=4预留校验位为0;
停止位StopBits :默认使用1个,不建议使用0个;
比特位Bits :默认为8,实际按设备说明输入;
超时时间Timeout :默认为-1,实际按设备说明输入;
接受数据结束符RecDataEndingChars :默认为空字符串,不启用。一次指令接受完成标记,设置了该属性并且是ASCII编码格式,客户端串口控件将多次接收串口的数据直到发现0D0A数据组合结尾的数据后再发送批量组合数据到服务端;(解决在WLAN环境中,由于网络延迟引起的服务端接收次序问题) ;
属性 | 名称 | 说明 |
PortName | 端口名称 | 默认COM2,依据实际设备的接入端口设置 |
EncodingName | 数据编码格式 | 按实际设备说明输入,如果没有说明默认设置为ASCII码制;值为ASCII |
Rate | 速率 | 默认9600bps; |
Parity | 奇偶校验 | None=0 不奇偶校验, Odd=1奇数,Event=2偶数, Mark=3预留校验位为1, Space=4预留校验位为0; |
StopBits | 停止位 | 默认使用1个,不建议使用0个; |
Bits | 比特位 | 默认为8,实际按设备说明输入; |
Timeout | 超时时间 | 默认为-1,实际按设备说明输入; |
RecDataEndingChars | 接受数据结束符 | 默认为空字符串,不启用。一次指令接受完成标记,设置了该属性并且是ASCII编码格式,客户端串口控件将多次接收串口的数据直到发现设备配置的结束符组合结尾的数据后再发送批量组合数据到服务端;(解决在WLAN环境中,由于网络延迟引起的服务端接收次序问题) ; 一般的,扫描设备的结束符为0D0A,比如一般的键盘接口型条码扫描枪。 |
3、编写业务插件。
实现对串口控件的控制逻辑。(所有下面python代码缩进为4个英文空格)
#如下代码,实现对端口的动态控制,切换,和关闭。
def ButtonClick(e):
if(e.Key=="FB2"):
# 下面参数一定要看设备说明书,并配置正确
cfg = KDSerialPortConfig()
cfg.PortName="COM2"
cfg.Rate = 9600
cfg.Parity = 0
cfg.Bits = 8
cfg.StopBits = 1
cfg.Timeout = -1
cfg.EncodingName = "ASCII"
this.View.GetControl("FSerialPortCtrl").Init(cfg) # 初始化并打开端口
if(e.Key=="FB4"):
cfg = KDSerialPortConfig()
cfg.PortName="COM4"
cfg.Rate = 9600
cfg.Parity = 0
cfg.Bits = 8
cfg.StopBits = 1
cfg.Timeout = -1
cfg.EncodingName = "ASCII"
#一次指令接受完成标记,设置了该属性并且是ASCII编码格式,客户端串口控件将多次接收串口的数据直到发现0D0A数据组合结尾的数据后再发送批量组合数据到服务端;(解决在WLAN环境中,由于网络延迟引起的服务端接收次序问题)
# 6.x 2018-04-26 已发布
# 7.x 2018-05-10 已发布
cfg.RecDataEndingChars = "0D0A"
# 特别注意,如果你的设备结束符号是xx,请用正确的结束符替代例子中的0D0A
this.View.GetControl("FSerialPortCtrl").Init(cfg)
# c sharp代码: this.View.GetControl<SerialPortControl>("FSerialPortCtrl").Init(cfg);
if(e.Key=="FCB"):
this.View.GetControl("FSerialPortCtrl").Close()
# c sharp代码: this.View.GetControl<SerialPortControl>("FSerialPortCtrl").Close();
4、编写业务插件,实现串口数据的接受存储。
覆写PortDataReceived(e): 接口,e对象传入结构包括Key,DataType,Value,ReceivedDataType四个重要属性;Key:当前控件键值;DataType:当前接受数据类型,目前全部为String;Value:实际接受的数据, 16进制编码Bytes数组字符串;ReceivedDataType:0正常数据,1:Eof的停止位。
def PortDataReceived(e):
this.Model.SetValue("FTEXT",e.Value)
this.View.UpdateView("FTEXT")
this.View.ShowMessage("数据到达",0)
5、错误诊断。
当端口不存在,打不开,或者其他什么错误的时候,串口控件位置上显示感叹号,并用Tooltip显示错误信息。
6、串口控件写入接口
三个写入接口,注意bytes写入类型必须转换为base64编码格式:
/// <summary>
/// 端口写入字符串
/// </summary>
/// <returns></returns>
public void WriteLine(string value)
/// <summary>
/// 端口写入Byte数组
/// </summary>
public void WriteBytes(string base64str, int offset, int count)
/// <summary>
/// 端口写入Char数组
/// </summary>
public void WriteChars(char[] value, int offset, int count)
这三个接口调用例子如下:
import clr
clr.AddReference('Kingdee.BOS')
from Kingdee.BOS.DataEntity import *
def ButtonClick(e):
if(e.Key=="FCB"):
this.View.GetControl("FSerialPortCtrl").Close()
if(e.Key=="FBSS"):
this.View.GetControl("FSerialPortCtrl").WriteLine("sendhello")
if(e.Key=="FBSB"):
value = "c2VuZGhlbGxv" #base64格式的“sendhello”, 可以使用 System.Convert.ToBase64String(byte[])接口
this.View.GetControl("FSerialPortCtrl").WriteBytes(value,0,9)
if(e.Key=="FBSC"):
this.View.GetControl("FSerialPortCtrl").WriteChars("sendhello".ToCharArray(),0,9)
# 上面代码在C#中要用 this.View.GetControl<SerialPortControl>("FSerialPortCtrl")获取控件模型
初始化串口插件示例:
import clr
clr.AddReference('Kingdee.BOS')
from Kingdee.BOS.DataEntity import *
def ButtonClick(e):
if(e.Key=="FB2"):
cfg = KDSerialPortConfig()
cfg.PortName="COM31"
cfg.Rate = 9600
cfg.Parity = 0
cfg.Bits = 8
cfg.StopBits = 1
cfg.Timeout = -1
cfg.EncodingName = "ASCII"
#一次指令接受完成标记,设置了该属性并且是ASCII编码格式,客户端串口控件将多次接收串口的数据直到发现0D0A数据组合结尾的数据后再发送批量组合数据到服务端;(解决在WLAN环境中,由于网络延迟引起的服务端接收次序问题)
# 6.x 2018-04-26 已发布
# 7.x 2018-05-10 已发布
cfg.RecDataEndingChars = "0D0A" #特别注意,如果你的设备结束符号是xx,请用正确的结束符替代例子中的0D0A
#this.View.GetControl("FSerialPortCtrl").Init(cfg)
this.View.GetControl("FSerialPortCtrl").InvokeControlMethod('Init',cfg)
this.View.GetControl("FSerialPortCtrl").Visible = True
7、串口控件可编程反馈事件配置(预计:2020-07-02)
7.1、利用构建插件激活串口控件反馈事件,如下代码。
def CreateControl(e): if(e.ControlAppearance.Key=="FSERIALPORTCTRL"): e.Control['allowFireEvtBack']=True
7.2、利用业务插件动态激活反馈参数。
this.View.GetControl("FSERIALPORTCTRL").SetAllowFireEvtBack(True)
7.3、设置参数后,二开业务插件override接口CustomEvents事件既可以接收到反馈事件,如下图。
附录:
python插件1:初始化串口控件,设置是否启用反馈事件
import clr clr.AddReference('Kingdee.BOS') from Kingdee.BOS.DataEntity import * def ButtonClick(e): comPort = this.Model.GetValue("FCOM") if(e.Key=='FFBT'): this.View.GetControl("FSERIALPORTCTRL").SetAllowFireEvtBack(True) if(e.Key=='FFBF'): this.View.GetControl("FSERIALPORTCTRL").SetAllowFireEvtBack(False) if(e.Key=="FB4"): cfg = KDSerialPortConfig() cfg.PortName=comPort cfg.Rate = 9600 cfg.Parity = 0 cfg.Bits = 8 cfg.StopBits = 1 cfg.Timeout = -1 cfg.EncodingName = "ASCII" cfg.RecDataEndingChars = "" this.View.GetControl("FSERIALPORTCTRL").InvokeControlMethod("Init", cfg)
python插件2:方法调用,写入串口控件数据
import clr clr.AddReference('Kingdee.BOS') from Kingdee.BOS.DataEntity import * from System import * from System.Text import * def ButtonClick(e): #界面放置一个文本框可录入ascii数据 msg = this.Model.GetValue("FTEXT") if(e.Key=="FCB"): this.View.GetControl("FSerialPortCtrl").Close() if(e.Key=="FBSS"): this.View.GetControl("FSerialPortCtrl").WriteLine(msg) if(e.Key=="FBSC"): chrs = msg.ToCharArray() this.View.GetControl("FSerialPortCtrl").WriteChars(chrs,0,chrs.Length) if(e.Key=="FBSB"): #ascii编码 bys = Encoding.ASCII.GetBytes(msg) value = Convert.ToBase64String(bys) # "c2VuZGhlbGxv" base64格式的“sendhello” this.View.GetControl("FSerialPortCtrl").WriteBytes(value,0,bys.Length)
python插件3:接收串口控件返回数据
def PortDataReceived(e): this.Model.SetValue("FTEXTREC",e.Value) this.View.UpdateView("FTEXTREC") this.View.ShowMessage("数据到达",0)
python插件4:服务端接收反馈接口演示
import clr clr.AddReference('Kingdee.BOS') from Kingdee.BOS.DataEntity import * from System import * from System.Text import * def CustomEvents(e): if (e.Key=='FSERIALPORTCTRL'): # FRMK 为一个多行文本框,用于demo服务端接收数据 custEvtData = String.Format('EventName: {0}\r\nEventArgs: \r\n{1}', e.EventName, e.EventArgs) this.Model.SetValue('FRMK', custEvtData) this.View.UpdateView('FRMK')
------------------------------------------------------------------------------------------------------------
参考资料: 串口控件读取数据不完整,一个完整的数据被分
https://vip.kingdee.com/article/18741
https://vip.kingdee.com/questions/52168
https://vip.kingdee.com/questions/52518
另外对于不是很了解串口的同学,可以参考下面操作步骤:
1、连接串口设备,记录串口号;
2、查看设备说明书,看看com口参数;
3、设备说明书配置好结束码;
4、表单增加按钮,按钮事件初始化对应串口号的参数,打开串口;
5、设备扫描数据,或地磅上进行称重;
6、串口控件获取到数据发送PortDataReceived(e)到服务端;
7、服务端插件获取PortDataReceived(e)的数据进行业务处理;
简单诊断如果串口没有获取的数据,说明:
1、串口接错了,串口号错误,参数错误;
2、串口被别的程序占用;
3、串口设备本身有问题或连接线有问题;
... ...
串口外接设备支持--编程说明
本文2024-09-23 03:47:19发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-161108.html