记一次工业软件开发经历

2020-01-06  本文已影响0人  eleksbai

项目概述

项目背景:工厂表面处理产线项目

b司接了a司一条表面处理产线的项目,包含硬件及软件,由于现在b司做的软件难用且数据难以查找,a司不满意验收不通过,款项没有结清。所有b司找到我们,希望我们能帮他搞定这个软件系统。

公司关系:

人员关系:

系统架构(旧):

控制流程, 软件 < -----> PLC <--------->物理设备

阶段一 (10月10)

需求

此时的需求是,需要有生产数据导出的Excel.

技术准备

通过看组态王的说明文件,了解到其有一个web,api接口可拿到所有字段的数据。

技术方案

于是此时考虑的技术方案,就是从组态王里面拿到数据进行格式化后输出。
采用该技术方案的原因:

开发

我在开发电脑安装了一个演示版组态王(演示版2小时会自动关闭),开发了一个脚本不断请求组态王web接口的数据,然后格式化生成excel。
碰到的技术点:通过测试发现组态王程序不允许使用Connection: Keep-Alive,该选项会使组态王崩溃。
一两天的时间开发完成,就等待安排时间去现场部署。(因为部署时会影响生产,只能等待安排时间)

部署

部署时发生的问题:

结果

所以阶段一的开发工作是无效的,主要问题是双方缺少沟通,这个技术方案需要俩套系统的功能上的支持。我对工业软件按模块收费的模式不了解,我以为花钱了就是所有的功能都有的,和演示版一样,只是不会自动关闭。

阶段二 (准备期,10月10日至11月10日)

需求

每天一个生产数据报表excel文件。

准备

下一步方案考虑绕开组态王和plc通讯。让plc开发给我一个tcp通讯口。
找了很多关于plc的资料学习,使用plc开发软件进行联系。使用仿真软件模拟测试。

准备工作完成后开始正式开发,开了一个专门的工厂项目。原来只是一些单文件脚本,挂在其他项目里。

技术方案一

我在plc中的变量区定义一个地址块,plc程序把我需要的数据传到这个地址块。我会高频的读取这个地址块的数据,写入到我定义的数据库里面。然后按需求输出一个客户需要的excel文件。

开发一

进行demo开发,确认技术方案可以实现。
与L工同步这个技术方案,L工表示数据都有的组态王已经把数据存在数据库了,不需要这么麻烦。
调整技术方案

技术方案二

调整技术方案, 直接从组态王的数据库提取数据,不做plc通讯。
通过沟通发现L工并不懂数据库,经过自己研究发现他所谓的数据库是ms access。
不断读取ms access的数据来生成今日报表excel文件,每当有新的数据产生,今日报表文件就会刷新。
到了第二天,就会产生一个不断更新的excel文件。(为什么不生成昨日的数据?忘了,且客户需要当日数据)

开发二

通过观察组态王的演示程序,其中演示功能有数据库存储即ms access的模块。我可以直接基于这个演示模块进行开发, 到现场只要替换掉字段名称,即ms access 文件即可。

  1. 通过统计行数来判断是否有的新的数据产生。 有新的数据则重新加载数据。
  2. 加载的数据放在内存,当重新加载时,把新的数据添加内存。
  3. 当有新数据重写整个excel文件。由于数据时基于每天的,所以量不可能很大。
  4. 原来是生成2013的excel文件, 为了适应现场改成2007的excel文件。
  5. python程序打包Windows系统服务

部署

约时间到现场部署, 这次L工也在现场。L工见到我马上抛出一个重要问题。
数据只有行车是自动模式才会存,手动模式不存数据。(此时心里mmp)
感觉又是浪费时间,因为这个线基本不用自动模式,win7系统组件装上去,python环境安装。部署服务。
看了一下历史数据只有少数的几次,估计还是测试的数据。所以这个功能虽然可行,但是源头上就没有数据。

结果

功能可行,部署也很顺利。 但是源头没有数据,后来去看确实没有数据。

阶段三 (11月14日至12月22日)

需求

完成对产线的自动化生产的控制,在实现原来组态王实现的所有功能上增加数据保存
解除原来程序的一些操作限制方便工人使用。

准备

和leader即b司leader沟通, 直接把整个组态王干掉。我这个写一个界面程序直接与plc通讯。
leader 出原型图,我负责系统结构设计及开发,另外一个同事配合我与L工沟通一些问题。

技术方案

  1. 使用cs结构socket通讯,因为后面可能会有前端来配合我完成开发工作,也可能做成ipad应用。
  2. 目前前台使用使用pyqt5 实现。
  3. 操作方式尽可能倾向与触摸操作。
  4. 与plc的通讯使用S7协议
  5. 上位机与plc的协作方式。
    在plc变量区中定义一个上位机只读块,和上位机只写块。通过这两个块的字段修改进行控制反馈。

开发

前台开发:基于pyqt5进行开发,一边开发一边学。官网文档主要是c++的,只能看个大概,多多谷歌。
有个pyqt5群,这帮人闲得很,可以解答各种问题。

  1. 数据模块,利用import实现单例, 主要衔接了界面和通讯。对接口进行分发处理
  2. 网络通讯模块
  3. qt designer 生成的界面模型
  4. 界面程序,继承界面模型,定义槽及事件关联。
  5. tableview 模块
  6. tablemodel模块
  7. 对话框模块

后台开发:基于Python开发

  1. 数据模块, 使用Init()实例引用传递的方式实现单例(缺点,pycharm不知道具体结构,无法自动提示)
  2. s7 协议模块, 用于和西门子plc通信
  3. plc字段对象,协商的地址块的每个此段抽象出来的对象
  4. socketserver, 与界面程序通信。
  5. 数据库结构定义模块。
  6. 数据库操作模块。

写给plc使用的接口文档。 即地址断的定义说明

开发过程心得,

  1. 由于采用了这个分离结构,导致工作量翻倍。要时刻记得这是客户端尽量不要有逻辑处理。
  2. 如果是一个人开发再也不要使用这种结构。
  3. 用了非常多的动态挂载,导致到了后面查找一个功能要用全局搜索。
  4. 数据满天乱飞,自己看了都怕。
  5. 轻重缓急要分清楚,要为最核心的功能做最简单的实现,再去优化。类似于TDD。
    花了一些时间在无关紧要的细节上(细节最后还没用上),最后只能把需求砍了。
  6. 日志模块真的是挺难的。由于代码复杂,出了问题也不好复现。一般都需要查日志解决。
    一个好的日志应该能帮助快速且正确的定位问题。现在这个日志用得太烂了。

联调

早上到了现场准备联调, 结果工厂说线停错了,等到下午才开始联调。
因为我们这里开始联调的话现场无法进行生产。
碰到了一个plc浮点数问题,一开始我让另一个同事跟L工对好字段的数据类型,
这个工作没做到位。因为我觉得出了问题我也还能hold住,也就没管了。
花了一个多小时解决整个问题。
碰到了一个位的问题,我代码里的bit位是按字节流顺序的即高位到低位的顺序,
而PLC代码里的位是按低位到高位的顺序排的。最后把所有位类型的数据改成字节类型。浪费了空间。
然后就是对天车的控制,整个中间出了很多问题。
基本就是我这边出问题改半天,L工在边上等着。L工那边PLC出问题改半天,我在边上等着。
就这样搞了一个通宵,只对完了一些基本控制。只好约下次再去搞了。让他们还是先用原来的系统。

结果

只完成了一部分的联调,联调必须在现场才能完成。

阶段四 (12月30日至 1月2日)

联调

元旦工厂放假三天,给了我们充足的联调时间。

第一天 12月30日

动作联调,改了很多逻辑。晚上11点就撤了,第二天早上继续搞。
晚上在酒店看俄罗斯电影,《夜空飞燕》真的挺好看,俄罗斯妹子真漂亮

第二天 12月31日

联调基本完成,优化了一下策略及界面,准备部署。内部联合验收时出了问题,
因为我的程序是没有保存过程数据。每天开始要手动录入数据昨天没做完的数据,因为设备晚上会断电。
为什么不保存过程数据?

  1. 因为在我的设计里活每天都要干完的。活不可能干到一半的。这钱算谁的。
  2. 保存数据需要进行数据库操作,我的逻辑很多这样实现起来很麻烦。
  3. 工人可以每天早上来的时候录一下数据。
    我们几个重新沟通了一下,确定了这个功能必须实现。 然后我就回酒店加班改代码。

那天是跨年夜,而我在酒店里加班改代码。浙江卫视放着《追梦》的节目。我在想我是不是在
追梦。我想应该不是,那天我在群里和朋友说,这不是我心爱的代码,这只是让我我苟且的代码。
我心爱的代码平时不肯多花点时间去写,现在却在为这破玩意而竭尽全力。真是想打自己一顿。
这个其实不是一天时间内可以写完的(以我目前的能力),但我挑战一下这个极限编程,
我不想认输,想把他做好。我在工作上总是有一种莫名的责任感,鞭策我吧,公瑾!
那天晚上本来想晚上12点睡的,但是压力太大实在睡不着。 在床上失眠了一个小时决定起来继续写代码。
在这个极限编程的时候发现了自己的一些问题,过度依赖ide的提示及自动补全。自己取得名字自己记不住,
英文太差了。(最近正好学词根词缀,感觉这个非常适合用来写代码)。对多线程的理解不到位,直到在真正调试的时候我才意识到这个问题,多线程必须结合类似于队列的东西使用。
我的多线打破了我分模块解耦的设计。由于这个多线程的错误使用导致代码高度耦合,
还好python内置全局锁,没有出现错误数据。代码正常运行。只是我也难以把握代码代码运行轨迹。
差不到写到了早上五点,终于有了困意就开始睡觉,定了个8点半的闹钟,

第三天 1月1日

8点半爬起来去酒店吃早餐,被告知没有早餐,只好拿出百度地图开始找吃的。找到了一家快餐店。吃了早饭就回去改代码,从早上9点改代码,中午1点的时候花了半个小时去吃饭, 就这样改到了下午3点半,然后我让K工和L工接我到现场调试。
调试过程依然不顺利,搞到了晚上22点才把联调完成,动作符合预期行为。开始准备进行部署。
由于我的分离结构,设备部署也很麻烦,服务端我部署在centos上,使用了多网卡,网络问题也搞了半天才接通。客户端部署发现了由于目标设备分辨率问题,导致整个页面显示效果很不理想。然后调整代码。还出了界面显示修改,一开始以为是硬件问题导致,到了后面才发现是代码里有个路径问题。这样差不多折腾到了早上6点,才把流程跑通。我教了一下K工如何使用我开发的这个软件,等工人上班由K工教工人如何使用。
K工把L工和我送回酒店休息,L工中午要赶火车就先和我回酒店休息。

第四天 1月2日

我睡到了9点多,有点不放心打车跑现场去看看,毕竟这个代码我自己都没测过。K工在现场教工人使用我开发的软件,使用过程中由于代码出了bug导致自动化跑不起来。在我配合实际生产使用的时候,发现我这个软件不能帮助工人提高生产效率,手自动模式衔接的不是很好。这整个交互可能需要重新进行设计。我在现场留下了我的电话,一再叮嘱工人出了问题打我电话, 因为这个未经过测试,我也不清楚会出现什么问题。我和K工一起去吃饭,K工送我回酒店,就回去睡觉了毕竟昨晚通宵一直没睡。然后我就回酒店把那个bug改掉,还有一个页面优化的问题。晚上7点的时候我打电话给K工让他接我去现场,
因为这个bug不是我预料的错误,必须在现场才能调试出来。到了现场,工人反馈说,
因为我软件崩溃一直打不开,泵关不掉,水溢出了。这个是由于前天晚上赶出来的代码,没有添加限制导致下标越位,工人在操作的不知道有这个要求。而且因为数据是持久化的,所有每次程序重启的使用的时候会
加载这个错误数据,然后程序报错退出。我首先简单修改了一下程序,能正常打开程序,先帮工人把泵关了。考虑了一下这其中的风险,我程序崩溃会导致现场无法进行生产,而且现在用我的程序并不能提高生产效率。我打电话给 leader说明一下现场情况及我的考虑。准备回滚为原来旧的系统。leader和B司的leader沟通后同意我的做法,于是我准备进行系统回滚。打电话给L工,让他把原来的PLC代码发给我,因为我部署的方式是直接换硬盘的所有他这个回滚倒是方便的。这个时候发现了一个问题,原来系统的加密狗不见了(应该是L工拿走了)L工说会寄一个新的加密狗过来。这样只有明天才能回滚了。我在代码把自动化相关的那块,具有复杂逻辑的东西给禁用了。减少出问题的概率。再三叮嘱工人出了问题一定要打电话给我。我开发的电脑先放在现场,等明天加密狗到了再去现场代码进行回滚。就这样我们折腾到了晚上11点才走。晚上终于可以好好睡觉了,电视放着百家讲坛。

阶段五 (1月3日至1月4日)

1月3日

这天睡到10天,我电话给L工追问加密狗的事,让他寄快递加急件,把快递单号发给我。我看快递单号是标快,打电话过去追问情况,他说寄不了加急,只有标快的。这样的今天就到不了。我打电话给leader说明情况,leader让我把操作步骤写下来,让K工找个现场的人明天配合我进行远程回滚。我把步骤写下给leader看,leader认为步骤过于复杂,工人搞不定的。说明天带我去现场回滚。中午时候K工来酒店接我。我告诉K工,人不用安排,明天我们会过来回滚的。让他和现场的人交代一下,出了问题一定要打电话给我。我们就一起回杭州了,我的东西先扔现场,反正明天就过来了。回来高速还堵车了。
下午我和leader碰了一下,沟通一下现状和后续计划。leader表示工人先这么用着,出了问题开车过去也就一个小时。明天和b司leader碰一下。
晚上我在家的时候用远程连了一下,看了下现场服务端代码的运行情况,正常使用,我把数据库同步脚本开起来。

1月4日

K工打电话说了现场有了问题,我告诉他正确的操作流程。晚上远程的修改了一下代码,初始化时加载持久化数据的功能。减少问题发生的概率

结语

上一篇 下一篇

猜你喜欢

热点阅读