Explorar o código

Merge branch 'master' of https://tree.clementinecomputing.com/clementinecomputing/popufare

clementinecomputing %!s(int64=6) %!d(string=hai) anos
pai
achega
f0afbc86ca

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 638 - 575
busunit/DIUv2/diu_main.c


+ 76 - 75
busunit/DIUv2/driver.c

@@ -20,8 +20,9 @@
 
 #include "driver.h"
 
-//This function searches the driver file and checks a driver, pin pair returning 0 on success
-//or -1 on failure.
+// This function searches the driver file and checks a driver, pin pair returning 0 on success
+// or -1 on failure.
+//
 int driver_login(int drivernum, char *pinnum)
 {
     FILE *f;
@@ -52,7 +53,7 @@ int driver_login(int drivernum, char *pinnum)
             break;
 
         line[sizeof(line)-1] = '\0';          //terminating each line safely
-    
+
         inc_line = line;
 
         while(1)        //and ignoring any leading whitespace
@@ -64,16 +65,16 @@ int driver_login(int drivernum, char *pinnum)
                 inc_line++;
                 continue;
             }
- 
+
             break;
         }
 
         if( (inc_line[0] == '#') || (inc_line[0] == '\0'))                      //and ignoring blank/comment lines
             continue;
-    
+
         name[0]='\0';
-        pin[0]='\0';        
- 
+        pin[0]='\0';
+
         retval=sscanf(inc_line,"%d %63[0123456789] %63[^\r\n]",&drv,pin,name);  //parse the line format (drivernum pin_num drivername)
 
         if(retval >= 2)           //if we get at least a driver number and pin number
@@ -87,13 +88,13 @@ int driver_login(int drivernum, char *pinnum)
                 strncpy(my_driver_status.driver_name, name, DRIVER_NAME_LEN);
                 my_driver_status.driver_name[DRIVER_NAME_LEN - 1] = '\0';
                 my_driver_status.equip_num = get_equip_num();
- 
+
                 format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Successful login for driver %d\n", drivernum);
                 send_message(hub_fd,&outgoing_msg);
 
                 update_driver_status |= 1;
                 fclose(f);
-                return 0; 
+                return 0;
             }
             else
             {
@@ -101,91 +102,91 @@ int driver_login(int drivernum, char *pinnum)
                 send_message(hub_fd,&outgoing_msg);
                 fclose(f);
                 return -1;
-            }      
+            }
         }
     }
-    
+
     format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Failed login for unknown driver %d\n", drivernum);
     send_message(hub_fd,&outgoing_msg);
-    fclose(f); 
+    fclose(f);
     return -1;
 }
 
-//Log a driver out and cancel any pending set paddle request
-int driver_logout()
-{    
-    struct message_record outgoing_msg;
-        
-    if(my_driver_status.logged_in_driver)
-    {
-        format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Driver logout for driver %d\n", my_driver_status.logged_in_driver);
-        send_message(hub_fd,&outgoing_msg);
-    }
-     
-    my_driver_status.logged_in_driver = 0;
-    my_driver_status.driver_name[0] = '\0';
-    paddle_req_timeout = 0;
-    update_driver_status |= 1;
-    return 0;   
-}           
- 
-int make_paddle_request(int paddle, char *okmenu, char *failmenu)
-{
-    struct message_record outgoing_msg;
+// Log a driver out and cancel any pending set paddle request
+//
+int driver_logout() {
+  struct message_record outgoing_msg;
+
+  if(my_driver_status.logged_in_driver) {
+    format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Driver logout for driver %d\n", my_driver_status.logged_in_driver);
+    send_message(hub_fd,&outgoing_msg);
+  }
+
+  my_driver_status.logged_in_driver = 0;
+  my_driver_status.driver_name[0] = '\0';
+  paddle_req_timeout = 0;
+  update_driver_status |= 1;
+  return 0;
+}
+
+//--------------
 
-    paddle_req.result = 0;
-    paddle_req.request = paddle;
-    paddle_req_timeout = time(NULL) + PADDLE_REQ_TIMEOUT;
+int make_paddle_request(int paddle) {
+  struct message_record outgoing_msg;
 
-    //paddle_ok_menu = okmenu;
-    //paddle_fail_menu = failmenu;
+  paddle_req.result = 0;
+  paddle_req.request = paddle;
+  paddle_req_timeout = time(NULL) + PADDLE_REQ_TIMEOUT;
 
-    prepare_message(&outgoing_msg, MAILBOX_SET_PADDLE, &paddle_req, sizeof(paddle_req));
-    return send_message(hub_fd, &outgoing_msg);
+  prepare_message(&outgoing_msg, MAILBOX_SET_PADDLE, &paddle_req, sizeof(paddle_req));
+  return send_message(hub_fd, &outgoing_msg);
 }
 
-//int check_paddle_request(menutree *mt)
-int check_paddle_request()
-{
-    struct message_record outgoing_msg;
+int check_paddle_request() {
+  char buf[LINE_BUFFER_SIZE];
+  struct message_record outgoing_msg;
 
-    if(paddle_req_timeout != 0)
-    {
+  if(paddle_req_timeout != 0) {
 
-        if(paddle_req.request == paddle_req.result)
-        {
-            format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Set Paddle %d\n", paddle_req.request);
-            send_message(hub_fd, &outgoing_msg);
-            paddle_req_timeout = 0;
-            //setmenu(mt, paddle_ok_menu);
-            return 1;
-        }
-        else if( (paddle_req.result < 0) || (paddle_req_timeout < time(NULL)) )
-        {
-            format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Failed to set Paddle %d\n", paddle_req.request);
-            send_message(hub_fd, &outgoing_msg);
-            paddle_req.result = 0;
-            paddle_req.request = 0;
-            paddle_req_timeout = 0;
-            //setmenu(mt, paddle_fail_menu);
-            return 1;
-        }
+    if(paddle_req.request == paddle_req.result) {
+      format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Set Paddle %d\n", paddle_req.request);
+      send_message(hub_fd, &outgoing_msg);
+      paddle_req_timeout = 0;
+
+      //setmenu(mt, paddle_ok_menu);
+      snprintf(buf, LINE_BUFFER_SIZE, "paddle ok %i", paddle_req.result);
+      ws_send(&g_mgr, buf);
+
+      return 1;
     }
+    else if( (paddle_req.result < 0) || (paddle_req_timeout < time(NULL)) ) {
+      format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "Failed to set Paddle %d\n", paddle_req.request);
+      send_message(hub_fd, &outgoing_msg);
+      paddle_req.result = 0;
+      paddle_req.request = 0;
+      paddle_req_timeout = 0;
 
-    return 0;
+      //setmenu(mt, paddle_fail_menu);
+      ws_send(&g_mgr, "paddle fail");
+
+      return 1;
+    }
+  }
+
+  return 0;
 }
 
-void action_nextstop()
-{
-    struct message_record outgoing_msg;
-    prepare_message(&outgoing_msg, MAILBOX_NEXT_STOP, "", 0);
-    send_message(hub_fd, &outgoing_msg);
+//--------------
+
+void action_nextstop() {
+  struct message_record outgoing_msg;
+  prepare_message(&outgoing_msg, MAILBOX_NEXT_STOP, "", 0);
+  send_message(hub_fd, &outgoing_msg);
 }
 
-void action_prevstop()
-{
-    struct message_record outgoing_msg;
-    prepare_message(&outgoing_msg, MAILBOX_PREV_STOP, "", 0);
-    send_message(hub_fd, &outgoing_msg);
+void action_prevstop() {
+  struct message_record outgoing_msg;
+  prepare_message(&outgoing_msg, MAILBOX_PREV_STOP, "", 0);
+  send_message(hub_fd, &outgoing_msg);
 }
 

+ 10 - 0
busunit/DIUv2/driver.h

@@ -34,6 +34,8 @@
 #include "../commhub/client_utils.h"
 #include "../common/common_defs.h"
 
+#include "mongoose.h"
+
 extern driver_status my_driver_status;
 extern int update_driver_status;
 
@@ -47,6 +49,14 @@ extern int hub_fd;
 void clear_diu_messages();
 int check_paddle_request();
 
+int make_paddle_request(int);
+
 int driver_login(int, char*);
 
+void action_nextstop(void);
+void action_prevstop(void);
+
+void ws_send(struct mg_mgr *mgr, char *msg);
+extern struct mg_mgr g_mgr;
+
 #endif

+ 5 - 0
busunit/DIUv2/html/css/diustyles.css

@@ -213,9 +213,14 @@ p:focus {
   margin-left:9px;
   background: #aaaaaa;
 
+  /*
   -webkit-transition: margin-left 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
   -moz-transition: margin-left 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
   transition: margin-left 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
+  */
+  -webkit-transition: margin-left 0.05s ease, box-shadow 0.05s ease, background 0.05s ease;
+  -moz-transition: margin-left 0.05s ease, box-shadow 0.05s ease, background 0.05s ease;
+  transition: margin-left 0.05s ease, box-shadow 0.05s ease, background 0.05s ease;
 
   -webkit-box-shadow: 0px 0px 0px #8e44ad;
   -moz-box-shadow: 0px 0px 0px #8e44ad;

+ 11 - 16
busunit/DIUv2/html/index-ORG.html

@@ -296,22 +296,17 @@ ETH0 = 00:80:66:10:E8:8A
 
         <button class='invisiblock' id='ui_main_blockwindow'> </button>
 
-<textarea wrap="" class='statusmain' type='textarea' id='ui_main_status' rows='10' cols='40' onselect='return false;' unselectable='on' disabled readonly>
-012345678901234567890123456789012345678901234567890
-one
-two
-three
-four
-five
-six
-seeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeven
-eight
-nine
-ten
-eleven
-twelve
-thirtheen
-
+<textarea
+  wrap=""
+  class='statusmain'
+  type='textarea'
+  id='ui_main_status'
+  rows='10'
+  cols='40'
+  onselect='return false;'
+  unselectable='on'
+  disabled readonly>
+...
 </textarea>
 
         <!-- <div class='pure-u-1-2 col'> <button class='bstatus' id='ui_main_status'>status...</button> </div> -->

+ 202 - 24
busunit/DIUv2/html/js/diu_ui-ORG.js

@@ -1,7 +1,15 @@
 
-var _URL = "http://localhost";
+var _ADDRESS = "192.168.0.110";
+//var _URL = "http://localhost";
+var _URL = "http://" + _ADDRESS;
 var _PORT = 60535;
 
+var _fqADDRESS = _ADDRESS + ":" + _PORT;
+
+var BG_COLOR = "#f7f7f7";
+var TEXT_COLOR = "#444444";
+
+
 var g_ctx = {
 
   "driver_login_state" : "driver",
@@ -17,6 +25,31 @@ var g_ctx = {
   "bulkfare" : "",
   "bulkfare_count" : "",
 
+  "status_text": "",
+  "status_text_w": 0,
+  "status_text_h": 0,
+
+  "diu_status" : {},
+
+  /*
+  "rule" : {
+    "adult":"CASH-ADULT",
+    "youth":"CASH-YOUTH",
+    "half":"CASH-HALF",
+    "bike":"MISC-BIKE",
+    "wheelchair":"MISC-WHEELCHAIR",
+    "transfer":"MISC-TRANSFER",
+    "interline":"MISC-INTERLINE",
+    "event":"MISC-EVENT",
+    "schoola":"OVR-SCHOOLA",
+    "schoolb":"OVR-SCHOOLB",
+    "schoolc":"OVR-SCHOOLC",
+    "orga":"OVR-ORGA",
+    "orgb":"OVR-ORGB",
+    "orgc":"OVR-ORGC",
+  },
+  */
+
   "x": ""
 };
 
@@ -77,9 +110,13 @@ function _api_request(action, param, cb_ok, cb_fail, cb_neterr) {
   req.onerror = function() { console.log("network error"); };
 
   try {
-  req.open("POST", url, true);
-  req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-  req.send(varstr);
+
+    //DEBUG
+    console.log("req, varstr:", varstr);
+
+    req.open("POST", url, true);
+    req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+    req.send(varstr);
   } catch (er) {
     console.log(">>>>>>ERROR", er);
   }
@@ -266,10 +303,6 @@ function _driver_login(inp) {
     else if (uvar == "pin") {
       g_ctx.driver_login_state = "driver";
 
-
-      //_verify_driver();
-      //_switch_ui("ui_driver", "ui_driververify");
-
       _verify_driver();
       g_ctx.ui_change_timeoutid = window.setTimeout(function() {
         _switch_ui("ui_driververify");
@@ -313,10 +346,12 @@ function _driver_login(inp) {
 function _verify_paddle() {
   var paddle = g_ctx.paddle;
 
-  _api_request("paddleinput", {"paddle":paddle}, _verify_paddle_ok, _verify_paddle_fail);
+  _api_request("paddleinput", {"paddle":paddle}, _verify_paddle_ack, _verify_paddle_fail);
   return;
 }
 
+function _verify_paddle_ack()    { console.log("got ack for push paddle message\n"); }
+
 function _verify_paddle_ok()    { _switch_ui("ui_main"); }
 function _verify_paddle_fail()  { _switch_ui("ui_paddleunknown"); }
 function _paddle_unknown(inp)   {
@@ -331,8 +366,8 @@ function _paddle_input(inp) {
 
   if (inp == 'cancel')    { _switch_ui('ui_login'); }
   else if (inp == 'ok')   {
-    _verify_paddle();
 
+    _verify_paddle();
     g_ctx.ui_change_timeoutid = window.setTimeout(function() {
       _switch_ui("ui_paddleverify");
     }, 150);
@@ -365,32 +400,32 @@ function _main_nxt() {
 
 function _fare_adult() {
   console.log("fare adult");
-  _api_request("fare", {"fare":"adult","count":1});
+  _api_request("fare", {"rule":"CASH-ADULT", "param":"", "fare":"adult","count":1});
 }
 
 function _fare_youth() {
   console.log("fare youth");
-  _api_request("fare", {"fare":"youth","count":1});
+  _api_request("fare", {"rule":"CASH-YOUTH", "param":"", "fare":"youth","count":1});
 }
 
 function _fare_half() {
   console.log("fare half");
-  _api_request("fare", {"fare":"half","count":1});
+  _api_request("fare", {"rule":"CASH-HALF", "param":"", "fare":"half","count":1});
 }
 
 function _fare_bike() {
   console.log("fare bike");
-  _api_request("fare", {"fare":"bike","count":1});
+  _api_request("fare", {"rule":"MISC-BIKE", "param":"", "fare":"bike","count":1});
 }
 
 function _fare_wheelchair() {
   console.log("fare wheelchair");
-  _api_request("fare", {"fare":"wheelchair","count":1});
+  _api_request("fare", {"rule":"MISC-WHEELCHAIR", "param":"", "fare":"wheelchair","count":1});
 }
 
 function _fare_transfer() {
   console.log("fare transfer");
-  _api_request("fare", {"fare":"transfer","count":1});
+  _api_request("fare", {"rule":"MISC-TRANSFER", "param":"", "fare":"transfer","count":1});
 }
 
 //-------------
@@ -416,7 +451,7 @@ function _bulkaccept_ok() {
   console.log("bulkfare:", g_ctx.bulkfare, ", count:", g_ctx.bulkfare_count);
   _switch_ui("ui_main");
 
-  _api_request("fare",{"fare":g_ctx.bulkfare,"count":g_ctx.bulkfare_count});
+  _api_request("fare",{"rule":g_ctx.bulkfare, "param":g_ctx.bulkfare_count.toString(), "fare":g_ctx.bulkfare,"count":g_ctx.bulkfare_count});
 }
 
 function _bulkaccept_cancel() {
@@ -446,16 +481,50 @@ function _bulkaccept_input(inp) {
 function _cb_status(inp) {
   //console.log("_cb_status>>\n", inp);
 
-  var fields = inp.substr(3).split(";");
-  var fv = {};
+  var tok = inp.split(" ");
+  if (tok.length < 2) { return; }
+  if (tok[0]!="ok") { return; }
+
+  var valtok = tok[1].split("\n");
+  if (valtok[0]!="msg=status") { return; }
 
+  g_ctx.diu_status = {};
+  var fields = valtok[1].split("|");
   for (var ii=0; ii<fields.length; ii++) {
     var kv = fields[ii].split("=");
-    fv[kv[0]] = kv[1];
+    g_ctx.diu_status[kv[0]] = kv[1];
+
+
   }
 
   //for (var x in fv) { console.log(x, ";;;", fv[x]); }
 
+  var m = g_ctx.diu_status;
+  if (g_ctx.current_ui === "ui_login") {
+    var ele = document.getElementById("ui_login_status");
+    var str = "";
+    str += "Tunnel: " + m["tunnel"] + "  GPRS: " + m["gprs"] + "  Eq#: " + m["equipno"] + "  #Msg: " + m["nmsg"] + "\n";
+    str += "Last Token Read (" + m["last_token"] + ")\n";
+    str += "GPS: " + m["gps"] + "\n";
+    str += "\n";
+    str += "Package   Version   Installed\n";
+    str += "\n";
+    str += "\n";
+
+    ele.innerHTML = str;
+  }
+  else if (g_ctx.current_ui === "ui_main") {
+    var ele = document.getElementById("mainstatus");
+    var str = "";
+    str += "Rt " + m["route"] + " ";
+    str += "Trip " + m["trip"] + " ";
+    str += "Stop " + m["stop"] + " ";
+    str += "GPS " + m["gps"] + " ";
+    str += "Tun " + m["tunnel"] + " ";
+    str += m["date"];
+
+    ele.innerHTML = str;
+  }
 
 }
 
@@ -463,12 +532,110 @@ function _cb_status_err(e) {
   console.log("ERROR: _cb_status_err:", e);
 }
 
+//-------------
+
+function _main_message_replace(msg, bg_color, text_color) {
+  var ele = document.getElementById("ui_main_status");
+  g_ctx.status_text_w = ele.cols;
+  g_ctx.status_text_h = ele.rows;
+
+  bg_color = ((typeof bg_color === "undeinfed") ? BG_COLOR : bg_color);
+  text_color = ((typeof text_color === "undefined") ? TEXT_COLOR : text_color);
+
+  var lines = g_ctx.status_text.split("\n");
+  if (lines.length > g_ctx.status_text_h) {
+    var n = lines.length;
+    lines = lines.slice(n - g_ctx.status_text_h);
+  }
+  for (var i=0; i<lines.length; i++) {
+    lines[i] = lines[i].slice(0,g_ctx.status_text_w);
+  }
+
+  var idx = lines.length-1;
+  if (idx<0) { idx = 0; }
+
+  lines[idx] = msg;
+
+  g_ctx.status_text = lines.join("\n");
+  ele.innerHTML = g_ctx.status_text;
+
+  console.log(">>replace:", msg);
+}
+
+function _main_message_add(msg, bg_color, text_color) {
+  var ele = document.getElementById("ui_main_status");
+  g_ctx.status_text_w = ele.cols;
+  g_ctx.status_text_h = ele.rows;
+
+  bg_color = ((typeof bg_color === "undeinfed") ? BG_COLOR : bg_color);
+  text_color = ((typeof text_color === "undefined") ? TEXT_COLOR : text_color);
+
+  var txt = g_ctx.status_text + "\n" + msg;
+
+  var lines = txt.split("\n");
+  if (lines.length > g_ctx.status_text_h) {
+    var n = lines.length;
+    lines = lines.slice(n - g_ctx.status_text_h);
+  }
+  for (var i=0; i<lines.length; i++) {
+    lines[i] = lines[i].slice(0,g_ctx.status_text_w);
+  }
+
+  g_ctx.status_text = lines.join("\n");
+  ele.innerHTML = g_ctx.status_text;
+
+  console.log(">>add:", msg);
+}
+
+
 //-------------
 //-------------
 //-------------
 
+function _ws_process(dat) {
+
+  var tok = dat.split(" ");
+  
+  if (tok.length < 2) { return; }
+
+  if (tok[0] == "paddle") {
+    if      (tok[1] == "ok")    { _verify_paddle_ok(); }
+    else if (tok[1] == "fail")  { _verify_paddle_fail(); }
+    else { _verify_paddle_fail(); }
+  }
+
+  else if (tok[0] == "driver_notify") {
+    if (tok.length < 5) {
+      console.log("malformed message: ", dat);
+    }
+    else if (tok[1] == "replace") {
+      _main_message_replace(tok.slice(4).join(" "));
+    }
+    else if (tok[1] == "ok") {
+      _main_message_add(tok.slice(4).join(" "));
+    }
+    else {
+      console.log("unknown message: ", dat);
+    }
+  }
+
+
+}
+
+function _init_websocket() {
+  var sock = new WebSocket("ws://" + _fqADDRESS);
+  sock.onopen = function(e) { console.log("open", e); }
+  sock.onmessage = function(e) { _ws_process(e.data); }
+  sock.onclose = function(e) { console.log("close", e); }
+  sock.onerror = function(e) { console.log("error", e); }
+}
+
+//-------------
+
 function init() {
 
+  _init_websocket();
+
   // login
   //
   document.getElementById('ui_login_login').onclick = _login;
@@ -521,11 +688,16 @@ function init() {
 
   var bulk_pass = ["adult", "youth", "half", "event", "transfer", "interline",
                     "schoola", "schoolb", "schoolc", "orga", "orgb", "orgc"];
+  var bulk_rule = ["BULK-CASH-ADULT", "BULK-CASH-YOUTH", "BULK-CASH-HALF",
+                   "BULK-MISC-EVENT", "BULK-MISC-TRANSFER", "BULK-MISC-INTERLINE",
+                   "BULK-OVR-SCHOOLA", "BULK-OVR-SCHOOLB", "BULK-OVR-SCHOOLC",
+                   "BULK-OVR-ORGA", "BULK-OVR-ORGB", "BULK-OVR-ORGC"];
   var bulk_pass_name = ["Adult Cash", "Youth Cash", "Half Cash", "Special Event", "Transfer", "Interline",
                         "School A", "Sschool B", "School C", "Org A", "Org B", "Org C"];
   for (var i=0; i<bulk_pass.length; i++) {
     var p = bulk_pass[i];
     var u = bulk_pass_name[i];
+    var r = bulk_rule[i];
     var ele = document.getElementById('ui_bulk_' + p);
     ele.onclick = (function(x,y) {
       return function() {
@@ -535,7 +707,7 @@ function init() {
         var ee = document.getElementById("ui_bulkaccept_faretype");
         ee.innerHTML = y;
       };
-    })(p, u);
+    })(r, u);
   }
 
 
@@ -583,12 +755,18 @@ function init() {
                         "event", "interline",
                         "schoola", "schoolb", "schoolc",
                         "orga", "orgb", "orgc" ];
+  var override_rule = [ "CASH-ADULT", "CASH-YOUTH", "CASH-HALF",
+                        "MISC-BIKE", "MISC-WHEELCHAIR", "MISC-TRANSFER",
+                        "MISC-EVENT", "MISC-INTERLINE",
+                        "OVR-SCHOOLA", "OVR-SCHOOLB", "OVR-SCHOOLC",
+                        "OVR-ORGA", "OVR-ORGB", "OVR-ORGC" ];
   for (var i=0; i<override_pass.length; i++) {
     var p = override_pass[i];
+    var r = override_rule[i];
     var ele = document.getElementById("ui_fareoverride_" + p);
-    ele.onclick = (function(x) {
-      return function() { _api_request("fare", {"fare":x,"count":1}); };
-    })(p);
+    ele.onclick = (function(x,y) {
+      return function() { _api_request("fare", {"rule":x,"fare":y,"param":"","count":1}); };
+    })(r,p);
   }
 
 

+ 53 - 0
busunit/testing/rules-TEST.scm

@@ -181,6 +181,34 @@
   (bulk_generic rule_OVR-CARD (string->number (param)))
 )
 
+;---
+
+(define (rule_BULK-OVR-SCHOOLA)
+  (bulk_generic rule_OVR-SCHOOLA (string->number (param)))
+)
+
+(define (rule_BULK-OVR-SCHOOLB)
+  (bulk_generic rule_OVR-SCHOOLB (string->number (param)))
+)
+
+(define (rule_BULK-OVR-SCHOOLC)
+  (bulk_generic rule_OVR-SCHOOLC (string->number (param)))
+)
+
+;---
+
+(define (rule_BULK-OVR-ORGA)
+  (bulk_generic rule_OVR-ORGA (string->number (param)))
+)
+
+(define (rule_BULK-OVR-ORGB)
+  (bulk_generic rule_OVR-ORGB (string->number (param)))
+)
+
+(define (rule_BULK-OVR-ORGC)
+  (bulk_generic rule_OVR-ORGC (string->number (param)))
+)
+
 ;-----
 
 (define (rule_TEST-ORG-TEST)
@@ -194,6 +222,31 @@
   (accept_fare "Test School Pass" "Test School Pass" 0)
 )
 
+(define (rule_OVR-SCHOOLA)
+  (accept_fare_no_passback "School A Override" "School A Override" 0)
+)
+
+(define (rule_OVR-SCHOOLB)
+  (accept_fare_no_passback "School B Override" "School B Override" 0)
+)
+
+(define (rule_OVR-SCHOOLC)
+  (accept_fare_no_passback "School C Override" "School C Override" 0)
+)
+
+(define (rule_OVR-ORGA)
+  (accept_fare_no_passback "Org A Override" "Org A Override" 0)
+)
+
+(define (rule_OVR-ORGB)
+  (accept_fare_no_passback "Org B Override" "Org B Override" 0)
+)
+
+(define (rule_OVR-ORGC)
+  (accept_fare_no_passback "Org C Override" "Org C Override" 0)
+)
+
+
 (define (rule_TEST-GOV-PASS)
   (tell_rider "Test Gov Pass")
   (accept_fare "Test Gov Pass" "Test Gov Pass" 0)