仪器接口设计

不是所有设备都是TCP连接模式,有读文件的、读数据库的设备,为此还需要一个客户端仪器接口程序,面向接口编程是一个良好的思想,他使得调用者和接口实现者不用绑定太死,只要双方按约定实现即可。

仪器有读文件的、写文件的、读数据库的、写数据库的、定时取图的等,从PDF提取数据的、从Excel提取数据、读csv等。虽然很繁杂,但是对业务解析大家是固定的,都是要解析数据行,再把数据存入LIS。所以可以抽取接口,把繁杂的文件和数据库操作留给主程序,把业务解析操作留给接口实现类。

初步效果
在这里插入图片描述

配置对象,对接JSON的配置,通过配置控制主程序行为

package JRTMachineImpl.Base;

/**
 * 用来配置仪器接口的行为,去和配置串匹配,通过配置控制行为
 */
public class ConfDto {
    /**
     * 构造,避免为null
     */
    public ConfDto()
    {
        MachID="";
        Type="";
        Address="";
        UpTime=30000;
        DealProcess="";
        Para="";
        UpPara="";
        PreDealClass="";
        UPPreDealClass="";
        BakPath="";
        PathRegex="";
        ReadFileModel="";
        IsDBLooseKey="";
        ReadFileLeavelModel="";
        OtherPara="";
        CopyFile="";
        ExcelSheetIndex="";
        RowSplitChar="";
        WaringDealNum="";
        DBChangeUpLoadWaringNum="";
        NotSaveLog="";
        DemoImageClass="";
        StableTime="8000";
        SleepTime="2000";
        Encoding="";
        WriteEncoding="";
        ImgPixelFormat="";
        ImgZipWidthHeight="";
        ImgCutRate="";
        ImgAddSuffix="";
        ExcludeFile="";
        MachName="";
        AutoClipboardImg="";
        PDFImageModel="";
        PDFCutPageRectImage="";
    }

    /**
     * 仪器主键
     */
    public String MachID;

    /**
     * 监听类型
     */
    public String Type;

    /**
     * 监听地址
     */
    public String Address;

    /**
     * 上传定时间隔
     */
    public int UpTime;

    /**
     * 处理程序类
     */
    public String DealProcess;

    /**
     * 参数
     */
    public String Para;

    /**
     * 上传前处理参数
     */
    public String UpPara;

    /**
     * 前处理类:"类全名,动态库名"
     */
    public String PreDealClass;

    /**
     * 上传前处理类:"类全名,动态库名"
     */
    public String UPPreDealClass;

    /**
     * 备份路径
     */
    public String BakPath;

    /**
     * 读取文件一级目录正则表达式,没有读取全部文件夹,有内容按正则表达式读取符合的文件夹对日期表示的约定$y1 $y2 $y3 $y4表示年的1234位,$M1 $M2表示月的12位,$d1 $d2表示日的12位。例如:$y1$y2$y3$y4$M1$M2$d1$d2.*
     */
    public String PathRegex;

    /**
     * 读取文件模式0:读完删除,1:读取变化的,读完不删,2:监听到变化后不整个读取,从上次最后行读取,行数小于最后行从头读取
     */
    public String ReadFileModel;

    /**
     * 数据库监听比对模式是否是宽松型主键,1的话存一个主键多条记录日志,数据串和全部日志不同才上传检验,否则不上传
     */
    public String IsDBLooseKey;

    /**
     * 读取文件层级模式0:读取子级,1:仅读取一级目录
     */
    public String ReadFileLeavelModel;

    /**
     * 其他参数,供前处理使用
     */
    public String OtherPara;

    /**
     * 拷贝文件参数
     */
    public String CopyFile;

    /**
     * 读取Excel的页索引
     */
    public String ExcelSheetIndex;

    /**
     * 读数据库一行数据多列之间的分隔符,不配置为~
     */
    public String RowSplitChar;

    /**
     * 调用保存数据警告次数,一天内一次运行调用次数到达数量后将弹窗警告
     */
    public String WaringDealNum;

    /**
     * 数据库变化模式,数据变化触发警告的次数,防止主键不唯一重复传输
     */
    public String DBChangeUpLoadWaringNum;

    /**
     * 监听是否放弃保存数据文件日志1:是,否则默认保存到C盘10天,或者按配置的BakPath路径备份,完成新老并行。默认读取和上传日志在C:\LISMachineLogMian、上传日志在UP文件夹
     */
    public String NotSaveLog;

    /**
     * 默认选图和截图上传图片的类别
     */
    public String DemoImageClass;

    /**
     * 最后修改时间和当前时间的秒数,用来确定文件是否处于稳定状态,单位秒。为正数用当前电脑时间和文							件最后修改时间差比较。为负数的话第一次文件都不读,用两次文件的时间差比较
     */
    public String StableTime;

    /**
     * 每一轮循环后休眠的时间,单位毫秒
     */
    public String SleepTime;

    /**
     * 读取文本的编码格式:空默认系统编码,可为:ASCII、Default、Unicode、UTF32、UTF7、UTF8
     */
    public String Encoding;

    /**
     * 写文本的编码格式:空默认系统编码,可为:ASCII、Default、Unicode、UTF32、UTF7、UTF8
     */
    public String WriteEncoding;

    /**
     * 上传图片的图像深度,默认原图上传,自己画的为32深度。可以指定24就采用24深度在上传图片前转换
     */
    public String ImgPixelFormat;

    /**
     * 上传图片的图像要压缩的宽高,格式230*200
     */
    public String ImgZipWidthHeight;

    /**
     * 上传图片的图像要截取的宽高,格式1*0.7
     */
    public String ImgCutRate;

    /**
     * 上传图片添加的后缀带点
     */
    public String ImgAddSuffix;

    /**
     * 排除文件
     */
    public String ExcludeFile;

    /**
     * 仪器名字
     */
    public String MachName;

    /**
     * 自动监听粘贴板图片
     */
    public String AutoClipboardImg;

    /**
     * 空得到所有图。0:只取小图,1:只取大图
     */
    public String PDFImageModel;

    /**
     * PDF解析处理的一页图片是否切割矩形小图 1:切割,0:不切割
     */
    public String PDFCutPageRectImage;
}

前处理接口(重要)

package JRTMachineImpl.Base;

import JRTMachineImpl.Base.ConfDto;

import java.util.Map;

/**
 * 往检验上传数据之前调用的处理接口,任何要给LIS上传数据的处理类实现该接口,主程序会把数据一行行抛给接口方法处理,
 * 接口不需要关心主程序的实现,主程序不用关心具体的业务处理
 */
public interface IPreDeal {
    /**
     * 前处理
     *
     * @param conf     监听配置
     * @param result   结果串
     * @param index    当前文件的第几行
     * @param fileName 当前读取的文件全名
     * @return 是否继续后处理,true是,false否
     */
    boolean PreDeal(ConfDto conf, String result, int index, String fileName);

    /**
     * 数据库前处理
     *
     * @param conf  监听配置
     * @param row   结果Map
     * @param index 当前文件的第几行
     * @return 是否继续后处理,true是,false否
     */
    boolean PreDealDataBase(ConfDto conf, Map row, int index);
}

上传前处理接口(重要)

package JRTMachineImpl.Base;

import JRTMachineImpl.Base.ConfDto;
import JRTMachineImpl.Base.CmdDto;

import java.util.Map;

/**
 * 往检验上传数据之前调用的处理接口,根据虚拟M返回的命令执行。任何要给仪器上传的仪器接口实现该接口,主程序会按时间配置定时执行虚拟M查询数据逻辑后调用该接口。
 */
public interface IUpPreDeal {
    /**
     * 上传前处理
     *
     * @param conf 监听配置
     * @param key  操作键,不为空成功就调用处理类的SetFlag方法设置状态
     * @param cmd  要执行的命令
     * @return 是否继续后处理,true是,false否
     */
    boolean UPPreDeal(ConfDto conf, String key, CmdDto cmd);
}

定时执行接口

package JRTMachineImpl.Base;

import JRTMachineImpl.Base.ConfDto;

/**
 * 定时执行的接口,定时取图等实现。任何要实现定制执行逻辑的对象实现此接口,主程序会按配置时间定时调用该接口,来达到定时执行固定逻辑。
 */
public interface ITimer {
    /**
     * 执行任务
     * @param conf
     */
    void Action(ConfDto conf);
}

基础类

package JRTMachineImpl.Base;

import JRTMachineImpl.WebService.OutValue;
import JRTMachineImpl.Util.LogUtils;
import JRTMachineImpl.Base.CmdDto;

import java.util.List;

/**
 * 实现基础逻辑,保存数据,存图片路径,上传文件,执行命令等
 */
public class BaseDeal {
    /**
     * 保存数据
     *
     * @param conf      配置
     * @param data      数据
     * @param epis      流水
     * @param index     序号
     * @param fileName  文件全名
     * @param DBColName 数据库列名
     * @return
     * @throws Exception
     */
    public String SaveData(JRTMachineImpl.Base.ConfDto conf, String data, String epis, int index, String fileName, String DBColName) throws Exception {
        //得到配置的处理程序处理数据
        try {
            LogUtils.WriteSecurityLog("开始调用保存:" + conf.DealProcess + ".SaveData" + " 参数:P0:" + conf.MachID + " P1:" + data + " P2:");
            LogUtils.WriteDebugLog("开始调用:" + conf.DealProcess + ".SaveData" + " 参数:P0:" + conf.MachID + " P1:" + data + " P2:" + epis);
            //索引
            int rowCount;
            //类名
            String className = conf.DealProcess;
            //方法名
            String funcName = "SaveData";
            //创建参数对象
            JRTMachineImpl.WebService.Parameters param = new JRTMachineImpl.WebService.Parameters();
            //仪器主键
            param.P0 = conf.MachID;
            //结果
            param.P1 = data;
            //流水号
            param.P2 = epis;
            //文件名
            param.P3 = fileName;
            //文件名
            param.P4 = DBColName;
            //读文件序号
            param.P5 = String.valueOf(index);
            //写日志
            LogUtils.WriteDebugLog("保存:" + conf.MachID + ",数据:" + data + ",流水号:" + epis);
            OutValue session = new OutValue();
            OutValue out = new OutValue();
            //序列号保存配置数据
            String objStr = JRTMachineImpl.WebService.WebGetData.GetData("", className, funcName, param, session, out);
            LogUtils.WriteDebugLog("调用结束");
            LogUtils.WriteDebugLog("保存返回:" + objStr);
            LogUtils.WriteSecurityLog("保存返回:" + objStr);
            //返回就认为返回的命令列表
            if (objStr != "") {
                LogUtils.WriteDebugLog("处理返回消息");
                List<CmdDto> cmdList = JRTMachineImpl.Util.JsonDealUtil.Json2List(objStr, CmdDto.class);
                ExecCommand(cmdList, conf);
                LogUtils.WriteDebugLog("处理返回消息结束");
            }
            //设置调用次数
            //SetDealNum();
        } catch (Exception ex) {
            LogUtils.WriteExceptionLog("获得数据处理程序失败", ex);
            throw ex;
        }
        return "";
    }

    /**
     * 执行命令
     *
     * @param cmdList 要执行的命令列表
     * @param conf 配置
     */
    public void ExecCommand(List<CmdDto> cmdList, JRTMachineImpl.Base.ConfDto conf) {
        //把取图,写文件,执行SQL等约定成命令来简化程序逻辑
    }
}

主程序模型
在这里插入图片描述

这样监听的基础就打下了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/372686.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习Android的第四天

目录 Android FrameLayout ( 帧布局 ) FrameLayout size 大小 FrameLayout 属性 Android GridLayout ( 网格布局 ) GridLayout 属性 计算器布局 Android AbsoluteLayout 绝对布局 AbsoluteLayout 四大控制属性 Android FrameLayout ( 帧布局 ) FrameLayout 是 Android…

家政小程序系统开发:从构思到实现

随着科技的快速发展&#xff0c;移动互联网已经深入到我们生活的方方面面。特别是在家政服务领域&#xff0c;传统的服务方式已经不能满足现代人的需求。因此&#xff0c;开发一款家政小程序系统显得尤为重要。本文将介绍家政小程序系统的开发过程&#xff0c;包括需求分析、设…

SQLserver2008 r2 下载安装配置、使用、新建登录用户及通过Navicat远程连接

目录 一、下载 二、安装配置 1.安装 2.许可条款 3.安装程序支持文件 4.功能选择 5.实例配置 6.服务器配置 7.数据库引擎配置 8.Reporting Services 配置 9.安装进度 ​编辑 10.完成 三、使用 四、新建登录用户 1.新建登录名 2.常规 3.服务器角色 4. 用户映…

算法学习——LeetCode力扣链表篇1

算法学习——LeetCode力扣链表篇1 203. 移除链表元素 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 示例 …

thinkphp数据批量提交(群发消息)

<form id="edit-form" class="form-horizontal" role="form" data-toggle<

Verilog实现2进制码与BCD码的互相转换

1、什么是BCD码&#xff1f; BCD码是一种2进制的数字编码形式&#xff0c;用4位2进制数来表示1位10进制中的0~9这10个数。这种编码技术&#xff0c;最常用于会计系统的设计里&#xff0c;因为会计制度经常需要对很长的数字做准确的计算。相对于一般的浮点式记数法&#xff0c;…

Camera2+OpenGL ES+MediaCodec+AudioRecord实现录制音视频写入H264 SEI数据

记录一下学习过程&#xff0c;得到一个需求是基于Camera2OpenGL ESMediaCodecAudioRecord实现录制音视频。 需求&#xff1a; 在每一帧视频数据中&#xff0c;写入SEI额外数据&#xff0c;方便后期解码时获得每一帧中的自定义数据。点击录制功能后&#xff0c;录制的是前N秒至…

RCS系统之:显示AGV预测路线

在AGV做业务过程中&#xff0c;常会看到AGV一直停在哪里&#xff0c;没有任何动作。所以显示AGV马上要行进的路线非常有必要。 好处有&#xff1a; AGV是否有任务&#xff0c;AGV是否已经规划出路线&#xff1b;AGV马上要行进的路线 那具体要如何实现呢&#xff1f;有兴趣的可…

ONLYOFFICE:一站式办公,探索高效办公新境界

写在前面ONLYOFFICE 介绍ONLYOFFICE 有哪些优势ONLYOFFICE 文档 8.0 发布如何体验 ONLYOFFICEONLYOFFICE 文档部分页面截图 写在前面 在当今这样一个数字化时代&#xff0c;办公软件已经成为我们日常工作中不可或缺的一部分&#xff0c;熟练使用 Office、WPS、腾讯文档、金山文…

如何在Mac上允许主流浏览器使用弹出式窗口?这里有详细步骤

这篇文章教你如何关闭流行的Mac浏览器上的弹出窗口阻止程序,包括Safari、Chrome和Firefox。它还探讨了你可能希望这样做的原因及其影响。 如何在Mac上允许Safari使用弹出窗口 如果你经常在Mac上使用Safari,你会注意到默认情况下弹出窗口阻止程序是打开的。有时,这并不方便…

[office] 教你实现Excel中工作表重命名的诀窍 #知识分享#职场发展#其他

教你实现Excel中工作表重命名的诀窍 在Excel中要实现工作表的重命名其实不是难事&#xff0c;重在你要掌握技巧。一些初学者&#xff0c;可能还不是特别的懂。今天&#xff0c;小编就要一步步来教一下大家了。有两种方法&#xff0c;大家学好了。 方法一、打开excel表格&#x…

YOLOv8改进 | 检测头篇 | 重参数化检测头RepHead解决困难样本检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是RepHead,该检测头为我独家全网首发,该检测头由重参数化模块组成,加大对于特征学习的能力,却可以不增加GFLOPs(仅仅略微提升)从而不影响模型的推理速度和性能,保持较高的FPS能力,牺牲了少量GFLOPs的情况下确提高了模型的特征提…

进程和线程的区别详解

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 进程 进程在系统中是如何管理的 进一步认识PCB 线程 能否一直增加线程数目来提高效率 进程和线程…

极狐GitLab 与钉钉的集成实践

DingTalk OAuth 2.0 OmniAuth provider * 引入于 14.5 版本。 您可以使用您的钉钉账号登录极狐GitLab。 登录钉钉开放平台&#xff0c;创建应用。钉钉会生成一个客户端 ID 和密钥供您使用。 登录钉钉开放平台。 在顶部栏上&#xff0c;选择 应用程序开发 > 企业内部开发&am…

数据挖掘实战-基于决策树算法构建北京市空气质量预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

看论文利器:paperswithcode

paperswithcode&#xff0c;从名字就可以看出来&#xff0c;有源代码的paper。 写论文&#xff0c;很关键的就是能够复现论文内容。 这个网站提供了“论文代码”的参考文献。 以【图像加密】领域为例&#xff0c;搜索一下&#xff1a; 图像分割&#xff1a; 除了论文&#x…

2024.2.5日总结(小程序开发2)

小程序的宿主环境 宿主环境 宿主环境指的是程序运行所必须的依赖环境。 Android系统和iOS系统是两个不同的宿主环境。安卓版的微信App不能再iOS环境下运行。Android是安卓软件的宿主环境&#xff0c;脱离了宿主环境的软件是没有意义的。 小程序的宿主环境 手机微信是小程序…

Uibot (RPA设计软件)智能识别信息+微信群发助手(升级版)———课后练习1

微信群发助手机器人的小项目友友们可以参考小北的课前材料二博客~ (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; 紧接着小北的前两篇博客&#xff0c;友友们我们即将开展新课的学习~RPA 培训前期准备指南——安装Uibot(RPA设计软件&#x…

jmeter-问题一:关于线程组,线程数,用户数详解

文章目录 jmeter参数介绍1.线程数2.准备时长(Ramp-up)3.循环次数4.same user on each iteratio5.调度器 场景一&#xff1a;当你的线程组中线程数为1,循环为1场景二&#xff1a;当你的线程组中线程数为2&#xff0c;循环为1场景三&#xff1a;当你的线程组中线程数为1&#xff…

Javascript | 打印菱形

Javascript打印菱形&#xff0c;在校大学生可以拿来糊弄作业&#xff08;笑&#xff09; var str ; for (var i 1; i < 9; i) {if (i < 5) {for (var k1 1; k1 < 5 - i; k1) {str ;}} else {for (var k2 1; k2 < i - 5; k2) {str ;}}if (i < 5) {for (…