TjPlcConfig.java 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package com.mes.plc;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.InputStream;
  8. import java.io.InputStreamReader;
  9. import java.io.OutputStreamWriter;
  10. import java.net.URL;
  11. import java.nio.charset.StandardCharsets;
  12. import java.util.Properties;
  13. /**
  14. * 涂胶 PLC 配置:一台 PLC,a1/b1 为两把胶枪地址。
  15. */
  16. public class TjPlcConfig {
  17. public final boolean enabled;
  18. public final String machine;
  19. public String host;
  20. public final int rack;
  21. public final int slot;
  22. public final int db;
  23. public final GunAddr a1;
  24. public final GunAddr b1;
  25. public static class GunAddr {
  26. public final String name;
  27. public final int frameCodeOffset;
  28. public final int frameCodeLen;
  29. public final int scanFeedbackByte;
  30. public final int scanFeedbackBit;
  31. public final int allowEntryByte;
  32. public final int allowEntryBit;
  33. public final int pathDoneByte;
  34. public final int pathDoneBit;
  35. public final int allDoneByte;
  36. public final int allDoneBit;
  37. public final int seqOffset;
  38. public final int glueSpeedOffset;
  39. public final int glueLengthOffset;
  40. public GunAddr(String name, Properties pro, String prefix) {
  41. boolean a1 = "a1".equals(name);
  42. this.name = name;
  43. this.frameCodeOffset = parseInt(pro.getProperty(prefix + "frameCodeOffset"), a1 ? 0 : 32);
  44. this.frameCodeLen = parseInt(pro.getProperty(prefix + "frameCodeLen"), 30);
  45. this.scanFeedbackByte = parseInt(pro.getProperty(prefix + "scanFeedbackByte"), 64);
  46. this.scanFeedbackBit = parseInt(pro.getProperty(prefix + "scanFeedbackBit"), a1 ? 0 : 1);
  47. this.allowEntryByte = parseInt(pro.getProperty(prefix + "allowEntryByte"), 64);
  48. this.allowEntryBit = parseInt(pro.getProperty(prefix + "allowEntryBit"), a1 ? 2 : 3);
  49. this.pathDoneByte = parseInt(pro.getProperty(prefix + "pathDoneByte"), a1 ? 64 : 74);
  50. this.pathDoneBit = parseInt(pro.getProperty(prefix + "pathDoneBit"), a1 ? 4 : 0);
  51. this.allDoneByte = parseInt(firstNonBlank(pro.getProperty(prefix + "allDoneByte"), pro.getProperty(prefix + "glueDoneByte")), a1 ? 64 : 74);
  52. this.allDoneBit = parseInt(firstNonBlank(pro.getProperty(prefix + "allDoneBit"), pro.getProperty(prefix + "glueDoneBit")), a1 ? 5 : 1);
  53. this.seqOffset = parseInt(pro.getProperty(prefix + "seqOffset"), a1 ? 66 : 76);
  54. this.glueSpeedOffset = parseInt(pro.getProperty(prefix + "glueSpeedOffset"), a1 ? 68 : 78);
  55. // 涂胶长度:博途为 Word(非 Real)
  56. this.glueLengthOffset = parseInt(pro.getProperty(prefix + "glueLengthOffset"), a1 ? 72 : 82);
  57. }
  58. public String frameCodeAddr(int db) {
  59. return String.format("DB%d.DBB%d String[%d]", db, frameCodeOffset, frameCodeLen);
  60. }
  61. public String scanFeedbackAddr(int db) {
  62. return String.format("DB%d.DBX%d.%d", db, scanFeedbackByte, scanFeedbackBit);
  63. }
  64. public String allowEntryAddr(int db) {
  65. return String.format("DB%d.DBX%d.%d", db, allowEntryByte, allowEntryBit);
  66. }
  67. public String pathDoneAddr(int db) {
  68. return String.format("DB%d.DBX%d.%d", db, pathDoneByte, pathDoneBit);
  69. }
  70. public String allDoneAddr(int db) {
  71. return String.format("DB%d.DBX%d.%d", db, allDoneByte, allDoneBit);
  72. }
  73. public String seqAddr(int db) {
  74. return String.format("DB%d.DBW%d", db, seqOffset);
  75. }
  76. public String glueSpeedAddr(int db) {
  77. return String.format("DB%d.DBD%d", db, glueSpeedOffset);
  78. }
  79. public String glueLengthAddr(int db) {
  80. return String.format("DB%d.DBW%d", db, glueLengthOffset);
  81. }
  82. }
  83. private TjPlcConfig(Properties pro) {
  84. this.enabled = "true".equalsIgnoreCase(trim(pro.getProperty("mes.tj.plc.enabled")));
  85. this.machine = trim(pro.getProperty("mes.machine", "a1"));
  86. this.host = trim(pro.getProperty("mes.tj.plc.host"));
  87. this.rack = parseInt(pro.getProperty("mes.tj.plc.rack"), 0);
  88. this.slot = parseInt(pro.getProperty("mes.tj.plc.slot"), 1);
  89. this.db = parseInt(pro.getProperty("mes.tj.plc.db"), 1300);
  90. this.a1 = new GunAddr("a1", pro, "mes.tj.a1.");
  91. this.b1 = new GunAddr("b1", pro, "mes.tj.b1.");
  92. }
  93. public GunAddr activeGun() {
  94. return "b1".equalsIgnoreCase(machine) ? b1 : a1;
  95. }
  96. public GunAddr gun(String name) {
  97. return "b1".equalsIgnoreCase(name) ? b1 : a1;
  98. }
  99. public static TjPlcConfig load() {
  100. try {
  101. Properties pro = loadProperties();
  102. return new TjPlcConfig(pro);
  103. } catch (Exception e) {
  104. e.printStackTrace();
  105. return new TjPlcConfig(new Properties());
  106. }
  107. }
  108. public static Properties loadProperties() throws Exception {
  109. Properties pro = new Properties();
  110. File file = resolveConfigFile();
  111. if (file != null && file.exists()) {
  112. try (InputStream is = new FileInputStream(file);
  113. BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
  114. pro.load(br);
  115. }
  116. return pro;
  117. }
  118. InputStream is = ClassLoader.getSystemResourceAsStream("config/config.properties");
  119. if (is != null) {
  120. try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
  121. pro.load(br);
  122. }
  123. }
  124. return pro;
  125. }
  126. /**
  127. * 保存 PLC IP,并尽量写回可写的 config.properties。
  128. */
  129. public static synchronized boolean saveHost(String newHost) {
  130. try {
  131. File file = resolveConfigFile();
  132. if (file == null) {
  133. return false;
  134. }
  135. if (!file.exists()) {
  136. File parent = file.getParentFile();
  137. if (parent != null && !parent.exists()) {
  138. parent.mkdirs();
  139. }
  140. }
  141. String content;
  142. if (file.exists()) {
  143. try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
  144. StringBuilder sb = new StringBuilder();
  145. String line;
  146. boolean replaced = false;
  147. while ((line = br.readLine()) != null) {
  148. if (line.startsWith("mes.tj.plc.host=")) {
  149. sb.append("mes.tj.plc.host=").append(newHost.trim()).append("\n");
  150. replaced = true;
  151. } else {
  152. sb.append(line).append("\n");
  153. }
  154. }
  155. if (!replaced) {
  156. sb.append("mes.tj.plc.host=").append(newHost.trim()).append("\n");
  157. }
  158. content = sb.toString();
  159. }
  160. } else {
  161. content = "mes.tj.plc.host=" + newHost.trim() + "\n";
  162. }
  163. try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
  164. bw.write(content);
  165. }
  166. return true;
  167. } catch (Exception e) {
  168. e.printStackTrace();
  169. return false;
  170. }
  171. }
  172. public static File resolveConfigFile() {
  173. try {
  174. URL url = ClassLoader.getSystemResource("config/config.properties");
  175. if (url != null && "file".equalsIgnoreCase(url.getProtocol())) {
  176. return new File(url.toURI());
  177. }
  178. } catch (Exception ignored) {
  179. }
  180. File[] candidates = new File[]{
  181. new File("src/resources/config/config.properties"),
  182. new File("config/config.properties"),
  183. new File("bin/config/config.properties")
  184. };
  185. for (File f : candidates) {
  186. if (f.exists()) {
  187. return f;
  188. }
  189. }
  190. // 开发目录默认写入
  191. File dev = new File("src/resources/config/config.properties");
  192. if (dev.getParentFile() != null && (dev.getParentFile().exists() || dev.getParentFile().mkdirs())) {
  193. return dev;
  194. }
  195. return new File("config/config.properties");
  196. }
  197. private static String firstNonBlank(String a, String b) {
  198. if (a != null && !a.trim().isEmpty()) {
  199. return a;
  200. }
  201. return b;
  202. }
  203. private static String trim(String v) {
  204. return v == null ? "" : v.trim();
  205. }
  206. private static int parseInt(String v, int def) {
  207. try {
  208. if (v == null || v.trim().isEmpty()) {
  209. return def;
  210. }
  211. return Integer.parseInt(v.trim());
  212. } catch (Exception e) {
  213. return def;
  214. }
  215. }
  216. }