Skip to content
Snippets Groups Projects
WallVis.h 4.92 KiB
Newer Older
Dave Murray-Rust's avatar
Dave Murray-Rust committed
#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