ferment_container_output.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>{{ title }}</title>
  6. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  7. <!-- <meta http-equiv="refresh" content="5" /> 每 content 秒網頁自動更新-->
  8. <!-- 新 Bootstrap4 核心 CSS 文件 -->
  9. <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
  10. <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
  11. <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  12. <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
  13. <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
  14. <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
  15. <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
  16. <!--可用來建立使用者小圖示-->
  17. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  18. <script language="JavaScript">
  19. // 指定 秒 刷新網頁一次
  20. var ftn = '{{tid}}';
  21. var status = '{{status}}';
  22. console.log('ftn:' + ftn)
  23. $(function(){
  24. $("#ferment_output_page").text('發酵貨櫃出料儲豆槽 FO' + ftn + ' 攝影機畫面 ')
  25. $('#ferment_output_page').attr("href", "/camera_FO" + ftn)
  26. $("#ferment_container_output_title").text('發酵貨櫃出料儲豆槽 FO' + ftn + ' 操作介面')
  27. $("#coffee_title").text('FO' + ftn + ' 發酵出料儲豆槽操作介面');
  28. if (status == 2) {
  29. $('input').prop('disabled', true);
  30. $('button').prop('disabled', true);
  31. } else if ( (status == 0) || (status == 1) ) {
  32. $('input').prop('disabled', false);
  33. $('button').prop('disabled', false);
  34. }
  35. });
  36. WebUpdate_set = setInterval(function(){WebUpdate(ftn)} , 10 * 1000)
  37. </script>
  38. <style>
  39. .footer{
  40. position: absolute;
  41. width: 100%;
  42. background-color: #eee;
  43. text-align: center;
  44. }
  45. body {
  46. margin: 0;
  47. }
  48. input[type="button"] {
  49. padding: 4px 15px;
  50. background: #f3f3f3;
  51. border: 0 none;
  52. cursor: pointer;
  53. -webkit-border-radius: 5px;
  54. border-radius: 5px;
  55. }
  56. .navbar-dark .navbar-nav .nav-link {
  57. color: white;
  58. cursor: pointer;
  59. text-decoration: none;
  60. width: 110px;
  61. height: 46px;
  62. }
  63. .nav-top {
  64. line-height: 40px;
  65. background-color: #C4C4C4;
  66. }
  67. .website_title {
  68. font-family: Roboto;
  69. font-style: normal;
  70. font-weight: normal;
  71. font-size: 30px;
  72. color: #000000;
  73. }
  74. .navbar-nav>li {
  75. float: none;
  76. display: inline-block;
  77. width: 100px;
  78. margin: 0 auto;
  79. text-align: center;
  80. }
  81. .navbar-nav>li a {
  82. font-size: 20px;
  83. }
  84. .main-page {
  85. margin-top: 200px;
  86. }
  87. .page-title {
  88. font-family: Roboto;
  89. font-style: normal;
  90. font-weight: bold;
  91. font-size: 36px;
  92. }
  93. .flex {
  94. display: flex;
  95. flex-direction: row;
  96. flex-wrap: wrap;
  97. justify-content: center;
  98. }
  99. .set-link {
  100. display: inline-block;
  101. width: 350px;
  102. height: 100px;
  103. line-height: 100px;
  104. background: #008CBA;
  105. border: 1px solid #CFCFCF;
  106. box-sizing: border-box;
  107. color: #FFFFFF;
  108. border-radius: 10px;
  109. font-size: 36px;
  110. }
  111. .cmn-toggle {
  112. position: absolute;
  113. margin-left: 0px;
  114. visibility: hidden;
  115. }
  116. .cmn-toggle+label {
  117. display: block;
  118. position: relative;
  119. cursor: pointer;
  120. outline: none;
  121. user-select: none;
  122. }
  123. input.cmn-toggle-round-flat+label {
  124. padding: 2px;
  125. width: 60px;
  126. height: 30px;
  127. background-color: #C0C0C0;
  128. border-radius: 60px;
  129. transition: background 0.4s;
  130. }
  131. input.cmn-toggle-round-flat+label:before,
  132. input.cmn-toggle-round-flat+label:after {
  133. display: block;
  134. position: absolute;
  135. content: "";
  136. }
  137. input.cmn-toggle-round-flat+label:before {
  138. top: 2px;
  139. left: 2px;
  140. bottom: 2px;
  141. right: 2px;
  142. background-color: #fff;
  143. border-radius: 60px;
  144. transition: background 0.4s;
  145. }
  146. input.cmn-toggle-round-flat+label:after {
  147. top: 4px;
  148. left: 4px;
  149. bottom: 4px;
  150. width: 24px;
  151. background-color: #dddddd;
  152. border-radius: 52px;
  153. transition: margin 0.4s, background 0.4s;
  154. }
  155. input.cmn-toggle-round-flat:checked+label {
  156. background-color: #C0C0C0;
  157. }
  158. input.cmn-toggle-round-flat:checked+label:after {
  159. margin-left: 27px;
  160. background-color: #008CBA;
  161. }
  162. @media(max-width:373px) {
  163. .card {
  164. margin-right: 0px;
  165. }
  166. .set-link {
  167. width: 250px;
  168. }
  169. }
  170. @media(max-width:577px) {}
  171. @media(min-width:576px) {}
  172. @media(min-width:768px) {
  173. .navbar-nav>li {
  174. margin-left: 0px;
  175. }
  176. .navbar-nav .li-block {
  177. display: none;
  178. }
  179. }
  180. @media(min-width:991px) {
  181. .navbar-nav>li {
  182. margin-left: 20px;
  183. }
  184. .navbar-nav .li-block {
  185. display: none;
  186. }
  187. }
  188. @media(min-width:1200px) {
  189. .navbar-nav>li {
  190. margin-left: 50px;
  191. }
  192. .navbar-nav .li-block {
  193. display: inline-block;
  194. width: 100px;
  195. }
  196. }
  197. @media(min-width:1400px) {
  198. .navbar-nav .li-block {
  199. display: inline-block;
  200. width: 200px;
  201. }
  202. }
  203. @media(min-width:1689px) {
  204. .navbar-nav>li {
  205. margin-left: 50px;
  206. }
  207. .navbar-nav .li-block {
  208. display: inline-block;
  209. width: 500px;
  210. }
  211. }
  212. </style>
  213. <script>
  214. // 發酵槽_制動器控制
  215. var tank_num = '{{tid}}';
  216. function outputVacuum() {
  217. var status = "off";
  218. var check = $("input[name=output_vacuum_status]:checked");
  219. //大於0代表有被選中
  220. if (check.length > 0) {
  221. status = "on";
  222. $("#cmn-toggle-32").prop('checked', false);
  223. if (!confirm("你確定要開啟出料儲豆槽真空吸料機嗎?")) {
  224. return false;
  225. };
  226. } else {
  227. $("#cmn-toggle-32").prop('checked', true);
  228. if (!confirm("你確定要關閉出料儲豆槽真空吸料機嗎?")) {
  229. return false;
  230. };
  231. };
  232. var data = { "tank_num": "FO" + tank_num, "command": "output_vacuum_status", "value": status };
  233. console.log('data:', data)
  234. $.post('/mqtt/{{tid}}', data, function (res) {
  235. if (res == 'on') {
  236. $("#cmn-toggle-32").prop('checked', true);
  237. setTimeout("alert('出料儲豆槽真空吸料機_開啟成功!')", 500);
  238. } else if (res == 'off') {
  239. $("#cmn-toggle-32").prop('checked', false);
  240. setTimeout("alert('出料儲豆槽真空吸料機_關閉成功!')", 500);
  241. } else {
  242. alert(res);
  243. };
  244. }, 'text')
  245. };
  246. function outputVacuum_ON() {
  247. var data = { "tank_num": "FO" + tank_num, "command": "output_vacuum_status", "value": "on" };
  248. console.log('data:', data)
  249. $.post('/mqtt/{{tid}}', data, function (res) {
  250. if (res == 'on') {
  251. $("#cmn-toggle-32").prop('checked', true);
  252. } else if (res == 'off') {
  253. $("#cmn-toggle-32").prop('checked', false);
  254. } else {
  255. console.log('res error')
  256. };
  257. }, 'text')
  258. }
  259. function outputVacuum_OFF() {
  260. var data = { "tank_num": "FO" + tank_num, "command": "output_vacuum_status", "value": "off" };
  261. console.log('data:', data)
  262. $.post('/mqtt/{{tid}}', data, function (res) {
  263. if (res == 'on') {
  264. $("#cmn-toggle-32").prop('checked', true);
  265. } else if (res == 'off') {
  266. $("#cmn-toggle-32").prop('checked', false);
  267. } else {
  268. console.log('res error')
  269. };
  270. }, 'text')
  271. }
  272. function tankDiskValve_ON() {
  273. var data = { "tank_num": "F" + tank_num, "command": "tank_diskvalve_status", "value": "on" };
  274. $.post('/mqtt/{{tid}}', data, function (res) {
  275. console.log('data:', data)
  276. if (res == 'on') {
  277. $("#cmn-toggle-11").prop('checked', true);
  278. } else if (res == 'off') {
  279. $("#cmn-toggle-11").prop('checked', false);
  280. } else {
  281. };
  282. }, 'text')
  283. }
  284. function tankDiskValve_OFF() {
  285. var data = { "tank_num": "F" + tank_num, "command": "tank_diskvalve_status", "value": "off" };
  286. $.post('/mqtt/{{tid}}', data, function (res) {
  287. console.log('data:', data)
  288. if (res == 'on') {
  289. $("#cmn-toggle-11").prop('checked', true);
  290. } else if (res == 'off') {
  291. $("#cmn-toggle-11").prop('checked', false);
  292. } else {
  293. };
  294. }, 'text')
  295. }
  296. </script>
  297. </head>
  298. <body>
  299. <div id="wrapper">
  300. <div id="coffee_header">
  301. <!-- 匯入共同使用的 header.html 內容 -->
  302. {% include 'header.html' %}
  303. </div>
  304. <!--
  305. <div style="text-align: left;">
  306. <a href="/ferment" style="float: left;">&nbsp;&nbsp;&nbsp;返回發酵貨櫃首頁</a>
  307. </div>
  308. <div style="text-align: right;">
  309. <a id="ferment_output_page" href="/index_new" style="float: right;">___________________</a>
  310. </div>
  311. <div id="ferment_container_output_title" style="text-align: center; margin-top: 30px; font-size: 24px; margin-bottom: 15px;">
  312. 發酵貨櫃出料儲豆槽 FO 操作介面
  313. </div>
  314. -->
  315. 狀態更新時間(秒):
  316. <input name="webupdate_time" type="text" value="5" style="width:40px;">
  317. <input type="button" value="設定更新時間" onclick="changeUpdate()">
  318. <script language="JavaScript">
  319. function changeUpdate() {
  320. clearInterval(WebUpdate_set);
  321. var webupdate_time = $("input[name=webupdate_time]").val()
  322. console.log('webupdate_time' + webupdate_time)
  323. WebUpdate_set = setInterval(function(){WebUpdate(ftn)} , webupdate_time * 1000);
  324. }
  325. // jQuery 更新感測器制動器狀態
  326. function WebUpdate(ftn) {
  327. $.get('/loading/FO' + ftn, '', function (res) {
  328. $("#LiDAR_t_status").text(res.LiDAR);
  329. }, 'json');
  330. }
  331. </script>
  332. <h4>制動器</h4>
  333. <table border="1px solid black" style="font-size:18px;" width=100%>
  334. <tr>
  335. <td style="color:red;">Valve</td>
  336. <td>真空吸料機</td>
  337. </tr>
  338. <tr>
  339. <td>
  340. <span style="color:#C0C0C0;">off</span>
  341. <span style="color:#008CBA;">on</span>
  342. </td>
  343. <td>
  344. <div class="switch_div">
  345. <div class="switch">
  346. <input id="cmn-toggle-31" class="cmn-toggle cmn-toggle-round" type="checkbox">
  347. <label for="cmn-toggle-31"></label>
  348. </div>
  349. <div class="switch text-center">
  350. {% if output_vacuum == 1 %}
  351. <input id="cmn-toggle-32" class="cmn-toggle cmn-toggle-round-flat" type="checkbox" checked
  352. name="output_vacuum_status" value="ON" onclick="outputVacuum()">
  353. {% else %}
  354. <input id="cmn-toggle-32" class="cmn-toggle cmn-toggle-round-flat" type="checkbox"
  355. name="output_vacuum_status" value="OFF" onclick="outputVacuum()">
  356. {% endif %}
  357. <label for="cmn-toggle-32"></label>
  358. </div>
  359. <div class="switch">
  360. <input id="cmn-toggle-33" class="cmn-toggle cmn-toggle-yes-no" type="checkbox">
  361. <label for="cmn-toggle-33" data-on="Yes" data-off="No"></label>
  362. </div>
  363. </div>
  364. </td>
  365. </tr>
  366. <tr>
  367. <td><span style="color:#008CBA;"><b>ON</b></span></td>
  368. <td><input type="button" value="ON" onclick="outputVacuum_ON()"></td>
  369. </tr>
  370. <tr>
  371. <td><span style="color:#C0C0C0;"><b>OFF</b></span></td>
  372. <td><input type="button" value="OFF" onclick="outputVacuum_OFF()"></td>
  373. </tr>
  374. </table>
  375. <br>
  376. <h4>感測器</h4>
  377. <table border="1" style="font-size:18px; border:2px #cccccc solid; margin-left: 2px; margin-right: 2px;" cellpadding="10" width=98%>
  378. <tr>
  379. <td>[出料儲豆槽] 生豆高度:<span id="UltraSonic_t_status">{{output_UltraSonic.UltraSonic}}</span> 公分</td>
  380. </tr>
  381. </table>
  382. <br>
  383. <h4>排程設計</h4>
  384. <table border="1" style="font-size:18px; border:2px #cccccc solid; margin-left: 2px; margin-right: 2px;" width=98%>
  385. <tr>
  386. <td>入料</td>
  387. <td>循環測試</td>
  388. </tr>
  389. <tr>
  390. <td>
  391. <!--
  392. [桶內 F1] 生豆高度:&nbsp;<span id="LiDAR_t_status">{{tank_LiDAR.LiDAR}}</span>&nbsp;公分<br>
  393. 指定空桶高度
  394. <input name="testing_tank_empty_height" id="testing_tank_empty_height" type="text" value="0" style="width: 40px;">公分<br>
  395. 蝴蝶閥 ON
  396. <br>
  397. -->
  398. 指定桶內生豆高度
  399. <input name="testing_BeanIn_Height" type="text" value="0" style="width: 40px;">公分<br>
  400. 出料吸料時間
  401. <input name="testing_out_vacuum_in" id="testing_out_vacuum_in" value="1" type="text" style="width: 40px;">秒<br>
  402. 出料放料時間(>10)
  403. <input name="testing_out_vacuum_out" id="testing_out_vacuum_out" value="10" type="text" style="width: 40px;">秒<br>
  404. 出料循環次數
  405. <input name="testing_out_vacuum_loop" id="testing_out_vacuum_loop" value="3" type="text" style="width: 40px;">次
  406. </td>
  407. <td>
  408. ON (開) &nbsp;
  409. <input name="Testing_starttime" value="3" type="text" style="width: 40px;">秒<br>
  410. OFF (關) &nbsp;
  411. <input name="Testing_endtime" value="5" type="text" style="width: 40px;">秒<br>
  412. 循環
  413. <input name="Testing_loop" value="3" type="text" style="width: 40px;">次
  414. </td>
  415. </tr>
  416. <tr>
  417. <td>
  418. <button type="submit" class="btn btn-primary" onclick="CoffeeOut_testing()">排水出豆</button>
  419. <script>
  420. var CoffeeOut_process = 0;
  421. function CoffeeOut_testing() {
  422. var testing_BeanIn_Height = $("input[name=testing_BeanIn_Height]").val();
  423. var testing_out_vacuum_in = $("input[name=testing_out_vacuum_in]").val();
  424. var testing_out_vacuum_out = $("input[name=testing_out_vacuum_out]").val();
  425. var testing_out_vacuum_loop = $("input[name=testing_out_vacuum_loop]").val();
  426. if (testing_BeanIn_Height != 0){
  427. console.log('指定高度 ' + testing_BeanIn_Height + ' 入豆')
  428. $.get('/ferment_LiDAR_' + tank_num, '', function (res) {
  429. if ( parseInt(res.LiDAR) > parseInt(testing_BeanIn_Height) ){
  430. tankDiskValve_ON()
  431. console.log('tankDiskValve_ON')
  432. };
  433. }, 'json');
  434. var CoffeeOut_interval = setInterval(tankEmptyHeight, 5000);
  435. function tankEmptyHeight(){
  436. if (CoffeeOut_process == 1) {
  437. return;
  438. }
  439. CoffeeOut_process = 1 ;
  440. $.ajax({
  441. type:"GET",
  442. url:"/ferment_LiDAR_" + tank_num,
  443. dataType:"json",
  444. success:function (response) {
  445. var present_Coffee_height = response.LiDAR
  446. console.log("目前桶內生豆高度: ", present_Coffee_height)
  447. console.log("指定空桶生豆高度: ", testing_BeanIn_Height)
  448. if( parseInt(present_Coffee_height) < parseInt(testing_BeanIn_Height)){
  449. clearInterval(CoffeeOut_interval);
  450. console.log("桶內已淨空!")
  451. CoffeeOut_process = 0;
  452. } else {
  453. outputVacuum_ON();
  454. console.log('outputVacuum_ON')
  455. var time = new Date();
  456. while ((new Date() - time) < testing_out_vacuum_in * 1000) { };
  457. outputVacuum_OFF()
  458. console.log('outputVacuum_OFF')
  459. var time = new Date();
  460. while ((new Date() - time) < testing_out_vacuum_out * 1000) { };
  461. CoffeeOut_process = 0;
  462. }
  463. },
  464. error:function(thrownError){
  465. console.log("Error: " + thrownError)
  466. CoffeeIn_Process = 0;
  467. }
  468. })
  469. }
  470. tankDiskValve_OFF()
  471. console.log('tankDiskValve_OFF')
  472. } else if ( testing_BeanIn_Height == 0){
  473. console.log('循環方式入豆')
  474. tankDiskValve_ON()
  475. console.log('tankDiskValve_ON')
  476. for (step = 1; step <= testing_out_vacuum_loop; step++) {
  477. console.log('-- 循環第 ' + step + ' 次 --')
  478. outputVacuum_ON();
  479. console.log('outputVacuum_ON')
  480. var time = new Date();
  481. while ((new Date() - time) < testing_out_vacuum_in * 1000) { };
  482. if (step == 1) {
  483. tankDiskValve_ON();
  484. console.log('tankDiskValve_ON')
  485. var time = new Date();
  486. while ((new Date() - time) < testing_out_vacuum_in * 1000) { };
  487. }
  488. outputVacuum_OFF();
  489. console.log('outputVacuum_OFF')
  490. var time = new Date();
  491. while ((new Date() - time) < testing_out_vacuum_out * 1000) { };
  492. }
  493. tankDiskValve_OFF();
  494. console.log('tankDiskValve_OFF')
  495. };
  496. };
  497. </script>
  498. </td>
  499. <td>
  500. <button type="submit" class="btn btn-primary" onclick="tankVacuumTest()">真空吸料機測試(秒)</button><br>
  501. <script>
  502. function tankVacuumTest() {
  503. clearInterval(WebUpdate_set);
  504. var Testing_starttime = $("input[name=Testing_starttime]").val();
  505. var Testing_endtime = $("input[name=Testing_endtime]").val();
  506. var Testing_loop = $("input[name=Testing_loop]").val();
  507. alert('測試間隔' + Testing_starttime + ':' + Testing_endtime + ' 次數' + Testing_loop)
  508. var step;
  509. for (step = 1; step <= Testing_loop; step++) {
  510. console.log('循環第 ' + step + ' 次');
  511. outputVacuum_ON()
  512. console.log('outputVacuum_ON')
  513. var time = new Date();
  514. while ((new Date() - time) < Testing_starttime * 1000) { }
  515. outputVacuum_OFF()
  516. console.log('outputVacuum_OFF')
  517. var time = new Date();
  518. while ((new Date() - time) < Testing_endtime * 1000) { }
  519. }
  520. WebUpdate_set = setInterval(function(){WebUpdate(ftn)} , 10 * 1000);
  521. }
  522. </script>
  523. </td>
  524. </tr>
  525. </table>
  526. <br>
  527. <h4>攝影機畫面</h4>
  528. <div class="container-fluid">
  529. <div class="row" style="margin-top:10px;">
  530. <div class="col flex">
  531. <div class="col-md-12 row flex" style="text-align:center;margin-top:5px;">
  532. <div class="col-md-12 row flex">
  533. <img src="" id="two" width="80%" height="80%">
  534. </div>
  535. </div>
  536. <script>
  537. // M5 攝影機
  538. //const img = document.querySelector('#one');
  539. const img1 = document.querySelector('#two');
  540. const WS_URL1 = 'ws:///60.250.156.230:8089';
  541. const ws1 = new WebSocket(WS_URL1);
  542. let urlObject1;
  543. ws1.onopen = () => console.log(`Connected to ${WS_URL1}`);
  544. ws1.onmessage = message1 => {
  545. const arrayBuffer1 = message1.data;
  546. if (urlObject1) {
  547. URL.revokeObjectURL(urlObject1);
  548. }
  549. urlObject1 = URL.createObjectURL(new Blob([arrayBuffer1]));
  550. img1.src = urlObject1;
  551. }
  552. </script>
  553. </div>
  554. </div>
  555. </div>
  556. <br>
  557. <br>
  558. <!--
  559. <footer class="footer">
  560. <div style="text-align: center; margin-top: 10px; font-size: 13px; margin-bottom: 10px;">
  561. Copyright © 2021 Gold-in Tech. All Rights Reserved. 金子進科技股份有限公司 版權所有
  562. <a href="mailto:service.gitc@gmail.com" target="_blank">service.gitc@gmail.com</a>
  563. </div>
  564. </footer>
  565. -->
  566. <div id="coffee_footer">
  567. <!-- 匯入共同使用的 footer.html 內容 -->
  568. {% include 'footer.html' %}
  569. </div>
  570. </div>
  571. </body>
  572. </html>