浏览代码

further PIU development (#33)

* piufared which communicates over the serial line
clementinecomputing 4 年之前
父节点
当前提交
ef75deb74f

+ 10 - 6
busunit-PIU/html/css/piustyles.css

@@ -135,23 +135,27 @@ p:focus {
 .row5 { height: 15vh; }
 
 
-body { letter-spacing: 0.25em; }
+body {
+  letter-spacing: 0.25em;
+  background-color: #000;
+
+}
 
 .row { height: 160px; }
 .col { width: 160px; }
 
 .bdisp {
-  font-size: 12vh;
-  margin-top: 1vh;
-  margin-right: 1vw;
+  font-size: 11vh;
+  margin-top: 0.5vh;
+  /* margin-right: 1vw; */
 
   font-weight: bold;
-  color: #444444;
+  /* color: #444444; */
+  color: #aaa;
   margin-left: auto;
 
   background: none;
   border: none;
-
 }
 
 .bdispSmall {

+ 20 - 23
busunit-PIU/html/index.html

@@ -81,36 +81,33 @@
     <!-- <div id='ui_main' style='display:none;'> -->
     <div id='ui_main'>
 
-      <div class='pure-g'> <div class='pue-u'>
-
-      <div class='pure-g row'>
-        <div class='pure-u-1-12 col'>
-        </div>
-
-        <div class='pure-u-5-6 col'>
-          <div class='bdisp' style='color:#999a99;' id='ui_message_status' >SEE DRIVER...</div>
-        </div>
+      <div class='pure-g'>
+        <div class='pue-u'>
+
+          <div class='pure-g row'>
+            <div class='pure-u-1-12 col'> </div>
+            <div class='pure-u-5-6 col'>
+              <div class='bdisp' style='color:#999a99;' id='ui_message_status' >SEE DRIVER....</div>
+            </div>
+            <div class='pure-u-1-12 col'></div>
+          </div>
 
-        <div class='pure-u-1-12 col'></div>
-      </div>
+          <div class='pure-g row'>
+            <div class='pure-u-1-12 col'> </div>
+            <div class='pure-u-5-6 col'>
+              <div class='bdisp' id='ui_message_cardinfo'>--- ---- -- ----- </div>
+            </div>
 
-      <div class='pure-g row' style='height:55vh;'>
-        <img id='ui_main_vidfeed' style='height:50vh; margin-left: 16px;' src='' ></img>
-      </div>
+            <div class='pure-u-1-12 col'></div>
+          </div>
 
-      <div class='pure-g row'>
-        <div class='pure-u-1-12 col'>
-        </div>
+          <div class='pure-g row' style='height:55vh;'>
+            <img id='ui_main_vidfeed' style='height:50vh; margin-left: 16px;' src='' ></img>
+          </div>
 
-        <div class='pure-u-5-6 col'>
-          <div class='bdisp' id='ui_message_cardinfo'>...</div>
         </div>
-
-        <div class='pure-u-1-12 col'></div>
       </div>
 
-      </div></div>
-
       <div id="ui_message_datetime" class='datetimebar'>
         2020-04-11 09:50 AM
       </div>

+ 12 - 5
busunit-PIU/html/js/piu_ui.js

@@ -18,11 +18,15 @@
  *
  */
 
-//var _ADDRESS = "localhost";
-var _ADDRESS = "127.0.0.1";
+console.log("...");
+
+var _ADDRESS = "localhost";
+//var _ADDRESS = "127.0.0.1";
+//var _ADDRESS = "0.0.0.0";
 var _URL = "http://" + _ADDRESS;
-var _PORT = 60535;
+//var _PORT = 60535;
 var _WS_PORT = 8001;
+var _PORT = 8001;
 var _VID_FEED_PORT = 8080;
 
 var _fqADDRESS = _ADDRESS + ":" + _PORT;
@@ -35,7 +39,8 @@ var _fqADDRESS = _ADDRESS + ":" + _PORT;
 // Use 127.0.0.1 instead
 //
 //var _wsADDRESS = "localhost" + ":" + _WS_PORT;
-var _wsADDRESS = "127.0.0.1" + ":" + _WS_PORT + "/ws";
+//var _wsADDRESS = _ADDRESS +  ":" + _WS_PORT + "/ws";
+var _wsADDRESS = "192.168.0.26" +  ":" + _WS_PORT + "/ws";
 
 var BG_COLOR = "#f7f7f7";
 var TEXT_COLOR = "#444444";
@@ -353,6 +358,8 @@ function _ws_process(dat) {
 function _init_websocket() {
   var sock = new WebSocket("ws://" + _wsADDRESS);
 
+  console.log("??? _init_websockets:", sock, "ws://" + _wsADDRESS);
+
   g_sock = sock;
 
   sock.onopen = function(e) { console.log("open", e); }
@@ -364,7 +371,7 @@ function _init_websocket() {
   }
 
   sock.onerror = function(e) {
-    console.log("error", e);
+    console.log("error", e.message, e);
   }
 }
 

+ 211 - 0
busunit-PIU/piufared/piufared

@@ -0,0 +1,211 @@
+#!/usr/bin/python3
+#
+# Copyright (c) 2021 Clementine Computing LLC.
+#
+# This file is part of PopuFare.
+#
+# PopuFare is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# PopuFare is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with PopuFare.  If not, see <https://www.gnu.org/licenses/>.
+#
+
+
+import serial
+import re
+import math
+import time
+import sys
+import os
+
+from datetime import datetime
+
+PIU_FARED_VERSION = "0.1.0"
+
+cur_t = int(time.time())
+
+opt = {
+  "verbose" : 2,
+  "state_fn" : "/home/bus/config/piufared.state",
+  "sleepy" : 0.015625,
+
+  "ratelimit_mark" : 0.0,
+  "ratelimit_t" : 10.0,
+
+  "dev" : "/dev/ttyPIU",
+  "baud" : 115200,
+  "serial_timeout" : 0.05,
+  "MAX_BUF" : 1024,
+
+  "mag_fn" : "/home/bus/log/credential.mag",
+  "rfid_fn" : "/home/bus/log/credential.rfid",
+  "qr_fn" : "/home/bus/log/credential.barcode",
+
+  "mag_ts" : cur_t,
+  "rfid_ts" : cur_t,
+  "qr_ts" : cur_t
+}
+
+def _DT():
+  return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+def write_state(_opt):
+  with open(opt["state_fn"], "w") as ofp:
+    ofp.write("mag_ts " + str(_opt["mag_ts"]) + "\nrfid_ts " + str(_opt["rfid_ts"]) + "\nqr_ts " + str(_opt["qr_ts"]) + "\n")
+
+def read_state(_opt):
+  with open(_opt["state_fn"]) as fp:
+    lines = fp.read().split("\n")
+    for line in lines:
+      tok = line.split(" ")
+      if len(tok) < 2: continue
+      if tok[0] == "mag_ts":
+        _opt["mag_ts"] = int(tok[1])
+      elif tok[0] == "rfid_ts":
+        _opt["rfid_ts"] = int(tok[1])
+      elif tok[0] == "qr_ts":
+        _opt["qr_ts"] = int(tok[1])
+
+def send_data(_ser, _s):
+  #_s = dat + "\r\n"
+  _ser.write(_s.encode("utf-8"))
+
+# if we don't have a state file, create a new
+# one with the default (0) values
+#
+if not os.path.isfile(opt["state_fn"]):
+  write_state(opt)
+
+read_state(opt)
+
+piu_serial = serial.Serial(opt["dev"], baudrate=opt["baud"], timeout=opt["serial_timeout"])
+
+#_msg = '/M:;255100010014851?\r\n'
+#piu_serial.write(_msg.encode('utf-8'))
+
+sys.stdout.flush()
+
+buf = []
+
+while True:
+
+  eol = False
+  read_len = -1
+  have_data = False
+
+  while (len(buf) < opt["MAX_BUF"]) and (not eol) and (read_len != 0):
+    b = piu_serial.read()
+
+    read_len = len(b)
+    for _b in b:
+      if _b == ord('\r') or _b == ord('\n'):
+        eol = True
+        have_data = True
+        break
+      else:
+        buf.append(chr(_b))
+
+  if len(buf) >= opt["MAX_BUF"]:
+    have_data = True
+
+  if have_data:
+    s = "".join(buf)
+    buf = []
+
+    if len(s)==0:
+      if time.time() > opt["ratelimit_mark"]:
+
+        ## DEBUG
+        if opt["verbose"] > 0:
+          print(_DT(), "[piufared]", "sending init msg '/?: ?=rider_ui\\r\\n")
+          os.stdout.flush()
+
+        write_data(piu_serial, "/?: ?=rider_ui\r\n")
+        opt["ratelimit_mark"] = time.time() + opt["ratelimit_t"]
+      continue
+
+
+    if len(s) < 3: continue
+    if s[0] != '/': continue
+    if s[2] != ':': continue
+    msg = s[3:]
+
+    if s[1] == '0':
+      os.system("/home/bus/bin/piumsg 'relay passenger_message " + msg + "'")
+    elif s[1] == '1':
+      os.system("/home/bus/bin/piumsg 'relay passenger_notify " + msg + "'")
+
+  ###
+
+  state_change = False
+
+  with open(opt["mag_fn"]) as fp:
+    lines = fp.read().split("\n")
+    for idx in range(len(lines)-1):
+      line = lines[idx]
+      tok = line.split(" ")
+      if len(tok)!=2: continue
+      _ts = int(tok[0].split(":")[0])
+
+      if _ts <= opt["mag_ts"]: continue
+
+      if opt["verbose"] > 0:
+        print(_DT(), "[piufared]", "sending mag", " ".join(tok[1:]))
+
+      send_data(piu_serial, "/M:" + " ".join(tok[1:]) + "\r\n")
+      opt["mag_ts"] = _ts
+      state_change = True
+
+  with open(opt["rfid_fn"]) as fp:
+    lines = fp.read().split("\n")
+    for idx in range(len(lines)-1):
+      line = lines[idx]
+      tok = line.split(" ")
+      if len(tok)!=2: continue
+      _ts = int(tok[0].split(":")[0])
+
+      if _ts <= opt["rfid_ts"]: continue
+
+      if opt["verbose"] > 0:
+        print(_DT(), "[piufared]", "sending rfid", " ".join(tok[1:]))
+
+      send_data(piu_serial, "/R:" + " ".join(tok[1:]) + "\r\n")
+      opt["rfid_ts"] = _ts
+      state_change = True
+
+  with open(opt["qr_fn"]) as fp:
+    lines = fp.read().split("\n")
+    for idx in range(len(lines)-1):
+      line = lines[idx]
+      tok = line.split(" ")
+      if len(tok)!=2: continue
+      _ts = int(tok[0].split(":")[0])
+
+      if _ts <= opt["qr_ts"]: continue
+
+      if opt["verbose"] > 0:
+        print(_DT(), "[piufared]", "sending qr", " ".join(tok[1:]))
+
+      send_data(piu_serial, "/M:" + " ".join(tok[1:]) + "\r\n")
+      opt["qr_ts"] = _ts
+      state_change = True
+
+  if state_change:
+
+    if opt["verbose"] > 1:
+      print(_DT(), "[piufared]", "state change, writing")
+
+    write_state(opt)
+
+  time.sleep(opt["sleepy"])
+
+
+

+ 7 - 6
busunit-PIU/piumsgd/client/piumsg.c

@@ -82,9 +82,9 @@ static void _ws(struct mg_connection *c, int ev, void *ev_data, void *_data) {
     // When websocket handshake is successful, send message
     //
     n = strlen(g_msg);
-    printf("# sending: "); fflush(stdout);
-    write(1, g_msg, n);
-    printf("\n"); fflush(stdout);
+    //printf("# sending: "); fflush(stdout);
+    //write(1, g_msg, n);
+    //printf("\n"); fflush(stdout);
     mg_ws_send(c, g_msg, n, WEBSOCKET_OP_TEXT);
 
   } else if (ev == MG_EV_WS_MSG) {
@@ -92,7 +92,7 @@ static void _ws(struct mg_connection *c, int ev, void *ev_data, void *_data) {
     // When we get echo response, print it
     //
     struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
-    printf("# got: %.*s\n", (int) wm->data.len, wm->data.ptr);
+    //printf("# got: %.*s\n", (int) wm->data.len, wm->data.ptr);
 
   }
 
@@ -100,8 +100,9 @@ static void _ws(struct mg_connection *c, int ev, void *ev_data, void *_data) {
       (ev == MG_EV_CLOSE) ||
       (ev == MG_EV_WS_MSG)) {
 
-    printf("# ev %i (err%i, close%i, msg%i)\n",
-        ev, MG_EV_ERROR, MG_EV_CLOSE, MG_EV_WS_MSG);
+
+    //printf("# ev %i (err%i, close%i, msg%i)\n",
+    //    ev, MG_EV_ERROR, MG_EV_CLOSE, MG_EV_WS_MSG);
 
     // Signal that we're done
     //

+ 26 - 2
busunit-PIU/piumsgd/piumsgd.c

@@ -80,13 +80,32 @@ void _ws_send_str(struct mg_connection *mgc, char *msg) {
 
 
 static void _cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
+  int i;
   size_t n;
+  struct mg_http_message *hm = NULL;
 
   if (ev == MG_EV_HTTP_MSG) {
 
     printf("bang\n"); fflush(stdout);
 
-    struct mg_http_message *hm = (struct mg_http_message *) ev_data;
+    hm = (struct mg_http_message *) ev_data;
+
+    //DEBUG
+    //ptr len
+    /*
+    printf("body:\n");
+    for (i=0; i<hm->body.len; i++) {
+      printf("%i (%c)\n", hm->body.ptr[i], hm->body.ptr[i]);
+    }
+    printf("message:\n");
+    for (i=0; i<hm->message.len; i++) {
+      printf("%c", hm->message.ptr[i], hm->message.ptr[i]);
+    }
+    printf("\n\n");
+    */
+
+
+
     if (mg_http_match_uri(hm, "/ws")) {
 
       // Upgrade to websocket. From now on, a connection is a full-duplex
@@ -104,12 +123,16 @@ static void _cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
     }
     else if (mg_http_match_uri(hm, "/rest")) {
 
+      printf("other req?\n");
+
       // Serve REST response
       //
       mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
     }
     else {
 
+      printf("cp x\n");
+
       // Serve static files
       //
       struct mg_http_serve_opts opts = {.root_dir = s_web_directory};
@@ -164,7 +187,8 @@ int main(int argc, char **argv) {
   // setup mongoose web server
   //
   mg_mgr_init(&g_mgr);
-  mg_http_listen(&g_mgr, "http://127.0.0.1:8001", _cb, NULL);
+  //mg_http_listen(&g_mgr, "http://127.0.0.1:8001", _cb, NULL);
+  mg_http_listen(&g_mgr, "http://0.0.0.0:8001", _cb, NULL);
   for (;;) {
     mg_mgr_poll(&g_mgr, 200);
   }