From ee901ad7f0b51b0aa66704f191ce5e89c597226d Mon Sep 17 00:00:00 2001 From: thehookup <38058757+thehookup@users.noreply.github.com> Date: Sun, 21 Apr 2019 00:07:20 -0400 Subject: [PATCH] Source File For Alexa Precompiled Bin --- Blinds_CONFIGURE_Portal_Alexa.ino | 315 ++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 Blinds_CONFIGURE_Portal_Alexa.ino diff --git a/Blinds_CONFIGURE_Portal_Alexa.ino b/Blinds_CONFIGURE_Portal_Alexa.ino new file mode 100644 index 0000000..229ec58 --- /dev/null +++ b/Blinds_CONFIGURE_Portal_Alexa.ino @@ -0,0 +1,315 @@ +/****************** ALEXA INTEGRATION LIBRARIES *************************************/ +#include "fauxmoESP.h" //https://bitbucket.org/xoseperez/fauxmoesp/downloads/ +#include //if you get an error here you need to install the ESP8266 board manager +/****************** WIFI MANAGER LIBRARIES *************************************/ +#include +#include +#include +#include //https://github.com/tzapu/WiFiManager +#include //https://github.com/bblanchon/ArduinoJson//this needs to be first, or it all crashes and burns... +/****************** SKETCH SPECIFIC LIBRARIES *************************************/ +#include //http://www.alhin.de/arduino/downloads/AH_EasyDriver_20120512.zip + +/****************** BASIC PACKAGE LIBRARIES *************************************/ +#include //https://github.com/thehookup/Simple-Timer-Library +#include //https://github.com/knolleary/pubsubclient +#include //if you get an error here you need to install the ESP8266 board manager +#include //if you get an error here you need to install the ESP8266 board manager +#include //ArduinoOTA is now included with the ArduinoIDE + +/***************** START USER CONFIG SECTION *********************************/ +/***************** START USER CONFIG SECTION *********************************/ +/***************** START USER CONFIG SECTION *********************************/ +/***************** START USER CONFIG SECTION *********************************/ + +//define your default values here, if there are different values in config.json, they are overwritten. +char alexa_id[20]; +char rotations[6]; +char current_position[6] = "0"; + +#define STEPPER_SPEED 35 //Defines the speed in RPM for your stepper motor +#define STEPPER_STEPS_PER_REV 1028 //Defines the number of pulses that is required for the stepper to rotate 360 degrees +#define STEPPER_MICROSTEPPING 0 //Defines microstepping 0 = no microstepping, 1 = 1/2 stepping, 2 = 1/4 stepping +#define DRIVER_INVERTED_SLEEP 1 //Defines sleep while pin high. If your motor will not rotate freely when on boot, comment this line out. + + +#define STEPPER_DIR_PIN D6 +#define STEPPER_STEP_PIN D7 +#define STEPPER_SLEEP_PIN D5 +#define STEPPER_MICROSTEP_1_PIN 14 +#define STEPPER_MICROSTEP_2_PIN 12 + +/***************** END USER CONFIG SECTION *********************************/ +/***************** END USER CONFIG SECTION *********************************/ +/***************** END USER CONFIG SECTION *********************************/ +/***************** END USER CONFIG SECTION *********************************/ +/***************** END USER CONFIG SECTION *********************************/ + +WiFiClient espClient; +PubSubClient client(espClient); +SimpleTimer timer; +AH_EasyDriver shadeStepper(STEPPER_STEPS_PER_REV, STEPPER_DIR_PIN ,STEPPER_STEP_PIN,STEPPER_MICROSTEP_1_PIN,STEPPER_MICROSTEP_2_PIN,STEPPER_SLEEP_PIN); +fauxmoESP fauxmo; + +//Global Variables +bool shouldSaveConfig = false; +bool boot = true; +int currentPosition = 0; +int newPosition = 0; +bool moving = false; +char positionPublish[50]; + +//callback notifying us of the need to save config +void saveConfigCallback () { + Serial.println("Should save config"); + shouldSaveConfig = true; +} + +void configPortal() +{ + + Serial.println("mounting FS..."); + if (SPIFFS.begin()) + { + Serial.println("mounted file system"); + if (SPIFFS.exists("/storedPosition.json")) + { + File storedFile = SPIFFS.open("/storedPosition.json", "r"); + if (storedFile) + { + Serial.println("opened config file"); + size_t size = storedFile.size(); + // Allocate a buffer to store contents of the file. + std::unique_ptr buf(new char[size]); + storedFile.readBytes(buf.get(), size); + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.parseObject(buf.get()); + json.printTo(Serial); + if (json.success()) + { + Serial.println("\nparsed json"); + strcpy(current_position, json["current_position"]); + String tempPos = String((char *)current_position); + currentPosition = tempPos.toInt(); + newPosition = tempPos.toInt(); + boot = false; + } + else + { + Serial.println("failed to load json config"); + } + } + } + if (SPIFFS.exists("/config.json")) + { + //file exists, reading and loading + Serial.println("reading config file"); + File configFile = SPIFFS.open("/config.json", "r"); + if (configFile) + { + Serial.println("opened config file"); + size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + std::unique_ptr buf(new char[size]); + configFile.readBytes(buf.get(), size); + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.parseObject(buf.get()); + json.printTo(Serial); + if (json.success()) + { + Serial.println("\nparsed json"); + strcpy(alexa_id, json["alexa_id"]); + strcpy(rotations, json["rotations"]); + } + else + { + Serial.println("failed to load json config"); + } + } + } + } + else + { + Serial.println("failed to mount FS"); + } + //end read + + + + // The extra parameters to be configured (can be either global or just in the setup) + // After connecting, parameter.getValue() will get you the configured value + // id/name placeholder/prompt default length + WiFiManagerParameter custom_alexa_id("ID", "Unique Alexa ID", alexa_id, 20); + WiFiManagerParameter custom_rotations("rotations", "Rotations (12 recommended)", rotations, 6); + + //WiFiManager + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + + //set config save notify callback + wifiManager.setSaveConfigCallback(saveConfigCallback); + + //add all your parameters here + wifiManager.addParameter(&custom_alexa_id); + wifiManager.addParameter(&custom_rotations); + + //reset settings - for testing + if(digitalRead(D1) == LOW) + { + wifiManager.resetSettings(); + } + + //set minimu quality of signal so it ignores AP's under that quality + //defaults to 8% + //wifiManager.setMinimumSignalQuality(); + + //sets timeout until configuration portal gets turned off + //useful to make it all retry or go to sleep + //in seconds + //wifiManager.setTimeout(120); + + //fetches ssid and pass and tries to connect + //if it does not connect it starts an access point with the specified name + //here "AutoConnectAP" + //and goes into a blocking loop awaiting configuration + if (!wifiManager.autoConnect("Blinds_Setup")) { + Serial.println("failed to connect and hit timeout"); + delay(3000); + //reset and try again, or maybe put it to deep sleep + ESP.reset(); + delay(5000); + } + + //if you get here you have connected to the WiFi + Serial.println("connected..."); + + //read updated parameters + strcpy(alexa_id, custom_alexa_id.getValue()); + strcpy(rotations, custom_rotations.getValue()); + + //save the custom parameters to FS + if (shouldSaveConfig) { + Serial.println("saving config"); + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + json["alexa_id"] = alexa_id; + json["rotations"] = rotations; + + File configFile = SPIFFS.open("/config.json", "w"); + if (!configFile) { + Serial.println("failed to open config file for writing"); + } + + json.printTo(Serial); + json.printTo(configFile); + configFile.close(); + //end save + } +} + +void processStepper() +{ + if (newPosition > currentPosition) + { + #if DRIVER_INVERTED_SLEEP == 1 + shadeStepper.sleepON(); + #endif + #if DRIVER_INVERTED_SLEEP == 0 + shadeStepper.sleepOFF(); + #endif + shadeStepper.move(80, FORWARD); + currentPosition++; + moving = true; + } + if (newPosition < currentPosition) + { + #if DRIVER_INVERTED_SLEEP == 1 + shadeStepper.sleepON(); + #endif + #if DRIVER_INVERTED_SLEEP == 0 + shadeStepper.sleepOFF(); + #endif + shadeStepper.move(80, BACKWARD); + currentPosition--; + moving = true; + } + if (newPosition == currentPosition && moving == true) + { + #if DRIVER_INVERTED_SLEEP == 1 + shadeStepper.sleepOFF(); + #endif + #if DRIVER_INVERTED_SLEEP == 0 + shadeStepper.sleepON(); + #endif + String temp_str = String(currentPosition); + temp_str.toCharArray(positionPublish, temp_str.length() + 1); + Serial.println("saving position"); + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + json["current_position"] = positionPublish; + + File storedFile = SPIFFS.open("/storedPosition.json", "w"); + if (!storedFile) { + Serial.println("failed to open config file for writing"); + } + json.printTo(Serial); + json.printTo(storedFile); + storedFile.close(); + + moving = false; + } + Serial.println(currentPosition); + Serial.println(newPosition); +} + +//Run once setup +void setup() { + pinMode(D1, INPUT_PULLUP); + Serial.begin(115200); + configPortal(); + shadeStepper.setMicrostepping(STEPPER_MICROSTEPPING); // 0 -> Full Step + shadeStepper.setSpeedRPM(STEPPER_SPEED); // set speed in RPM, rotations per minute + #if DRIVER_INVERTED_SLEEP == 1 + shadeStepper.sleepOFF(); + #endif + #if DRIVER_INVERTED_SLEEP == 0 + shadeStepper.sleepON(); + #endif + WiFi.mode(WIFI_STA); + ArduinoOTA.setHostname(alexa_id); + ArduinoOTA.begin(); + delay(10); + if(alexa_id != "Echo Control ID") + { + fauxmo.createServer(true); // not needed, this is the default value + fauxmo.setPort(80); // This is required for gen3 devices + fauxmo.enable(true); + fauxmo.addDevice(alexa_id); + fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) + { + if (strcmp(device_name, alexa_id)==0) + { + if(state) + { + int rots = strtoul(rotations, NULL, 10); + newPosition = map(value, 0, 255, 0, rots); + } + else + { + newPosition = 0; + } + } + }); + } + timer.setInterval(((1 << STEPPER_MICROSTEPPING)*5800)/STEPPER_SPEED, processStepper); + Serial.print("Device Name is "); + Serial.println(alexa_id); +} + +void loop() +{ + fauxmo.handle(); + ArduinoOTA.handle(); + timer.run(); +} +