項目概述
項目背景:工廠表面處理產線項目
b司接了a司一條表面處理產線的項目,包含硬件及軟件,由于現在b司做的軟件難用且數據難以查找,a司不滿意驗收不通過,款項沒有結清。所有b司找到我們,希望我們能幫他搞定這個軟件系統。
公司關系:
- 互聯網軟件公司,A司(我在的公司)
- 工業服務集成商,B司(我們直接接觸的客戶)
- 工廠C司(制造業的工廠,B司的客戶)
人員關系:
- H工,A司的軟件開發人員(即在下)
- I工,A司的某部門leader(即在下領導)
- J工,B司該項目負責人
- K工,B司該項目的駐場協調人員(J工的手下)
- L工,外包人員,負責電路設計,plc開發,原有的軟件系統開發。
系統架構(舊):
- 軟件(給工人使用的人機交互程序,基于組態王軟件開發的工業軟件)
- plc,工業中普遍采用的可編程控制器,用來控制物理設備
- 物理設備,各種傳感器及物理設備。(如溫度傳感,水泵設備,超聲設備等)
控制流程, 軟件 < -----> PLC <--------->物理設備
階段一 (10月10)
需求
此時的需求是,需要有生產數據導出的Excel.
技術準備
通過看組態王的說明文件,了解到其有一個web,api接口可拿到所有字段的數據。
技術方案
于是此時考慮的技術方案,就是從組態王里面拿到數據進行格式化后輸出。
采用該技術方案的原因:
- 該方案可以滿足客戶需要數據的需求。
- 該方案開發周期短,不需要接管麻煩的硬件控制。
開發
我在開發電腦安裝了一個演示版組態王(演示版2小時會自動關閉),開發了一個腳本不斷請求組態王web接口的數據,然后格式化生成excel。
碰到的技術點:通過測試發現組態王程序不允許使用Connection: Keep-Alive,該選項會使組態王崩潰。
一兩天的時間開發完成,就等待安排時間去現場部署。(因為部署時會影響生產,只能等待安排時間)
部署
部署時發生的問題:
- 現場電腦使用win7系統,缺少一些重要組件導致python無法直接安裝。
- 現場的組態王程序沒有我在公司測試的api接口
此時與原先的軟件開發人員L工溝通這個問題,他解釋說現場使用的加密狗沒有開通這個功能,這個功能要單獨收費。
因為組態王使用的是加密狗授權。我在公司測試運行的演示版是全功能的。
結果
所以階段一的開發工作是無效的,主要問題是雙方缺少溝通,這個技術方案需要倆套系統的功能上的支持。我對工業軟件按模塊收費的模式不了解,我以為花錢了就是所有的功能都有的,和演示版一樣,只是不會自動關閉。
階段二 (準備期,10月10日至11月10日)
需求
每天一個生產數據報表excel文件。
準備
下一步方案考慮繞開組態王和plc通訊。讓plc開發給我一個tcp通訊口。
找了很多關于plc的資料學習,使用plc開發軟件進行聯系。使用仿真軟件模擬測試。
- plc程序開發軟件與plc設備具有很強的關聯性。不同設備要使用不同的軟件開發。
- 沒有官方的仿真軟件,且仿真軟件模擬不了網絡通訊。
后來強烈要求leader搞一個真實plc設備。
plc設備搞來后,花了兩周了解熟悉了plc程序開發,能寫一些簡單的邏輯程序輯器網絡通訊(socket)開發。
準備工作完成后開始正式開發,開了一個專門的工廠項目。原來只是一些單文件腳本,掛在其他項目里。
技術方案一
我在plc中的變量區定義一個地址塊,plc程序把我需要的數據傳到這個地址塊。我會高頻的讀取這個地址塊的數據,寫入到我定義的數據庫里面。然后按需求輸出一個客戶需要的excel文件。
開發一
進行demo開發,確認技術方案可以實現。
與L工同步這個技術方案,L工表示數據都有的組態王已經把數據存在數據庫了,不需要這么麻煩。
調整技術方案
技術方案二
調整技術方案, 直接從組態王的數據庫提取數據,不做plc通訊。
通過溝通發現L工并不懂數據庫,經過自己研究發現他所謂的數據庫是ms access。
不斷讀取ms access的數據來生成今日報表excel文件,每當有新的數據產生,今日報表文件就會刷新。
到了第二天,就會產生一個不斷更新的excel文件。(為什么不生成昨日的數據?忘了,且客戶需要當日數據)
開發二
通過觀察組態王的演示程序,其中演示功能有數據庫存儲即ms access的模塊。我可以直接基于這個演示模塊進行開發, 到現場只要替換掉字段名稱,即ms access 文件即可。
- 通過統計行數來判斷是否有的新的數據產生。 有新的數據則重新加載數據。
- 加載的數據放在內存,當重新加載時,把新的數據添加內存。
- 當有新數據重寫整個excel文件。由于數據時基于每天的,所以量不可能很大。
- 原來是生成2013的excel文件, 為了適應現場改成2007的excel文件。
- python程序打包Windows系統服務
部署
約時間到現場部署, 這次L工也在現場。L工見到我馬上拋出一個重要問題。
數據只有行車是自動模式才會存,手動模式不存數據。(此時心里mmp)
感覺又是浪費時間,因為這個線基本不用自動模式,win7系統組件裝上去,python環境安裝。部署服務。
看了一下歷史數據只有少數的幾次,估計還是測試的數據。所以這個功能雖然可行,但是源頭上就沒有數據。
結果
功能可行,部署也很順利。 但是源頭沒有數據,后來去看確實沒有數據。
階段三 (11月14日至12月22日)
需求
完成對產線的自動化生產的控制,在實現原來組態王實現的所有功能上增加數據保存
解除原來程序的一些操作限制方便工人使用。
準備
和leader即b司leader溝通, 直接把整個組態王干掉。我這個寫一個界面程序直接與plc通訊。
leader 出原型圖,我負責系統結構設計及開發,另外一個同事配合我與L工溝通一些問題。
技術方案
- 使用cs結構socket通訊,因為后面可能會有前端來配合我完成開發工作,也可能做成ipad應用。
- 目前前臺使用使用pyqt5 實現。
- 操作方式盡可能傾向與觸摸操作。
- 與plc的通訊使用S7協議
- 上位機與plc的協作方式。
在plc變量區中定義一個上位機只讀塊,和上位機只寫塊。通過這兩個塊的字段修改進行控制反饋。
開發
前臺開發:基于pyqt5進行開發,一邊開發一邊學。官網文檔主要是c++的,只能看個大概,多多谷歌。
有個pyqt5群,這幫人閑得很,可以解答各種問題。
- 數據模塊,利用import實現單例, 主要銜接了界面和通訊。對接口進行分發處理
- 網絡通訊模塊
- qt designer 生成的界面模型
- 界面程序,繼承界面模型,定義槽及事件關聯。
- tableview 模塊
- tablemodel模塊
- 對話框模塊
后臺開發:基于Python開發
- 數據模塊, 使用Init()實例引用傳遞的方式實現單例(缺點,pycharm不知道具體結構,無法自動提示)
- s7 協議模塊, 用于和西門子plc通信
- plc字段對象,協商的地址塊的每個此段抽象出來的對象
- socketserver, 與界面程序通信。
- 數據庫結構定義模塊。
- 數據庫操作模塊。
寫給plc使用的接口文檔。 即地址斷的定義說明
開發過程心得,
- 由于采用了這個分離結構,導致工作量翻倍。要時刻記得這是客戶端盡量不要有邏輯處理。
- 如果是一個人開發再也不要使用這種結構。
- 用了非常多的動態掛載,導致到了后面查找一個功能要用全局搜索。
- 數據滿天亂飛,自己看了都怕。
- 輕重緩急要分清楚,要為最核心的功能做最簡單的實現,再去優化。類似于TDD。
花了一些時間在無關緊要的細節上(細節最后還沒用上),最后只能把需求砍了。 - 日志模塊真的是挺難的。由于代碼復雜,出了問題也不好復現。一般都需要查日志解決。
一個好的日志應該能幫助快速且正確的定位問題。現在這個日志用得太爛了。
聯調
早上到了現場準備聯調, 結果工廠說線停錯了,等到下午才開始聯調。
因為我們這里開始聯調的話現場無法進行生產。
碰到了一個plc浮點數問題,一開始我讓另一個同事跟L工對好字段的數據類型,
這個工作沒做到位。因為我覺得出了問題我也還能hold住,也就沒管了。
花了一個多小時解決整個問題。
碰到了一個位的問題,我代碼里的bit位是按字節流順序的即高位到低位的順序,
而PLC代碼里的位是按低位到高位的順序排的。最后把所有位類型的數據改成字節類型。浪費了空間。
然后就是對天車的控制,整個中間出了很多問題。
基本就是我這邊出問題改半天,L工在邊上等著。L工那邊PLC出問題改半天,我在邊上等著。
就這樣搞了一個通宵,只對完了一些基本控制。只好約下次再去搞了。讓他們還是先用原來的系統。
結果
只完成了一部分的聯調,聯調必須在現場才能完成。
階段四 (12月30日至 1月2日)
聯調
元旦工廠放假三天,給了我們充足的聯調時間。
第一天 12月30日
動作聯調,改了很多邏輯。晚上11點就撤了,第二天早上繼續搞。
晚上在酒店看俄羅斯電影,《夜空飛燕》真的挺好看,俄羅斯妹子真漂亮
第二天 12月31日
聯調基本完成,優化了一下策略及界面,準備部署。內部聯合驗收時出了問題,
因為我的程序是沒有保存過程數據。每天開始要手動錄入數據昨天沒做完的數據,因為設備晚上會斷電。
為什么不保存過程數據?
- 因為在我的設計里活每天都要干完的。活不可能干到一半的。這錢算誰的。
- 保存數據需要進行數據庫操作,我的邏輯很多這樣實現起來很麻煩。
- 工人可以每天早上來的時候錄一下數據。
我們幾個重新溝通了一下,確定了這個功能必須實現。 然后我就回酒店加班改代碼。
那天是跨年夜,而我在酒店里加班改代碼。浙江衛視放著《追夢》的節目。我在想我是不是在
追夢。我想應該不是,那天我在群里和朋友說,這不是我心愛的代碼,這只是讓我我茍且的代碼。
我心愛的代碼平時不肯多花點時間去寫,現在卻在為這破玩意而竭盡全力。真是想打自己一頓。
這個其實不是一天時間內可以寫完的(以我目前的能力),但我挑戰一下這個極限編程,
我不想認輸,想把他做好。我在工作上總是有一種莫名的責任感,鞭策我吧,公瑾!
那天晚上本來想晚上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工打電話說了現場有了問題,我告訴他正確的操作流程。晚上遠程的修改了一下代碼,初始化時加載持久化數據的功能。減少問題發生的概率
結語
- 需求搞錯了
我是基于leader的ppt進行開發和構思的,leader和b司的leader也一起對過了ppt。
然而這倆人壓根不知道現場情況,導致我很多設計是錯誤的。 - 工業軟件一定到了解真實的使用場景。挖到客戶的真正需求。
- 代碼一到現場就大改了,所以一開始在公司寫的很多的代碼都是無效的。