diff --git a/Behaviours.h b/Behaviours.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a448b84300c3dd2c1495351571b5f444f5c1019
--- /dev/null
+++ b/Behaviours.h
@@ -0,0 +1,90 @@
+#ifndef BEHAVIOUR_h
+#define BEHAVIOUR_h
+
+
+
+
+
+class Behaviour {
+protected:
+  boolean _interruptable = true;
+  boolean _temp = false;
+  boolean _priority = false;
+  boolean _running = false;
+  String _name = "name";
+
+
+public:
+  Behaviour(String name) : _name(name) {};
+  ~Behaviour() {};
+
+  //Can this behaviour be interruped
+  virtual boolean is_interruptable() { return _interruptable; };
+  //Can this behaviour be run quickly without stopping what's going on (e.g. comms, debug)
+  virtual boolean is_temp() { return _temp; };
+  //Should this behaviour override others
+  virtual boolean is_priority() {return _priority;};
+  //Is the behaviour running
+  virtual boolean is_running() {return _running;};
+  //What's the name of this behaviour
+  virtual String name() {return _name; };
+  //Start the behaviour, with arguments (don't know why this can't be virtual?)
+  virtual String start(String args) {Serial.println("Base start called <"+args+">");};
+  //Update the behaviour periodically
+  virtual void update() {};
+  //Start the behaviour, with arguments (don't know why this can't be virtual?)
+  virtual void stop() { _running = false; };
+};
+
+/*
+ * Example way to make a simple behaviour
+ */
+class TestBehaviour : public Behaviour {
+public:
+  TestBehaviour(String n) : Behaviour(n)  {}
+  String start(String args) {
+    return "Test behaviour " + _name + " with (" + args + ")";
+  }
+};
+
+
+class BehaviourTable {
+  Behaviour* behaviours[40];
+
+
+public:
+  int num = 0;
+  BehaviourTable() {
+
+  }
+  void add(Behaviour *b) {
+    behaviours[num] = b;
+
+    num++;
+  }
+
+  Behaviour* get(String n) {
+    for( int i = 0; i < num; i++ ) {
+      if( behaviours[i]->name() == n) { return behaviours[i]; }
+    }
+    return nullptr;
+  }
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/ServoBehaviours.h b/ServoBehaviours.h
new file mode 100644
index 0000000000000000000000000000000000000000..31b3fdf0b272d65f3924a2f83c0bf4be97713284
--- /dev/null
+++ b/ServoBehaviours.h
@@ -0,0 +1,61 @@
+#ifndef SERVO_BEHAVIOUR_h
+#define SERVO_BEHAVIOUR_h
+#include "Arduino.h"
+#include "Behaviours.h"
+
+#include <Servo.h>
+
+class ServoGoto : public Behaviour {
+  Servo _servo;
+
+public:
+  ServoGoto(Servo servo, String name = "goto") :  Behaviour(name), _servo(servo) {}
+  //ServoMove(Servo servo, String name) : Behaviour(name), _servo(servo) {}
+
+  String start(String args) {
+    Serial.println("Goto: '"+args+"'");
+    int val = args.toInt();
+    _servo.write(val);
+    return "";
+  }
+
+};
+
+class ServoWiggle : public Behaviour {
+  Servo _servo;
+  int _start_time = 0;
+  int _wiggle_time = 300;
+  int _num_wiggles = 5;
+  int _wiggles = 0;
+  int _wiggle_angle = 0;
+  //Calculate wiggle time by multiplying the angle by this...
+  int _wiggle_factor = 5;
+
+public:
+  ServoWiggle(Servo servo, String name, int slowness=3) : Behaviour(name), _servo(servo),_wiggle_factor(slowness) {}
+  String start(String args) {
+    _wiggle_angle = args.toInt();
+    _wiggles = 0;
+    _running = true;
+    _wiggle_time = _wiggle_factor * _wiggle_angle;
+    return "Wiggling " + String(_num_wiggles) + " times";
+  }
+
+  void update() {
+    int time_since = millis() - _start_time;
+    if( time_since > _wiggle_time ) {
+      _wiggles++;
+      _start_time = millis();
+      int angle = ( _wiggles % 2 ) ? (90+_wiggle_angle) : (90-_wiggle_angle);
+      if( _wiggles > _num_wiggles ) {
+        angle = 90;
+        _running = false;
+      }
+      Serial.println("Wiggling to: " + String(angle));
+      _servo.write(angle);
+    }
+  }
+
+};
+
+#endif
diff --git a/WallVis.cpp b/WallVis.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/WallVis.cpp
@@ -0,0 +1 @@
+
diff --git a/WallVis.h b/WallVis.h
new file mode 100644
index 0000000000000000000000000000000000000000..957b85eee3c56b7f88e7233e9a8c78e17b49b35d
--- /dev/null
+++ b/WallVis.h
@@ -0,0 +1,199 @@
+#ifndef WALLVIS_H
+#define WALLVIS_H
+#include "Arduino.h"
+#include "Behaviours.h"
+#include "ServoBehaviours.h"
+
+#include <ESP8266WiFi.h>
+#include "Adafruit_MQTT.h"
+#include "Adafruit_MQTT_Client.h"
+
+#define WLAN_SSID "WallVisNet"      //"...your SSID..."
+#define WLAN_PASS "wallvisAP"     // "...your password..."
+
+/************************* Adafruit.io Setup *********************************/
+
+/*
+#define AIO_SERVER "192.168.4.1"    //"io.adafruit.com"
+#define AIO_SERVERPORT  1883                   // use 8883 for SSL
+#define AIO_USERNAME ""   //"...your AIO username (see https://accounts.adafruit.com)..."
+#define AIO_KEY ""        //"...your AIO key..."
+*/
+
+#define MQTT_topic  "new001"
+
+void* current_wallvis;
+
+void test_callback(char *data, uint16_t len) {
+  //((WallVis*)current_wallvis)->
+  Serial.println("Got testt: ");
+  Serial.println(data);
+}
+
+class WallVis {
+  BehaviourTable _behaviours;
+  char* _ssid;
+  char* _wifi_pass;
+  char* _id;
+  char* _server;
+  int _port;
+  Behaviour* _active = nullptr;
+  int _loop_time = 5;
+  Adafruit_MQTT_Client* _mqtt;
+  Adafruit_MQTT_Subscribe* _device_subscription;
+  WiFiClient* _client;
+
+
+
+
+
+public:
+  WallVis(char* id, char* ssid="WallVisNet", char* wifi_pass="wallvisAP",
+    char* server="192.168.4.1",int port=1883) : _id(id), _server(server), _port(port), _ssid(ssid), _wifi_pass(wifi_pass) {} ;
+
+  void command_callback(char *data, uint16_t len) {
+    Serial.println("Got command: ");
+    Serial.println(data);
+  }
+
+
+
+  void init() {
+    current_wallvis = this;
+    Serial.println("Initialising");
+    Serial.println(F("Adafruit MQTT demo"));
+
+    WiFi.mode(WIFI_STA);
+
+   // Connect to WiFi access point.
+   Serial.println(); Serial.println();
+   Serial.print("Connecting to ");
+   Serial.println(_ssid);
+
+   WiFi.begin(_ssid, _wifi_pass);
+   while (WiFi.status() != WL_CONNECTED) {
+     delay(500);
+     Serial.print(".");
+   }
+   Serial.println();
+
+   Serial.println("WiFi connected");
+   Serial.println("IP address: "); Serial.println(WiFi.localIP());
+
+   _client = new WiFiClient();
+   _mqtt = new Adafruit_MQTT_Client(_client, _server, _port, "" /* mqttt username */, "" /* mqtt pass*/);
+   _device_subscription = new Adafruit_MQTT_Subscribe(_mqtt, _id);
+   _device_subscription->setCallback(test_callback);
+
+   // Setup MQTT subscription for onoff feed.
+  // mqtt.subscribe(&onoffbutton);
+   _mqtt->subscribe(_device_subscription);
+   MQTT_connect();
+
+   Serial.println("Init finished");
+
+  }
+
+
+
+  void add(Behaviour *b) {
+    _behaviours.add(b);
+  }
+
+  void vis_loop() {
+    int loop_start_time = millis();
+    serial_command();
+    //mqtt_command();
+    if( _active ) {
+      Serial.println("Updating "+_active->name());
+      _active -> update();
+      if( ! _active->is_running() ) _active = nullptr;
+    }
+    int loop_time_taken = millis()-loop_start_time;
+    if( loop_time_taken < _loop_time ) {
+      delay( _loop_time - loop_time_taken );
+    }
+  }
+
+  void serial_command() {
+    if( Serial.available() ) {
+      String cmd = Serial.readStringUntil('\n');
+      Serial.println(process(cmd));
+    }
+  }
+
+  void mqtt_command() {
+      MQTT_connect(); //ensure connection
+
+      Adafruit_MQTT_Subscribe *subscription;
+      while ((subscription = _mqtt->readSubscription(50))) {
+        if (subscription == _device_subscription) {
+          Serial.print(F("Got: "));
+          Serial.println((char *)_device_subscription->lastread);
+          Serial.println(process((char *)_device_subscription->lastread));
+        }
+      }
+  }
+
+
+
+  String process(String input) {
+    int index = input.indexOf(" ");
+    String command = "";
+    String args = "";
+
+    if( index) {
+      command = input.substring(0,index);
+      args = input.substring(index+1);
+    } else {
+      command = input;
+    }
+    return process_command(command, args);
+  }
+
+  String process_command(String command, String args) {
+    Serial.println("Processing <"+command+"> <"+args+">");
+    Behaviour* b = _behaviours.get(command);
+    if(b) {
+      if( _active ) { _active->stop(); }
+      Serial.println( "Found behaviour: <"+command+">" );
+      _active = b;
+      return( b->start(args) );
+    } else {
+      return "Couldn't process command: " + command;
+    }
+  }
+
+  // Function to connect and reconnect as necessary to the MQTT server.
+  // Should be called in the loop function and it will take care if connecting.
+  void MQTT_connect() {
+    int8_t ret;
+
+    // Stop if already connected.
+    if (_mqtt->connected()) {
+      return;
+    }
+
+    Serial.print("Connecting to MQTT... ");
+
+    uint8_t retries = 3;
+    while ((ret = _mqtt->connect()) != 0) { // connect will return 0 for connected
+         Serial.println(_mqtt->connectErrorString(ret));
+         Serial.println("Retrying MQTT connection in 5 seconds...");
+         _mqtt->disconnect();
+         delay(5000);  // wait 5 seconds
+         retries--;
+         if (retries == 0) {
+           // basically die and wait for WDT to reset me
+           while (1);
+         }
+    }
+    Serial.println("MQTT Connected!");
+  }
+
+};
+
+
+
+
+#endif
diff --git a/examples/SimpleNode/SimpleNode.ino b/examples/SimpleNode/SimpleNode.ino
new file mode 100644
index 0000000000000000000000000000000000000000..b5f25a62a069e0c6b359cac0a2ac619a474ea33a
--- /dev/null
+++ b/examples/SimpleNode/SimpleNode.ino
@@ -0,0 +1,33 @@
+#include <Servo.h>
+
+#include <WallVis.h>
+#include <Behaviours.h>
+
+WallVis vis("new001");
+
+Servo s1 = Servo();
+
+
+void setup()
+{
+  s1.attach(D3);
+  Serial.begin(115200);
+  Serial.setTimeout(100);
+  Behaviour* hello = new TestBehaviour("hello");
+  //Behaviour* goodbye = new TestBehaviour("goodbye");
+  //vis.add(hello);
+  //vis.add(goodbye);
+  vis.add(new ServoWiggle(s1, "wiggle") );
+  vis.add(new ServoWiggle(s1, "slow_wiggle", 10) );
+  vis.add(new ServoWiggle(s1, "fast_wiggle", 1) );
+  vis.add(new ServoGoto(s1) );
+  vis.init();
+  s1.write(90);
+}
+
+
+void loop()
+{
+  vis.vis_loop();
+  delay(50);
+}