From 8f18e3412c7c260dc50ed93fa33840a08a56be41 Mon Sep 17 00:00:00 2001
From: Jake Read <jake.read@cba.mit.edu>
Date: Thu, 15 Nov 2018 14:54:27 -0500
Subject: [PATCH] ready to machine demo

---
 README.md                                |   5 +
 client/client.js                         |   9 +-
 client/divtools.js                       |  12 +-
 modules/dev/depricated/bridge.js         | 287 ---------------------
 modules/dev/depricated/servo.js          |  63 -----
 modules/dev/depricated/test.js           |  56 -----
 modules/hardware/atkseriallink.js        |   5 +-
 modules/motion/planner.js                |   2 +
 programs/{hwtst-3.json => hwtest-4.json} |  62 ++---
 programs/hwtest.json                     | 308 -----------------------
 programs/{hwtest-2.json => hwtst-5.json} | 116 +++++----
 11 files changed, 130 insertions(+), 795 deletions(-)
 delete mode 100644 modules/dev/depricated/bridge.js
 delete mode 100644 modules/dev/depricated/servo.js
 delete mode 100644 modules/dev/depricated/test.js
 rename programs/{hwtst-3.json => hwtest-4.json} (93%)
 delete mode 100644 programs/hwtest.json
 rename programs/{hwtest-2.json => hwtst-5.json} (85%)

diff --git a/README.md b/README.md
index e3f2c10..733f49b 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,9 @@ Herein will contain a list of known problems / common errors and their fixes.
 
 ## For MW
 
+ - want that better-planner
+ - do axis pullout separately from stepper motor ?
+
  - bug hunting
   - dereferenced events / stepper axis vector 
   - multiple button calls ... 
@@ -165,6 +168,8 @@ To assemble a representation of these, we want to have a kind of 'netlist' that,
 - heirarchy zoom 
  - architectural clarity betwixt UI and Heap 
 - some auto load / save currently.json file so that we can restart program w/o pain ... maybe just save on new user inputs ? 
+- state.setDefault('var', num) or etc / types
+- perhaps all state objects like this ... still somehow state.var = // is a good operator ? don't really want state.var.set(num) and state.var.get() 
 - states / uis / etc - one off / one-at-a-time for updates 
  - i.e. all f'n update calls are to single module-global state update
  - ! 
diff --git a/client/client.js b/client/client.js
index 7932d80..72aba40 100644
--- a/client/client.js
+++ b/client/client.js
@@ -312,6 +312,9 @@ function redrawLinks() {
     while (svg.firstChild) {
         svg.removeChild(svg.firstChild)
     }
+    // draw origin 
+    var og1 = newLine(-15,0,15,0,5, false)
+    var og2 = newLine(0,-15,0,15,5, false)
     // find that link
     var lnkPt
     var nLnk = 0
@@ -343,7 +346,7 @@ function redrawLinks() {
             nLnk++
             var hwPt = getRightWall(mdlRep.ui.domElem)
             lnkPt.y += 5 * nLnk
-            var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
+            var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y, 7, true)
         }
     }
 }
@@ -592,6 +595,10 @@ function heapSendsProgramMenu(tree) {
     menuDom.id = 'programMenu'
     menuDom.style.left = lastPos.x + 'px'
     menuDom.style.top = lastPos.y + 'px'
+    var title = document.createElement('div')
+    title.className = 'title'
+    title.innerHTML = 'program menu'
+    menuDom.appendChild(title)
     for (key in tree) {
         var li = document.createElement('li')
         var path = tree[key].path
diff --git a/client/divtools.js b/client/divtools.js
index ba16c01..0a50ee2 100644
--- a/client/divtools.js
+++ b/client/divtools.js
@@ -298,13 +298,19 @@ function getInputArrow(div) {
     return pos
 }
 
-function newLine(x1, y1, x2, y2) {
+function newLine(x1, y1, x2, y2, stroke, dashed) {
     var ln = {}
     ln.elem = document.createElementNS(svgns, 'line')
     ln.elem.style.stroke = '#1a1a1a'
-    ln.elem.setAttribute('stroke-dasharray', '21, 7, 7, 7')
+    if(dashed){
+        ln.elem.setAttribute('stroke-dasharray', '21, 7, 7, 7')
+    }
     ln.elem.style.fill = 'none'
-    ln.elem.style.strokeWidth = '6px'
+    if(stroke){
+        ln.elem.style.strokeWidth = stroke + 'px'
+    } else {
+        ln.elem.style.strokeWidth = '6px'
+    }
     ln.x1 = x1
     ln.y1 = y1
     ln.x2 = x2
diff --git a/modules/dev/depricated/bridge.js b/modules/dev/depricated/bridge.js
deleted file mode 100644
index ddf2d97..0000000
--- a/modules/dev/depricated/bridge.js
+++ /dev/null
@@ -1,287 +0,0 @@
-// boilerplate atkapi header
-const InOut = require('../../lib/jsunit.js')
-let Input = InOut.Input
-let Output = InOut.Output
-
-let State = InOut.State
-let Button = InOut.Button
-
-const serialport = require('serialport')
-
-function ATKBridge() {
-    var bridge = {
-        description: {
-            name: 'ATK Hardware Bridge',
-            alt: 'talks over serialport',
-            isHardware: true
-        }
-    }
-
-    var state = State()
-    bridge.state = state
-
-    state.rA = '0,0'
-    state.rB = '0,1'
-    state.rC = '0,2'
-    state.rD = '0,3'
-    state.rE = '0,4'
-    state.rF = '0,5'
-    state.rG = '0'
-
-    state.findPort = Button('click to find atk port', findPort)
-    state.portName = '---'
-    state.connect = Button('click to connect', openPort)
-    state.portStatus = 'closed' // or we hope it will be 
-    state.terminal = 'address | key:values'
-
-    /*
-    ------------------------------------------------------
-    SERIALPORT MANAGEMENT 
-    ------------------------------------------------------
-    */
-
-    port = null
-
-    function findPort() {
-        serialport.list(function(err, ports) {
-            ports.forEach(function(port) {
-                if (port.manufacturer == 'Silicon Labs') {
-                    console.log('found cp2102 port')
-                    state.portName = port.comName
-                    openPort()
-                }
-            })
-        })
-    }
-
-    bridge.init = openPort
-
-    function openPort() {
-        if (state.portName == '---') {
-            findPort()
-        } else {
-            if (port == null) {
-                port = new serialport(state.portName, {
-                    baudRate: 250000
-                })
-                port.on('open', function() {
-                    state.portStatus = 'open'
-                })
-                port.on('error', function(err) {
-                    state.portStatus = err.message
-                })
-                port.on('data', onPortData)
-            }
-        }
-    }
-
-
-    function sendToHardware(pckt) {
-        if (port != null && port.writable) {
-            if (port.write(pckt)) {
-                return true
-            } else {
-                console.log('------------------ !ACHTUNG! -------------------')
-                console.log('------------------ !ACHTUNG! -------------------')
-                console.log('---------- port.write(pckt) false --------------')
-                // https://nodejs.org/api/stream.html#stream_event_drain
-                // https://serialport.io/docs/api-stream
-            }
-            return true
-        } else {
-            return false
-        }
-    }
-
-    /*
-    ------------------------------------------------------
-    PACKETS TO HARDWARE
-    ------------------------------------------------------
-    */
-
-    // from software output to hardware ... 
-    bridge.inputs = {
-        A: Input('headless packet', function(pckt) {
-            onSoftwareInput('rA', pckt)
-        }),
-        B: Input('headless packet', function(pckt) {
-            onSoftwareInput('rB', pckt)
-        }),
-        C: Input('headless packet', function(pckt) {
-            onSoftwareInput('rC', pckt)
-        }),
-        D: Input('headless packet', function(pckt) {
-            onSoftwareInput('rD', pckt)
-        }),
-        E: Input('headless packet', function(pckt) {
-            onSoftwareInput('rE', pckt)
-        }),
-        F: Input('headless packet', function(pckt) {
-            onSoftwareInput('rF', pckt)
-        }),
-        G: Input('headless packet', function(pckt) {
-            onSoftwareInput('rG', pckt)
-        })
-    }
-
-    function onSoftwareInput(key, pckt) {
-        // it would be responsible to check this over now, but hey 
-        var packet = JSON.parse(JSON.stringify(pckt))
-        if (Array.isArray(pckt)) {
-            packet.unshift(255) // end delimiter
-            packet.unshift(254) // ptr 
-            var route = state[key].split(',')
-            packet = route.concat(packet)
-            if (packet.length > 128) {
-                console.log("LARGE PACKET ALERT:", packet.length)
-            }
-            packet.unshift(packet.length + 1)
-            if (sendToHardware(packet)) {
-                console.log('PCKT OOT >>', packet.toString())
-            } else {
-                console.log('ERR: attempt to send to hardware, port not writable')
-            }
-
-        } else {
-            console.log('non-array on bridge input')
-        }
-
-    }
-
-    function parseTerminal(str) {
-        console.log('ready to parse...', str, 'as packet')
-    }
-
-    /*
-    ------------------------------------------------------
-    PACKETS FROM HARDWARE 
-    ------------------------------------------------------
-    */
-
-    // from hardware outputs to software ... 
-    bridge.outputs = {
-        A: Output('headless packet'),
-        B: Output('headless packet'),
-        C: Output('headless packet'),
-        D: Output('headless packet'),
-        E: Output('headless packet'),
-        F: Output('headless packet'),
-        G: Output('headless packet')
-    }
-
-    bridge.pairs = {
-        A: {
-            route: state.rA,
-            output: bridge.outputs.A
-        },
-        B: {
-            route: state.rB,
-            output: bridge.outputs.B
-        },
-        C: {
-            route: state.rC,
-            output: bridge.outputs.C
-        },
-        D: {
-            route: state.rD,
-            output: bridge.outputs.D
-        },
-        E: {
-            route: state.rE,
-            output: bridge.outputs.E
-        }
-    }
-
-    var thisPacket = new Array()
-
-    function onPortData(data) {
-        // we'll make sure it's what we think it will be
-        // console.log("PORT DATA")
-        var dtArray = new Array()
-        if (Buffer.isBuffer(data)) {
-            for (var i = 0; i < data.length; i++) {
-                dtArray[i] = data[i]
-            }
-        } else {
-            console.log("ERR: port data non-buffer")
-        }
-
-        //console.log('DATA IN', dtArray.toString())
-
-        thisPacket = thisPacket.concat(dtArray)
-        if (thisPacket[0] <= 0) {
-            thisPacket = []
-            console.log('throwing packet with leading zero')
-        }
-
-        while (thisPacket.length >= thisPacket[0]) {
-            if (thisPacket.length == thisPacket[0]) {
-                var packetCopy = thisPacket.slice(0) // copy, deref
-                thisPacket = []
-                onPacket(packetCopy)
-            } else { // rare case of two packets saddling break 
-                var fullPacket = thisPacket.slice(0, thisPacket[0])
-                onPacket(fullPacket)
-                thisPacket = thisPacket.slice(thisPacket[0])
-            }
-
-        }
-    }
-
-    function onPacket(pckt) {
-        var debug = false
-        shiftPacketPointer(pckt)
-        console.log('PCKT IN <<', pckt.toString(), '-----------------------')
-        var incomingRoute = pckt.slice(2, pckt.indexOf(255))
-        // flip to match outgoing 
-        var returnRoute = new Array()
-        for (i in incomingRoute) {
-            returnRoute[i] = incomingRoute[incomingRoute.length - 1 - i]
-        }
-        var match = null
-        for (key in bridge.state) {
-            if (returnRoute.toString() === bridge.state[key].toString()) {
-                //console.log("FFFFFFFFFFFFFFFFFFOUND", key)
-                if (key.toString().charAt(0) == '_') {
-                    // bail
-                } else {
-                    //console.log(bridge.state[key])
-                    var outKey = key.toString().charAt(1)
-                    match = outKey
-                    var headless = pckt.slice(pckt.indexOf(255) + 1)
-                    //console.log('headless', headless)
-                    bridge.outputs[outKey].emit(headless)
-                    return true
-                }
-            }
-        }
-        if (match == null) {
-            console.log("PACKET RETURN AND NO KEY FOUND")
-            console.log(pckt)
-            console.log(bridge.pairs)
-        }
-    }
-
-    function shiftPacketPointer(pckt) {
-        var end = 0
-        var i = 0
-        while (end == 0) {
-            if (pckt[i] === 255) {
-                end = i
-            } else if (i >= pckt.length) {
-                break
-            }
-            i++
-        }
-        //array[1] = 254
-        for (var j = 1; j < end - 1; j++) {
-            pckt[j] = pckt[j + 1]
-        }
-        pckt[end - 1] = 0
-        // console.log('shifted', pckt)
-    }
-
-    return bridge
-}
-
-module.exports = ATKBridge
\ No newline at end of file
diff --git a/modules/dev/depricated/servo.js b/modules/dev/depricated/servo.js
deleted file mode 100644
index 1c1978b..0000000
--- a/modules/dev/depricated/servo.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// boilerplate atkapi header
-const InOut = require('../../lib/jsunit.js')
-let Input = InOut.Input
-let Output = InOut.Output
-let State = InOut.State
-let Button = InOut.Button
-
-const PCKT = require('../../lib/packets.js')
-
-// a constructor, a fn, a javascript mess
-function Servo() {
-
-    var servo = {
-        // descriptions are used in UI
-        description: {
-            name: 'Breadboard Servo Signal Generator',
-            alt: 'servo',
-            isHardware: true
-        }
-    }
-
-    servo.state = State()
-    // alias !
-    var state = servo.state
-
-    state.button = Button('SEND')
-    state.onChange('button', onButtonPress)
-    state.servoVal = 0 // 0->100 does 1 -> 2ms duty on 20ms period
-    state.onChange('servoVal', onButtonPress)
-
-    servo.inputs = {
-        packet: Input('headless packet', onPacketReturn) // makes anything into '1' event
-    }
-
-    servo.outputs = {
-        packet: Output('number')
-    }
-
-    function onButtonPress(evt) {
-        var pwm = state.servoVal
-        if(pwm > 100){
-            pwm = 100
-        } else if (pwm < 0){
-            pwm = 0
-        }
-
-        var microval = Math.round(7.5 * pwm)
-        console.log('pwm on line', microval)
-
-        var pwmpack = PCKT.pack32(microval)
-        pwmpack.unshift(141)
-
-        servo.outputs.packet.emit(pwmpack)
-    }
-
-    function onPacketReturn(evt) {
-    }
-
-    return servo
-}
-
-// exports 
-module.exports = Servo
\ No newline at end of file
diff --git a/modules/dev/depricated/test.js b/modules/dev/depricated/test.js
deleted file mode 100644
index 08fc4a1..0000000
--- a/modules/dev/depricated/test.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// boilerplate atkapi header
-const InOut = require('../../lib/jsunit.js')
-let Input = InOut.Input
-let Output = InOut.Output
-let State = InOut.State
-let Button = InOut.Button
-
-// a constructor, a fn, a javascript mess
-function Test() {
-
-    var test = {
-        // descriptions are used in UI
-        description: {
-            name: 'Test Packet',
-            alt: 'net state',
-            isHardware:true
-        }
-    }
-
-    test.state = State()
-    // alias !
-    var state = test.state
-
-    state.button = Button('TEST')
-    state.onChange('button', onButtonPress)
-    state.message = 'no test started'
-
-    test.inputs = {
-        packet: Input('headless packet', onPacketReturn), 
-        trigger: Input('event', onButtonPress)
-    }
-
-    test.outputs = {
-        packet: Output('number')
-    }
-
-    function onButtonPress(evt) {
-        state.message = 'packet out'
-        var tstpck = new Array()
-        tstpck.push(127)
-        test.outputs.packet.emit(tstpck)
-    }
-
-    function onPacketReturn(evt) {
-        if (evt[0] == '127') {
-            state.message = 'packet return OK'
-        } else {
-            state.message = 'other packet return'
-        }
-    }
-
-    return test
-}
-
-// exports 
-module.exports = Test
\ No newline at end of file
diff --git a/modules/hardware/atkseriallink.js b/modules/hardware/atkseriallink.js
index a42a6e2..c1d21cd 100644
--- a/modules/hardware/atkseriallink.js
+++ b/modules/hardware/atkseriallink.js
@@ -64,10 +64,6 @@ function ATKSerialLink() {
                 }
             })
         })
-        if(!found){
-            console.log('LINK ERR: no CP2102 device found, try serialport-list to make sure it is available to the system')
-            state.portStatus = 'no CP2102 device found'
-        }
     }
 
     function openSerialPort() {
@@ -78,6 +74,7 @@ function ATKSerialLink() {
                 serialport = new SerialPort(state.portName, {
                     baudRate: 250000
                 })
+                state.portStatus = 'opening'
                 serialport.on('open', function() {
                     state.portStatus = 'open'
                 })
diff --git a/modules/motion/planner.js b/modules/motion/planner.js
index aec37ff..8f2f19c 100644
--- a/modules/motion/planner.js
+++ b/modules/motion/planner.js
@@ -59,6 +59,7 @@ function Planner() {
     // i.e. one thing we can do is assert a starting value 
     planner.init = function(){
         state.isRunning = 0 
+        state.netState = [0, 0, 0]
     }
 
     /*
@@ -166,6 +167,7 @@ function Planner() {
             for (i in state.netState) {
                 state.netState[i]++
             }
+            state.netState = state.netState
             // dereference
             var move = JSON.parse(JSON.stringify(mq.shift()))
             console.log("MOVE FROM PLANNER", move)
diff --git a/programs/hwtst-3.json b/programs/hwtest-4.json
similarity index 93%
rename from programs/hwtst-3.json
rename to programs/hwtest-4.json
index d0adf2a..4d8925b 100644
--- a/programs/hwtst-3.json
+++ b/programs/hwtest-4.json
@@ -13,14 +13,14 @@
         "isHardware": true,
         "isLink": true,
         "position": {
-          "left": 968,
-          "top": 347
+          "left": 1922,
+          "top": 383
         }
       },
       "inputs": {},
       "outputs": {},
       "state": {
-        "portName": "COM10",
+        "portName": "COM3",
         "connect": {
           "type": "button",
           "label": "click to find and connect"
@@ -36,8 +36,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 457,
-          "top": 91
+          "left": 1427,
+          "top": 127
         }
       },
       "inputs": {
@@ -70,7 +70,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,3",
         "rate": 2000,
         "axis": "X",
@@ -92,8 +92,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 456,
-          "top": 491
+          "left": 1432,
+          "top": 504
         }
       },
       "inputs": {
@@ -126,7 +126,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,0",
         "rate": 2000,
         "axis": "Y",
@@ -148,8 +148,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 457,
-          "top": 883
+          "left": 1438,
+          "top": 871
         }
       },
       "inputs": {
@@ -182,7 +182,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,5",
         "rate": 2000,
         "axis": "Y",
@@ -204,8 +204,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 459,
-          "top": 1274
+          "left": 1440,
+          "top": 1248
         }
       },
       "inputs": {
@@ -238,7 +238,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test packet out",
+        "message": "click above to test network",
         "route": "0,1",
         "rate": 2000,
         "axis": "Z",
@@ -260,8 +260,8 @@
         "path": "./modules/hardware/atkbreadboard.js",
         "isHardware": true,
         "position": {
-          "left": 891,
-          "top": 1354
+          "left": 1886,
+          "top": 1362
         }
       },
       "inputs": {
@@ -291,7 +291,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,2",
         "servoButton": {
           "type": "button",
@@ -311,8 +311,8 @@
         "alt": "for clicking",
         "path": "./modules/ui/button.js",
         "position": {
-          "left": -544,
-          "top": 337
+          "left": 591,
+          "top": 332
         }
       },
       "inputs": {
@@ -349,8 +349,8 @@
         "alt": "for clicking",
         "path": "./modules/ui/number.js",
         "position": {
-          "left": -545,
-          "top": 605
+          "left": 586,
+          "top": 566
         }
       },
       "inputs": {
@@ -387,8 +387,8 @@
         "alt": "in ... out",
         "path": "./modules/util/delay.js",
         "position": {
-          "left": -546,
-          "top": 499
+          "left": 589,
+          "top": 464
         }
       },
       "inputs": {
@@ -418,8 +418,8 @@
         "alt": "movements -> acceleration planned moves",
         "path": "./modules/motion/planner.js",
         "position": {
-          "left": -31,
-          "top": 91
+          "left": 822,
+          "top": 1020
         }
       },
       "inputs": {
@@ -478,7 +478,7 @@
           0,
           0
         ],
-        "isRunning": 1,
+        "isRunning": 0,
         "netWindow": 3,
         "netState": [
           0,
@@ -494,8 +494,8 @@
         "alt": "line of gcode -> planner recognized move",
         "path": "./modules/parsing/gcode.js",
         "position": {
-          "left": -556,
-          "top": 83
+          "left": 583,
+          "top": 111
         }
       },
       "inputs": {
@@ -531,8 +531,8 @@
         "alt": "sequential txt input",
         "path": "./modules/ui/multiline.js",
         "position": {
-          "left": -1117,
-          "top": 89
+          "left": 24,
+          "top": 99
         }
       },
       "inputs": {
diff --git a/programs/hwtest.json b/programs/hwtest.json
deleted file mode 100644
index 7ccaf45..0000000
--- a/programs/hwtest.json
+++ /dev/null
@@ -1,308 +0,0 @@
-{
-  "description": {
-    "name": "new program",
-    "counter": 5
-  },
-  "modules": {
-    "Serialport ATK Link-1": {
-      "description": {
-        "id": "Serialport ATK Link-1",
-        "name": "Serialport ATK Link",
-        "alt": "window into hardware world",
-        "path": "./modules/hardware/atkseriallink.js",
-        "isHardware": true,
-        "isLink": true,
-        "position": {
-          "left": 968,
-          "top": 347
-        }
-      },
-      "inputs": {},
-      "outputs": {},
-      "state": {
-        "portName": "COM10",
-        "connect": {
-          "type": "button",
-          "label": "click to find and connect"
-        },
-        "portStatus": "open"
-      }
-    },
-    "ATKStepper-0": {
-      "description": {
-        "id": "ATKStepper-0",
-        "name": "ATKStepper",
-        "alt": "software representation of stepper motor",
-        "path": "./modules/hardware/atkstepper.js",
-        "isHardware": true,
-        "position": {
-          "left": 457,
-          "top": 91
-        }
-      },
-      "inputs": {
-        "trapezoid": {
-          "accepts": "move instruction"
-        },
-        "accel": {
-          "accepts": "number"
-        },
-        "rmtrig": {
-          "accepts": "event"
-        }
-      },
-      "outputs": {
-        "ack": {
-          "emits": "move acknowledgement",
-          "calls": []
-        },
-        "position": {
-          "emits": "number",
-          "calls": []
-        }
-      },
-      "state": {
-        "reset": {
-          "type": "button",
-          "label": "reset hardware"
-        },
-        "test": {
-          "type": "button",
-          "label": "test network"
-        },
-        "message": "test OK",
-        "route": "0,3",
-        "rate": 2000,
-        "axis": "X",
-        "spu": 200,
-        "rawMove": -10,
-        "makeMove": {
-          "type": "button",
-          "label": "test move"
-        },
-        "lead": 0,
-        "position": 0
-      }
-    },
-    "ATKStepper-2": {
-      "description": {
-        "id": "ATKStepper-2",
-        "name": "ATKStepper",
-        "alt": "software representation of stepper motor",
-        "path": "./modules/hardware/atkstepper.js",
-        "isHardware": true,
-        "position": {
-          "left": 456,
-          "top": 491
-        }
-      },
-      "inputs": {
-        "trapezoid": {
-          "accepts": "move instruction"
-        },
-        "accel": {
-          "accepts": "number"
-        },
-        "rmtrig": {
-          "accepts": "event"
-        }
-      },
-      "outputs": {
-        "ack": {
-          "emits": "move acknowledgement",
-          "calls": []
-        },
-        "position": {
-          "emits": "number",
-          "calls": []
-        }
-      },
-      "state": {
-        "reset": {
-          "type": "button",
-          "label": "reset hardware"
-        },
-        "test": {
-          "type": "button",
-          "label": "test network"
-        },
-        "message": "test OK",
-        "route": "0,0",
-        "rate": 2000,
-        "axis": "Y",
-        "spu": -200,
-        "rawMove": -10,
-        "makeMove": {
-          "type": "button",
-          "label": "test move"
-        },
-        "lead": 0,
-        "position": 0
-      }
-    },
-    "ATKStepper-3": {
-      "description": {
-        "id": "ATKStepper-3",
-        "name": "ATKStepper",
-        "alt": "software representation of stepper motor",
-        "path": "./modules/hardware/atkstepper.js",
-        "isHardware": true,
-        "position": {
-          "left": 457,
-          "top": 883
-        }
-      },
-      "inputs": {
-        "trapezoid": {
-          "accepts": "move instruction"
-        },
-        "accel": {
-          "accepts": "number"
-        },
-        "rmtrig": {
-          "accepts": "event"
-        }
-      },
-      "outputs": {
-        "ack": {
-          "emits": "move acknowledgement",
-          "calls": []
-        },
-        "position": {
-          "emits": "number",
-          "calls": []
-        }
-      },
-      "state": {
-        "reset": {
-          "type": "button",
-          "label": "reset hardware"
-        },
-        "test": {
-          "type": "button",
-          "label": "test network"
-        },
-        "message": "test OK",
-        "route": "0,5",
-        "rate": 2000,
-        "axis": "Y",
-        "spu": 200,
-        "rawMove": -10,
-        "makeMove": {
-          "type": "button",
-          "label": "test move"
-        },
-        "lead": 0,
-        "position": 0
-      }
-    },
-    "ATKStepper-4": {
-      "description": {
-        "id": "ATKStepper-4",
-        "name": "ATKStepper",
-        "alt": "software representation of stepper motor",
-        "path": "./modules/hardware/atkstepper.js",
-        "isHardware": true,
-        "position": {
-          "left": 459,
-          "top": 1274
-        }
-      },
-      "inputs": {
-        "trapezoid": {
-          "accepts": "move instruction"
-        },
-        "accel": {
-          "accepts": "number"
-        },
-        "rmtrig": {
-          "accepts": "event"
-        }
-      },
-      "outputs": {
-        "ack": {
-          "emits": "move acknowledgement",
-          "calls": []
-        },
-        "position": {
-          "emits": "number",
-          "calls": []
-        }
-      },
-      "state": {
-        "reset": {
-          "type": "button",
-          "label": "reset hardware"
-        },
-        "test": {
-          "type": "button",
-          "label": "test network"
-        },
-        "message": "test packet out",
-        "route": "0,1",
-        "rate": 2000,
-        "axis": "Z",
-        "spu": 200,
-        "rawMove": -10,
-        "makeMove": {
-          "type": "button",
-          "label": "test move"
-        },
-        "lead": -2000,
-        "position": 0
-      }
-    },
-    "ATKBBB-Servo-5": {
-      "description": {
-        "id": "ATKBBB-Servo-5",
-        "name": "ATKBBB-Servo",
-        "alt": "software representation of networked hardware object",
-        "path": "./modules/hardware/atkbreadboard.js",
-        "isHardware": true,
-        "position": {
-          "left": 891,
-          "top": 1354
-        }
-      },
-      "inputs": {
-        "servoVal": {
-          "accepts": "number"
-        },
-        "adcRequest": {
-          "accepts": "event"
-        }
-      },
-      "outputs": {
-        "servoConf": {
-          "emits": "event",
-          "calls": []
-        },
-        "adcValue": {
-          "emits": "number",
-          "calls": []
-        }
-      },
-      "state": {
-        "reset": {
-          "type": "button",
-          "label": "reset hardware"
-        },
-        "test": {
-          "type": "button",
-          "label": "test network"
-        },
-        "message": "test OK",
-        "route": "0,2",
-        "servoButton": {
-          "type": "button",
-          "label": "SEND VALUE"
-        },
-        "servoVal": 0,
-        "adcButton": {
-          "type": "button",
-          "label": "REQUEST ADC CONVERSION"
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/programs/hwtest-2.json b/programs/hwtst-5.json
similarity index 85%
rename from programs/hwtest-2.json
rename to programs/hwtst-5.json
index 0886e2e..fa74ebb 100644
--- a/programs/hwtest-2.json
+++ b/programs/hwtst-5.json
@@ -13,14 +13,14 @@
         "isHardware": true,
         "isLink": true,
         "position": {
-          "left": 968,
-          "top": 347
+          "left": 1922,
+          "top": 383
         }
       },
       "inputs": {},
       "outputs": {},
       "state": {
-        "portName": "COM10",
+        "portName": "COM3",
         "connect": {
           "type": "button",
           "label": "click to find and connect"
@@ -36,8 +36,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 457,
-          "top": 91
+          "left": 1427,
+          "top": 127
         }
       },
       "inputs": {
@@ -54,7 +54,12 @@
       "outputs": {
         "ack": {
           "emits": "move acknowledgement",
-          "calls": []
+          "calls": [
+            {
+              "parentId": "Lookahead-Motion-Planner-10",
+              "key": "acks"
+            }
+          ]
         },
         "position": {
           "emits": "number",
@@ -70,7 +75,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,3",
         "rate": 2000,
         "axis": "X",
@@ -92,8 +97,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 456,
-          "top": 491
+          "left": 1432,
+          "top": 504
         }
       },
       "inputs": {
@@ -110,7 +115,12 @@
       "outputs": {
         "ack": {
           "emits": "move acknowledgement",
-          "calls": []
+          "calls": [
+            {
+              "parentId": "Lookahead-Motion-Planner-10",
+              "key": "acks"
+            }
+          ]
         },
         "position": {
           "emits": "number",
@@ -126,7 +136,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,0",
         "rate": 2000,
         "axis": "Y",
@@ -148,8 +158,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 457,
-          "top": 883
+          "left": 1438,
+          "top": 871
         }
       },
       "inputs": {
@@ -182,7 +192,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,5",
         "rate": 2000,
         "axis": "Y",
@@ -204,8 +214,8 @@
         "path": "./modules/hardware/atkstepper.js",
         "isHardware": true,
         "position": {
-          "left": 459,
-          "top": 1274
+          "left": 1440,
+          "top": 1248
         }
       },
       "inputs": {
@@ -222,7 +232,12 @@
       "outputs": {
         "ack": {
           "emits": "move acknowledgement",
-          "calls": []
+          "calls": [
+            {
+              "parentId": "Lookahead-Motion-Planner-10",
+              "key": "acks"
+            }
+          ]
         },
         "position": {
           "emits": "number",
@@ -238,7 +253,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test packet out",
+        "message": "click above to test network",
         "route": "0,1",
         "rate": 2000,
         "axis": "Z",
@@ -248,7 +263,7 @@
           "type": "button",
           "label": "test move"
         },
-        "lead": -2000,
+        "lead": -6000,
         "position": 0
       }
     },
@@ -260,8 +275,8 @@
         "path": "./modules/hardware/atkbreadboard.js",
         "isHardware": true,
         "position": {
-          "left": 891,
-          "top": 1354
+          "left": 1886,
+          "top": 1362
         }
       },
       "inputs": {
@@ -291,7 +306,7 @@
           "type": "button",
           "label": "test network"
         },
-        "message": "test OK",
+        "message": "click above to test network",
         "route": "0,2",
         "servoButton": {
           "type": "button",
@@ -311,8 +326,8 @@
         "alt": "for clicking",
         "path": "./modules/ui/button.js",
         "position": {
-          "left": -544,
-          "top": 337
+          "left": 591,
+          "top": 332
         }
       },
       "inputs": {
@@ -349,8 +364,8 @@
         "alt": "for clicking",
         "path": "./modules/ui/number.js",
         "position": {
-          "left": -545,
-          "top": 605
+          "left": 586,
+          "top": 566
         }
       },
       "inputs": {
@@ -387,8 +402,8 @@
         "alt": "in ... out",
         "path": "./modules/util/delay.js",
         "position": {
-          "left": -546,
-          "top": 499
+          "left": 589,
+          "top": 464
         }
       },
       "inputs": {
@@ -418,8 +433,8 @@
         "alt": "movements -> acceleration planned moves",
         "path": "./modules/motion/planner.js",
         "position": {
-          "left": -31,
-          "top": 91
+          "left": 822,
+          "top": 1020
         }
       },
       "inputs": {
@@ -436,7 +451,24 @@
       "outputs": {
         "moves": {
           "emits": "move instruction",
-          "calls": []
+          "calls": [
+            {
+              "parentId": "ATKStepper-0",
+              "key": "trapezoid"
+            },
+            {
+              "parentId": "ATKStepper-2",
+              "key": "trapezoid"
+            },
+            {
+              "parentId": "ATKStepper-3",
+              "key": "trapezoid"
+            },
+            {
+              "parentId": "ATKStepper-4",
+              "key": "trapezoid"
+            }
+          ]
         },
         "moveComplete": {
           "emits": "number",
@@ -464,9 +496,9 @@
         "isRunning": 1,
         "netWindow": 3,
         "netState": [
-          0,
-          0,
-          0
+          3,
+          3,
+          3
         ]
       }
     },
@@ -477,8 +509,8 @@
         "alt": "line of gcode -> planner recognized move",
         "path": "./modules/parsing/gcode.js",
         "position": {
-          "left": -556,
-          "top": 83
+          "left": 583,
+          "top": 111
         }
       },
       "inputs": {
@@ -503,7 +535,7 @@
       },
       "state": {
         "mode": "G0",
-        "G0": 1200,
+        "G0": 50,
         "G1": 400
       }
     },
@@ -514,8 +546,8 @@
         "alt": "sequential txt input",
         "path": "./modules/ui/multiline.js",
         "position": {
-          "left": -1117,
-          "top": 89
+          "left": 24,
+          "top": 99
         }
       },
       "inputs": {
@@ -553,19 +585,19 @@
           "type": "multiline",
           "label": "lines complete",
           "rows": 11,
-          "value": ""
+          "value": "\n\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10"
         },
         "now": {
           "type": "multiline",
           "label": "line just out",
           "rows": 1,
-          "value": ""
+          "value": "G0 X20Y20Z0"
         },
         "incoming": {
           "type": "multiline",
           "label": "future lines",
           "rows": 36,
-          "value": "G0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\n"
+          "value": "G0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\n"
         }
       }
     }
-- 
GitLab