diff --git a/canvas.js b/canvas.js
index bdbc6d5e23fa94dcfe389bede2d0e74e8c8f1a72..14b1a0af440550af2d91b60cf4b03703edb246f0 100644
--- a/canvas.js
+++ b/canvas.js
@@ -6,7 +6,6 @@ const Programs = require('./programs.js')
 // the program object: real simple, just has a description, and a 'modules' 
 var program = Programs.new('new program')
 
-
 var canvas = Programs.loadModuleFromSource(program, './modules/ui/threeCanvas.js')
 Programs.setUI(canvas, 200, 200)
 
diff --git a/littlerascal.js b/littlerascal.js
new file mode 100644
index 0000000000000000000000000000000000000000..769634c0951e483ea0e62da2b7675b2509dd71ee
--- /dev/null
+++ b/littlerascal.js
@@ -0,0 +1,148 @@
+// business 
+const Reps = require('./reps.js')
+const Programs = require('./programs.js')
+
+// the program object: real simple, just has a description, and a 'modules' 
+var program = Programs.new('new program')
+
+/* ok
+- new plotter 
+- ack four 
+- go to pos block 
+- neil:mm adjust 
+- git push
+- add y axis network wait ? 
+*/
+
+// das link 
+var link = Programs.loadModuleFromSource(program, './modules/hardware/atkseriallink.js')
+link.startUp()
+link.state.log = true
+
+let steps = 10
+
+// x motor
+var xm = Programs.loadModuleFromSource(program, './modules/hardware/atkstepper.js')
+xm.route.route = '0,0'
+xm.state.route = '0,0'
+xm.state.spu = steps
+xm.state.axis = 'X'
+
+// y left and right
+var ylm = Programs.loadModuleFromSource(program, './modules/hardware/atkstepper.js')
+ylm.route.route = '0,1'
+ylm.state.route = '0,1'
+ylm.state.spu = steps 
+ylm.state.axis = 'Y'
+
+var ylr = Programs.loadModuleFromSource(program, './modules/hardware/atkstepper.js')
+ylr.route.route = '0,2'
+ylr.state.route = '0,2'
+ylr.state.spu = -steps
+ylr.state.axis = 'Y'
+
+// z motor
+var zm = Programs.loadModuleFromSource(program, './modules/hardware/atkstepper.js')
+zm.route.route = '0,3'
+zm.state.route = '0,3'
+zm.state.spu = -steps
+zm.state.axis = 'Z'
+
+var planner = Programs.loadModuleFromSource(program, './modules/motion/simplanner.js')
+planner.state.minSpeed = 1
+planner.state.accel = 300
+planner.netWindow = 1
+
+/*
+
+var simplanner = Programs.loadModuelFromSource(program, './modules/motion/simplanner.js')
+
+let ahMove = {
+	axes: ['X', 'Y', 'Z'],
+	p1: [10, 10, 10],
+	p2: [20, 20, 20],
+	vector: [10, 10, 10],
+	cruise: 100,
+	entry: 10,
+	exit: 10, 
+	accel: 100
+}
+
+*/
+
+// what doth planner output ?
+/*
+var newMove = {
+    axes: axes,
+    p1: p1,
+    p2: p2,
+    cruise: move.speed,
+    entry: 0,
+    exit: 0,
+    accel: state.accel
+}
+*/
+
+// can we write something that just steps through moves one by one ? 
+
+// HOOKUP
+planner.outputs.moves.attach(xm.inputs.trapezoid)
+planner.outputs.moves.attach(ylm.inputs.trapezoid)
+planner.outputs.moves.attach(ylr.inputs.trapezoid)
+planner.outputs.moves.attach(zm.inputs.trapezoid)
+xm.outputs.ack.attach(planner.inputs.acks)
+ylm.outputs.ack.attach(planner.inputs.acks)
+zm.outputs.ack.attach(planner.inputs.acks)
+
+let moveToPlanner = {
+	position: {
+		X: 20,
+		Y: 10,
+		Z: 5
+	},
+	speed: 150
+}
+
+link.onOpen = function(){
+	// planner.inputs.instruction.fn(moveToPlanner)
+	//xm.inputs.trapezoid.fn(ahMove)
+}
+
+// ws input
+
+var sockit = Programs.loadModuleFromSource(program, './modules/pipes/websocket.js')
+var np = Programs.loadModuleFromSource(program, './modules/motion/neilparse.js')
+
+sockit.outputs.data.attach(np.inputs.array)
+np.outputs.move.attach(planner.inputs.instruction)
+planner.outputs.moveComplete.attach(np.inputs.shift)
+
+// UI HOOKUP
+
+Programs.setView(program, {
+    scale: 0.5,
+    translate: [-160, -30],
+    origin: [200, 120]
+})
+
+let top = 100
+let motorbar = 1200
+let motorspace = 400
+
+Programs.setUI(sockit, top, top)
+Programs.setUI(np, 600, top)
+
+Programs.setUI(link, 1800, top)
+Programs.setUI(xm, motorbar, top)
+Programs.setUI(ylm, motorbar, top + motorspace)
+Programs.setUI(ylr, motorbar, top + 2 * motorspace)
+Programs.setUI(zm, motorbar, top + 3 * motorspace)
+Programs.setUI(planner, 600, 450)
+
+// UI 
+const View = require('./views.js')
+View.startHttp()
+View.startWs()
+
+Programs.assignSocket(View.uiSocket)
+View.assignProgram(program)
\ No newline at end of file
diff --git a/modules/hardware/atkseriallink.js b/modules/hardware/atkseriallink.js
index 6427385b7d289f0c4ad08ca99d7934de95cc2009..49cfc2811eaaa099204c38958dec14c878be391a 100644
--- a/modules/hardware/atkseriallink.js
+++ b/modules/hardware/atkseriallink.js
@@ -94,6 +94,7 @@ function ATKSerialLink() {
                 //state.portStatus = 'opening'
                 serialport.on('open', function() {
                     state.portStatus = 'open'
+                    atkSerialLink.onOpen() 
                 })
                 serialport.on('error', function(err) {
                     state.portStatus = err.message
@@ -103,6 +104,10 @@ function ATKSerialLink() {
         }
     }
 
+    atkSerialLink.onOpen = function() {
+        // null 4 now ... 
+    }
+
     /*
     ------------------------------------------------------
     PACKETS TO HARDWARE
diff --git a/modules/hardware/atkstepper.js b/modules/hardware/atkstepper.js
index 22e86c5efe64d249a8f6482bae34651fdd215420..09636182e4f0180560ee3ee3fbdaaa5b641e5288 100644
--- a/modules/hardware/atkstepper.js
+++ b/modules/hardware/atkstepper.js
@@ -47,7 +47,7 @@ function Stepper() {
     })
 
     state.axis = 'X'
-    state.spu = 200 // steps per unit 
+    state.spu = 80 // steps per unit 
     state.rawMove = -10
 
     var ui = stepper.ui 
@@ -191,7 +191,7 @@ function Stepper() {
             console.log(dMove)
         }
 
-        if(verbose) console.log('------------------- DMOVE', state.axis, dMove.steps)
+        if(true) console.log('------------------- DMOVE', state.axis, dMove)
 
         var packet = new Array()
         // step blocks are #131
diff --git a/modules/motion/neilparse.js b/modules/motion/neilparse.js
new file mode 100644
index 0000000000000000000000000000000000000000..0e3157489b9016dead282ac09d8672e85feb4a1f
--- /dev/null
+++ b/modules/motion/neilparse.js
@@ -0,0 +1,132 @@
+// boilerplate atkapi header
+const JSUnit = require('../../src/jsunit.js')
+
+let Input = JSUnit.Input
+let Output = JSUnit.Output
+let State = JSUnit.State
+
+// unit to convert neil's mods-output arrays into human readable move objects 
+// probably do flow control here also ?
+
+function NeilParser() {
+    var neilParser = {
+        description: {
+            name: 'neilParser Parser',
+            alt: 'line of neilParser -> points'
+        }
+    }
+
+    // log more 
+    var verbose = false
+
+    let npList = null
+
+    // one caveat here is that we can't dynamically add objects to this, 
+    // or they don't get getter / settered when we do
+    neilParser.state = State()
+    var state = neilParser.state
+    state.lift = 50
+    state.moveSpeed = 200
+    state.plungeSpeed = 50
+    state.jogSpeed = 600
+    state.listLength = 0
+
+    neilParser.inputs = {
+        array: Input('array', (arr) => {
+            let list = writeMoveObjects(arr)
+            console.log('have list', list)
+            npList = list
+            state.listLength = npList.length
+            // throw it out 
+            neilParser.outputs.newList.emit(1)
+            onShift() 
+
+        }),
+        shift: Input('event', (arg) => {
+            onShift() 
+        })
+    }
+
+    neilParser.outputs = {
+        move: Output('move'),
+        newList: Output('event')
+    }
+
+    function writeMoveObjects(arr) {
+        // arr[i] are segments, 
+        // between arr[i] instances, we put a z-lift and then 
+        // a z-drop 
+
+        if (Array.isArray(arr)) {
+            let flat = new Array()
+            for (var i = 0; i < arr.length; i++) {
+                flat.push(arr[i][0])
+                flat.push('z down move')
+                flat = flat.concat(arr[i].slice(1))
+                flat.push('z up move')
+            }
+            // console.log('FLATTENED TO', flat)
+            // add header
+            flat.splice(0, 0, 'z up move')
+            // and return home 
+            flat.push([0, 0])
+            // make a list of objs 
+            let list = new Array()
+            // this is actually stateful ... jogging or not 
+            let upState = false
+            for (var j = 0; j < flat.length; j++) {
+                if (Array.isArray(flat[j])) {
+                    let move = {
+                        position: {
+                            X: flat[j][0],
+                            Y: flat[j][1]
+                        }
+                    }
+                    if (upState) {
+                        move.speed = state.jogSpeed
+                    } else {
+                        move.speed = state.moveSpeed
+                    }
+                    list.push(move)
+                } else if (flat[j] === 'z up move') {
+                    upState = true
+                    list.push({
+                        position: {
+                            Z: state.lift
+                        },
+                        speed: state.plungeSpeed
+                    })
+                } else if (flat[j] === 'z down move') {
+                    upState = false
+                    list.push({
+                        position: {
+                            Z: 0
+                        },
+                        speed: state.plungeSpeed
+                    })
+                }
+            }
+
+            return list
+
+        } else {
+            console.log('NEIL PARSE: err: not an array')
+        }
+
+    }
+
+    function onShift() {
+        if (npList != null && npList.length > 0) {
+            neilParser.outputs.move.emit(npList.shift())
+            state.listLength = npList.length
+        } else {
+            console.log('NP Completes Moves')
+        }
+    }
+
+    return neilParser
+}
+
+
+// export the module 
+module.exports = NeilParser
\ No newline at end of file
diff --git a/modules/motion/simplanner.js b/modules/motion/simplanner.js
new file mode 100644
index 0000000000000000000000000000000000000000..05cb5f8cd69edf976095ca24e4649b9c9d880d3c
--- /dev/null
+++ b/modules/motion/simplanner.js
@@ -0,0 +1,374 @@
+// boilerplate atkapi header
+const JSUnit = require('../../src/jsunit.js')
+let Input = JSUnit.Input
+let Output = JSUnit.Output
+let State = JSUnit.State
+
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI
+
+// descartes, to you 
+const DCRT = require('../../src/cartesian.js')
+const MJS = require('mathjs')
+
+// planner consumes target moves (i.e. segments having uniform speed throughout)
+// and subjects them to acceleration constraints 
+
+function Planner() {
+    var planner = {
+        description: {
+            name: 'Lookahead-Motion-Planner',
+            alt: 'movements -> acceleration planned moves'
+        }
+    }
+
+    // log more 
+    var verbose = false
+
+    planner.state = State()
+    var state = planner.state // reference pass attempt?
+
+    state.axisIDs = 'X,Y,Z'
+    state.onUiChange('axisIDs', axisIDUpdate)
+
+    state.accel = 200 // units/s/s
+    state.minSpeed = 1 // units/s
+
+    state.position = [0, 0, 0]
+
+    // should be grn / red button ... 
+    state.isRunning = 1
+    state.onUiChange('isRunning', netStateRefresh)
+
+    state.netWindow = 1
+    state.netState = [0, 0, 0]
+
+    planner.ui = UI()
+    var ui = planner.ui
+
+    ui.addElement('startStopButton', 'ui/uiButton.js')
+    ui.startStopButton.subscribe('onload', function(msg) {
+        ui.startStopButton.send({
+            calls: 'setText',
+            argument: 'start / stop planner'
+        })
+    })
+    ui.startStopButton.subscribe('onclick', onStartStop)
+
+    planner.inputs = {
+        instruction: Input('move instruction', onNewInstruction),
+        acks: Input('move acknowledgement', onAck),
+        run: Input('boolean', onRunInstruction)
+    }
+
+    planner.outputs = {
+        moves: Output('move instruction'),
+        moveComplete: Output('number')
+    }
+
+    // we'll use one of these to assert / do things 
+    // after the module is loaded, and state is copied etc
+    // i.e. one thing we can do is assert a starting value 
+    planner.init = function() {
+        state.isRunning = 0
+        state.netState = [0, 0, 0]
+    }
+
+    /*
+    ------------------------------------------------------
+    UPDATING / SETUP
+    ------------------------------------------------------
+    */
+
+    function onAck(msg) {
+        //console.log("Planner onAck:", msg)
+        // update position, net states, run netCheck
+        var axes = state.axisIDs.split(',')
+        var match = axes.indexOf(msg.axis)
+        if (match !== -1) {
+            // HERE is a hack, for our state-updating system doesn't yet accomodate arrays 
+            var newPos = state.position.slice(0)
+            newPos[match] += msg.increment
+            state.position = newPos
+            var newNetState = state.netState.slice(0)
+            newNetState[match] -= 1
+            state.netState = newNetState
+            if (verbose) console.log('NEW NET STATE', newNetState)
+        } else {
+            console.log('ERR in PLANNER: missed axis on ack from stepper')
+        }
+        netStateRefresh()
+    }
+
+    function netStateRefresh() {
+        // check if received all four, 
+        // send a packet 
+        var ns = state.netState
+        var i = 0
+        // check equality
+        while (ns[i] == ns[i + 1]) {
+            i++
+            // console.log('EQUALITY LOOP')
+            if (i > ns.length - 1) {
+                break
+            }
+        }
+        if (i == ns.length - 1) {
+            console.log('Planner confirms Move Complete')
+            planner.outputs.moveComplete.emit(1)
+        }
+    }
+
+    function onRunInstruction(boolean) {
+        if (boolean) {
+            if (state.isRunning) {
+                // already running, do nothing 
+            } else {
+                state.isRunning = 1
+                netStateRefresh()
+            }
+        } else {
+            if (state.isRunning) {
+                state.isRunning = 0
+            } else {
+                // oy 
+            }
+        }
+    }
+
+    function axisIDUpdate() {
+        var axes = state.axisIDs.split(',')
+        var position = new Array(axes.length)
+        position.fill(0)
+        var packetState = new Array(axes.length)
+        for (i in axes) {
+            position.push(0)
+            packetState.push(0)
+            // could do 
+            //planner.outputs[axes[i]] = Output('move instruction')
+        }
+        state.position = position
+        state.packetState = packetState
+        console.log(planner)
+    }
+
+    function onStartStop() {
+        if (state.isRunning) {
+            state.isRunning = 0
+        } else {
+            state.isRunning = 1
+            netStateRefresh()
+        }
+    }
+
+    function sendMoveToNetwork(move) {
+        for (i in state.netState) {
+            state.netState[i]++
+        }
+        state.netState = state.netState
+        planner.outputs.moves.emit(move)
+    }
+
+    /*
+    ------------------------------------------------------
+    ENTRY POINTS
+    ------------------------------------------------------
+    */
+
+    function onNewInstruction(move) {
+        // our axis
+        var axes = state.axisIDs.split(',')
+
+        // we'll make a new move object
+        // start and end points, and axes to track
+        var p1 = []
+        var p2 = new Array(axes.length)
+        p2.fill(0)
+        // start point is current pos ... one at a time in simplanner 
+        p1 = state.position
+        // now pick out new deltas
+        for (i in axes) {
+            var key = axes[i]
+            if (move.position[key] != null) {
+                // some new pos,
+                p2[i] = move.position[key]
+            } else {
+                // or none, this axis stays 
+                p2[i] = p1[i]
+            }
+        }
+        // check for zero-length vector 
+        if (MJS.distance(p1, p2) == 0) {
+            console.log('------------------ !ACHTUNG! -------------------')
+            console.log('------------------ !ACHTUNG! -------------------')
+            console.log('planner throwing zero length vector')
+            zlcounter++
+            console.log(zlcounter)
+            // this means we need another one from the queue
+            planner.outputs.moveComplete.emit(1)
+        } else {
+            // starting with basics
+            let mv = {
+                axes: axes,
+                p1: p1,
+                p2: p2,
+                cruise: move.speed,
+                entry: state.minSpeed,
+                exit: state.minSpeed,
+                accel: state.accel
+            }
+            // run it once 
+            runSimpleAccel(mv)
+            sendMoveToNetwork(mv)
+        }
+    }
+
+    /*
+    ------------------------------------------------------
+    JUNCTION DEVIATION 
+    walk mq to generate permissible entry / exit speeds 
+    by 'junction deviation' algorithm 
+    ------------------------------------------------------
+    */
+
+    function runSimpleAccel(move) {
+        // useful
+        var accel = state.accel
+        var ms = state.minSpeed
+        // should reference axis ids, not these moves ? 
+        var numAxis = move.p1.length
+
+        // have entry and exit speeds already because we're simplanner
+        // now that we know permissible cornering speeds,
+        // we'll calculate the trapezoid shapes
+        // this becomes very useful for turning moves over to stepper motors
+        // and will give us a time estimate for each move as well,
+        // we need / want that so that we can set a network buffer length 
+        calcTrap(move, accel, false)
+        let time = moveTime(move)
+        if (true) console.log('PLANNER: trapezoid time to', move.p2, time)
+        if (time < 0.1) {
+            console.log('------------------ !ACHTUNG! -------------------')
+            console.log('------------------ !ACHTUNG! -------------------')
+            console.log("WARN! move time here", time)
+        }
+    }
+    /*
+    ------------------------------------------------------
+    TRAPEZOIDS FROM JUNCTION DEVIATION ENTRY / EXITS
+    ------------------------------------------------------
+    */
+
+    function calcTrap(move, a, debug) {
+        // have p1, p2, cruise, entry, exit
+        // add length, figure if full-accel, full-deccel, triangle, trapezoid, cruise ...
+        move.vector = MJS.subtract(move.p2, move.p1)
+        var d = DCRT.length(move.vector)
+        var vi = move.entry
+        var v = move.cruise
+        var vf = move.exit
+        // limits
+        var maxExit = Math.sqrt(Math.pow(vi, 2) + 2 * a * d)
+        var maxEntry = Math.sqrt(Math.pow(vf, 2) + 2 * a * d)
+        // seven possible cases
+        // HERE set move with type, accel / deccel lengths, calculate time for each, and total time 
+        // then get on with writing a larger gcode window, bringing in some 'real' moves, and getting these
+        // out / back from steppers 
+        if (d <= 0) {
+            console.log('ZERO LENGTH MOVE')
+        } else if (maxExit <= vf) {
+            if (debug) console.log('TRAP: full ramp up');
+            move.type = 'ramp up'
+            // full ramp up
+            // accel, cruise, and deccel time 
+            move.t1 = (vf - vi) / a
+            move.d1 = d
+            move.t2 = 0
+            move.d2 = 0
+            move.t3 = 0
+            move.d3 = 0
+            // check we won't break
+            if (maxExit < vf) console.log('max ramp up, misses by', vf - maxExit)
+        } else if (maxEntry <= vi) {
+            if (debug) console.log('TRAP: full ramp down');
+            move.type = 'ramp down'
+            move.t1 = 0
+            move.d1 = 0
+            move.t2 = 0
+            move.d2 = 0
+            move.t3 = (vi - vf) / a
+            move.d3 = d
+            // check we're not going to break / not make
+            if (maxEntry < vi) console.log('max ramp down, misses by', vi - maxEntry)
+        } else if (vi == v && vf == v) {
+            if (debug) console.log('TRAP: full cruise');
+            move.type = 'cruise'
+            move.t1 = 0
+            move.d1 = 0
+            move.t2 = d / v
+            move.d2 = d
+            move.t3 = 0
+            move.d3 = 0
+        } else if (vi == v) {
+            if (debug) console.log('TRAP: cruise, decelerate');
+            move.type = 'cruise and deccel'
+            var deccelDistance = (Math.pow(v, 2) - Math.pow(vf, 2)) / (2 * a)
+            move.t1 = 0
+            move.d1 = 0
+            move.t2 = (d - deccelDistance) / v
+            move.d2 = d - deccelDistance
+            move.t3 = (v - vf) / a
+            move.d3 = deccelDistance
+        } else if (vf == v) {
+            if (debug) console.log('TRAP: accel, cruise');
+            move.type = 'accel and cruise'
+            var accelDistance = (Math.pow(v, 2) - Math.pow(vi, 2)) / (2 * a)
+            move.t1 = (v - vi) / a
+            move.d1 = accelDistance
+            move.t2 = (d - accelDistance) / v
+            move.d2 = d - accelDistance
+            move.t3 = 0
+            move.d3 = 0
+        } else {
+            // either full trapezoid, or a triangle 
+            // distances to / from cruise from / to start / end 
+            var accelDistance = (Math.pow(v, 2) - Math.pow(vi, 2)) / (2 * a)
+            var deccelDistance = (Math.pow(v, 2) - Math.pow(vf, 2)) / (2 * a)
+            if (accelDistance + deccelDistance < d) {
+                if (debug) console.log('TRAP: complete trapezoid');
+                move.type = 'complete trapezoid'
+                move.t1 = (v - vi) / a
+                move.d1 = accelDistance
+                move.t2 = (d - accelDistance - deccelDistance) / v
+                move.d2 = d - accelDistance - deccelDistance
+                move.t3 = (v - vf) / a
+                move.d3 = deccelDistance
+            } else {
+                if (debug) console.log('TRAP: triangular');
+                // find the peak 
+                var vPeak = Math.sqrt(((2 * a * d + Math.pow(vi, 2) + Math.pow(vf, 2)) / 2))
+                var midPoint = (Math.pow(vPeak, 2) - Math.pow(vi, 2)) / (2 * a)
+                move.type = 'triangular'
+                move.t1 = (v - vi) / a
+                move.d1 = midPoint
+                move.t2 = 0
+                move.d2 = 0
+                move.t3 = (v - vf) / a
+                move.d3 = d - midPoint
+            }
+        }
+    }
+
+    function moveTime(move) {
+        if (move.t1 != null) {
+            return move.t1 + move.t2 + move.t3
+        } else {
+            console.log('move with no time')
+        }
+    }
+
+    return planner
+}
+
+module.exports = Planner
\ No newline at end of file
diff --git a/modules/pipes/websocket.js b/modules/pipes/websocket.js
new file mode 100644
index 0000000000000000000000000000000000000000..420965b7973704e199642088838670f17e737d2b
--- /dev/null
+++ b/modules/pipes/websocket.js
@@ -0,0 +1,60 @@
+// boilerplate atkapi header
+const JSUnit = require('../../src/jsunit.js')
+
+let Input = JSUnit.Input
+let Output = JSUnit.Output
+let State = JSUnit.State
+
+// websocket, to share program representations with the client (and back)
+const ws = require('ws')
+
+function WebSocket() {
+    var webSocket = {
+        description: {
+            name: 'webSocket',
+            alt: 'webseket'
+        }
+    }
+
+    // log more 
+    var verbose = false 
+
+    let sckt = null 
+
+    // one caveat here is that we can't dynamically add objects to this, 
+    // or they don't get getter / settered when we do
+    webSocket.state = State()
+    var state = webSocket.state
+    state.address = '127.0.0.1'
+    state.port = 1234
+    state.status = 'closed'
+
+    webSocket.inputs = {
+        in: Input('any', (thing) => {
+            // some fn 
+        })
+    }
+
+    webSocket.outputs = {
+        data: Output('any')
+    }
+
+    function openSocket(){
+        const wss = new ws.Server({port: state.port})
+        wss.on('connection', (pipe) => {
+            sckt = pipe 
+            console.log('WebSocket Opened')
+            sckt.on('message', (msg) => {
+                webSocket.outputs.data.emit(JSON.parse(msg))
+            })
+        })
+    }
+
+    openSocket() 
+
+    return webSocket
+}
+
+
+// export the module 
+module.exports = WebSocket
\ No newline at end of file
diff --git a/rundmc.js b/rundmc.js
index 189ac6897a24d3c8942e73d82cab851d5b5af59b..4d75709a22de0b497dbc906118e7c49c72dec3b2 100644
--- a/rundmc.js
+++ b/rundmc.js
@@ -29,9 +29,9 @@ const Reps = require('./reps.js')
 const Programs = require('./programs.js')
 
 // the program object: real simple, just has a description, and a 'modules' 
-// var program = Programs.new('new program')
+var program = Programs.new('new program')
 
-var program = Programs.open('./programs/temp.json')
+//var program = Programs.open('./programs/temp.json')
 
 /*
 var stest = Programs.loadModuleFromSource(program, './modules/ui/stest.js')
diff --git a/src/atkunit.js b/src/atkunit.js
index 2b328d5ff14b16df3866f96a3373885ae03715d8..5a673aa9bb680f8b6548362adad058b12ac5ab61 100644
--- a/src/atkunit.js
+++ b/src/atkunit.js
@@ -39,6 +39,7 @@ function Hardware() {
             argument: 'reset hardware'
         })
     })
+    ui.resetButton.subscribe('onclick', onReset)
 
     ui.addElement('testButton', 'ui/uiButton.js')
     ui.testButton.subscribe('onload', function(msg) {
@@ -47,8 +48,10 @@ function Hardware() {
             argument: 'test network'
         })
     })
+    ui.testButton.subscribe('onclick', onNetworkTest)
 
     state.onUiChange('route', function() {
+        console.log('logging state / route change')
         hardware.route.route = state.route
     })
 
diff --git a/views.js b/views.js
index 43b447d01de379b71187c70368c5fda0366a6f56..fb211bf15932815963b1276999ba489bc173f60e 100644
--- a/views.js
+++ b/views.js
@@ -141,7 +141,7 @@ function socketSend(type, data) {
         //console.log('SEND', msg)
         sckt.send(JSON.stringify(msg))
     } else {
-        console.log('on socketSend, ws not ready')
+        // console.log('on socketSend, ws not ready')
     }
 }
 
@@ -306,7 +306,7 @@ function uiRequestUiChange(data){
 }
 
 function uiRequestMdlPositionChange(data) {
-    if(verbose) console.log('UI REQUEST ADD / CHANGE UI INFO TO MODULE', data)
+    if(true) console.log('UI REQUEST ADD / CHANGE UI INFO TO MODULE', data)
     var mod = program.modules[data.description.id]
     mod.description.position = data.description.position
 }