## **Andon系统** #### **项目介绍** Andon(按灯)系统,项目主要解决生产现场出现问题时,通过安灯系统极快做出响应。 安灯内容包括: 1. 物料呼叫,拉动现场生产,点取对应物料及数量订单发送到现场看板大屏,类似购物车逻辑,仓库立即响应使用AGV无人车搬运物料。 2. 人员呼叫,生产出现问题,点取对应人员呼叫,以短信和车间广播通知对应人员。 3. 设备呼叫,设备出现问题,点击对应设备,以广播形式通知班组。 ![Alt text](image-5.png) 4. 工艺呼叫 5. 呼叫记录 事件升级:在ERP系统中的按灯模块维护基础数据,人员,设备,工艺,事件等,其中现场人员数据中会维护直接经理。当员工按灯后会系统开始计时,如果超过预设时间将会以短信形式发送通报至上级。 #### **工作内容** WMS基础数据增删改查开发,Andon广播呼叫程序开发,MES操作界面开发,电子看板开发。 #### **技术栈** WMS: ASP.NET SQLServer \ MES: VUE \ Andon广播呼叫程序: JavaFx Lame转码 JAVA Native Interface SAPI #### **广播呼叫程序介绍** 生产车间安装有ITC广播播放器,通过厂商提供的DLL文件对接广播使用。 逻辑:程序轮询数据库检测当前是否有未呼叫的安灯事件,如果有将生成的文本通过微软SAPI MTTS文字转语音技术将文字转换成WAV语音文件,并通过lame程序将音频转码为MP3格式发送至广播。 其他详情:https://cybersicko.net/article/24.html #### **预览** 广播呼叫程序 ![Alt text](image-6.png) 看板 ![Alt text](image-7.png) 操作界面 ![Alt text](image-8.png) WMS基础数据 ![Alt text](image-9.png) 代码预览 ```java package cn.ciemis.util; import cn.ciemis.base.CommandUtil; import cn.ciemis.entity.PlayModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.util.*; public class AudioUtil4 { public static String path = null; public static String lame = null; public static String tail = "F.mp3"; static MSTTSSpeech speech = new MSTTSSpeech(); static Logger LOG = LoggerFactory.getLogger(AudioUtil4.class); public static File mergeMp3(List playModels) throws IOException { Vector fileInputStreams = new Vector<>(); for (PlayModel playModel : playModels) { if (playModel.isMp3()) { playModel.setPath(path + "\\" + playModel.getContent()); } else { playModel.setPath(AudioUtil4.textToMp3(playModel.getContent())); } fileInputStreams.add(new FileInputStream(playModel.getPath())); LOG.info("合并文件:" + playModel.getPath()); } SequenceInputStream sequenceInputStream = new SequenceInputStream(fileInputStreams.elements()); String mergePath = path + "\\" + UUID.randomUUID() + tail; File afterMergeMp3 = new File(mergePath); boolean isSuccess = afterMergeMp3.createNewFile(); if (isSuccess) { FileOutputStream fileOutputStream = new FileOutputStream(afterMergeMp3);//destinationfile int temp; while ((temp = sequenceInputStream.read()) != -1) { // System.out.print( (char) temp ); // to print at DOS prompt fileOutputStream.write(temp); // to write to file } for (FileInputStream f : fileInputStreams) { f.close(); } fileOutputStream.close(); sequenceInputStream.close(); playModels.forEach(playModel -> { if (!playModel.isMp3()) { new File(playModel.getPath()).delete(); } }); } else { throw new IOException("mp3创建失败! " + mergePath); } return new File(mergePath); } public static List getPlayList(String message) { int i = 0; char[] messageArr = message.toCharArray(); List playModels = new ArrayList<>(); StringBuilder temp = new StringBuilder(); while (i < messageArr.length) { if (messageArr[i] == '[') { if (temp.length() > 0) { playModels.add(new PlayModel(false, temp.toString(), null)); temp = new StringBuilder(); } Map mp3 = getEndIndex(i, messageArr); i = (int) mp3.get("endIndex"); playModels.add(new PlayModel(true, mp3.get("mp3").toString(), null)); } else { temp.append(messageArr[i]); } i += 1; } if (temp.length() > 0) { playModels.add(new PlayModel(false, temp.toString(), null)); } return playModels; } public static Map getEndIndex(int index, char[] chars) { StringBuilder mp3 = new StringBuilder(); int mp3EndIndex = -1; int endIndex = -1; for (int i = index + 3; i < chars.length; i++) { if (chars[i] == ']') { endIndex = i; break; } else if (chars[i] == ';') { mp3EndIndex = i; } else { if (mp3EndIndex == -1) { mp3.append(chars[i]); } } } Map result = new HashMap<>(); result.put("endIndex", endIndex); result.put("mp3", mp3); return result; } public static String textToMp3(String text) throws FileNotFoundException { LOG.info("转语音:" + text); File wavFile = new File(textToWav(text)); if (!wavFile.exists()) { throw new FileNotFoundException("转语音失败!"); } else { //to mp3 use lame String wavPathStr = wavFile.getPath(); String mp3PathStr = wavFile.getPath(). replace(".wav", ".mp3"); String cmds1 = lame + String.format(" -b128 --resample 24 -m j %s %s", wavPathStr, mp3PathStr); // Arguments = string.Format("-b128 --resample 24 -m j \"{0}\" \"{1}\"", str3, str4) // String.format(" --silent -b 160 -m m -q 9-resample -tt %s %s", wavPathStr, mp3PathStr); String cmds2 = lame + String.format(" --scale 4 --mp3input %s %s", mp3PathStr, mp3PathStr.replace(".mp3", "L.mp3")); LOG.info("lame to mp3 : " + cmds1); LOG.info("large voice : " + cmds2); CommandUtil.exec(cmds1); CommandUtil.exec(cmds2); new File(wavPathStr).delete(); new File(mp3PathStr).delete(); return mp3PathStr.replace(".mp3", "L.mp3"); } } private static String textToWav(String text) { speech.setFormatType(16); File wavFile = new File(path); if (!wavFile.exists()) { wavFile.getParentFile().mkdirs(); } LOG.info(path); String filePath = path + "\\" + UUID.randomUUID() + ".wav"; LOG.info("wav文件保存到 : " + filePath); speech.saveToWav(text, filePath); return filePath; } } ```