Start firmware
This commit is contained in:
parent
0c59652222
commit
6071534a72
|
@ -1,90 +1,232 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESP8266WiFiMulti.h>
|
|
||||||
|
|
||||||
#include <ESP8266HTTPClient.h>
|
#include <ESP8266HTTPClient.h>
|
||||||
|
|
||||||
#define USE_SERIAL Serial
|
const char* WIFI_SSID = "Protospace";
|
||||||
|
const char* WIFI_PASS = "yycmakers";
|
||||||
|
char wifiMACAddr[18];
|
||||||
|
const String API_ROUTE = String("http://tools.protospace.ca:8080/api/lockout/");
|
||||||
|
|
||||||
ESP8266WiFiMulti WiFiMulti;
|
#define RELAY_PIN D1
|
||||||
char macAddr[18];
|
#define ON_BUTTON_PIN D3
|
||||||
|
#define OFF_BUTTON_PIN D4
|
||||||
|
#define ARMED_LED_PIN D5
|
||||||
|
#define ON_LED_PIN D6
|
||||||
|
#define OFF_LED_PIN D7
|
||||||
|
|
||||||
|
#define RELAY_CLOSED LOW
|
||||||
|
#define RELAY_OPEN !RELAY_CLOSED
|
||||||
|
#define BUTTON_CLOSED LOW
|
||||||
|
#define BUTTON_OPEN !BUTTON_CLOSED
|
||||||
|
#define LED_ON HIGH
|
||||||
|
#define LED_OFF !LED_ON
|
||||||
|
|
||||||
|
#define LOGGING true
|
||||||
|
|
||||||
|
#define DELAY_TIME 10
|
||||||
|
#define COMM_IDLE_TIME 500 / DELAY_TIME
|
||||||
|
|
||||||
// Generated with: https://arduinojson.org/assistant/
|
// Generated with: https://arduinojson.org/assistant/
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 50;
|
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 50;
|
||||||
DynamicJsonBuffer jsonBuffer(bufferSize);
|
DynamicJsonBuffer jsonBuffer(bufferSize);
|
||||||
|
|
||||||
void setup() {
|
enum wifiStates
|
||||||
|
{
|
||||||
|
WIFI_DISCONNECTED,
|
||||||
|
WIFI_CONNECTING,
|
||||||
|
WIFI_CONNECTED,
|
||||||
|
} wifiState = WIFI_DISCONNECTED;
|
||||||
|
|
||||||
pinMode(D2, OUTPUT);
|
enum lockStates
|
||||||
digitalWrite(D2, HIGH);
|
{
|
||||||
|
LOCK_OFF,
|
||||||
|
LOCK_ARMED,
|
||||||
|
LOCK_ON_PRESSED,
|
||||||
|
LOCK_ON,
|
||||||
|
LOCK_OFF_PRESSED,
|
||||||
|
} lockState = LOCK_OFF;
|
||||||
|
|
||||||
USE_SERIAL.begin(115200);
|
enum commStates
|
||||||
// USE_SERIAL.setDebugOutput(true);
|
{
|
||||||
|
COMM_INIT,
|
||||||
|
COMM_IDLE,
|
||||||
|
COMM_SEND,
|
||||||
|
} commState = COMM_INIT;
|
||||||
|
|
||||||
USE_SERIAL.println();
|
void setup()
|
||||||
USE_SERIAL.println();
|
{
|
||||||
USE_SERIAL.println();
|
if (LOGGING) Serial.begin(115200);
|
||||||
|
if (LOGGING) Serial.println("[INFO] Serial started.");
|
||||||
|
|
||||||
for(uint8_t t = 4; t > 0; t--) {
|
pinMode(RELAY_PIN, OUTPUT);
|
||||||
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
|
pinMode(ON_BUTTON_PIN, INPUT_PULLUP);
|
||||||
USE_SERIAL.flush();
|
pinMode(OFF_BUTTON_PIN, INPUT_PULLUP);
|
||||||
delay(1000);
|
pinMode(ARMED_LED_PIN, OUTPUT);
|
||||||
|
pinMode(ON_LED_PIN, OUTPUT);
|
||||||
|
pinMode(OFF_LED_PIN, OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFi.mode(WIFI_STA);
|
void loop()
|
||||||
WiFiMulti.addAP("Protospace", "yycmakers");
|
{
|
||||||
|
processWifiState();
|
||||||
|
processLockState();
|
||||||
|
processCommState();
|
||||||
|
|
||||||
|
delay(DELAY_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
void processWifiState()
|
||||||
|
{
|
||||||
|
switch(wifiState) {
|
||||||
|
case WIFI_DISCONNECTED:
|
||||||
|
lockState = LOCK_OFF;
|
||||||
|
commState = COMM_INIT;
|
||||||
|
|
||||||
|
if (LOGGING) Serial.println("[INFO] Wifi is disconnected. Attempting to connect...");
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||||
|
|
||||||
|
wifiState = WIFI_CONNECTING;
|
||||||
|
break;
|
||||||
|
case WIFI_CONNECTING:
|
||||||
|
lockState = LOCK_OFF;
|
||||||
|
commState = COMM_INIT;
|
||||||
|
|
||||||
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
|
if (LOGGING) Serial.println("[INFO] Wifi is connected.");
|
||||||
|
|
||||||
|
if (LOGGING) Serial.print("[INFO] Wifi IP Address:");
|
||||||
|
if (LOGGING) Serial.println(WiFi.localIP());
|
||||||
byte ar[6];
|
byte ar[6];
|
||||||
WiFi.macAddress(ar);
|
WiFi.macAddress(ar);
|
||||||
sprintf(macAddr, "%02X%02X%02X%02X%02X%02X", ar[0], ar[1], ar[2], ar[3], ar[4], ar[5]);
|
sprintf(wifiMACAddr, "%02X%02X%02X%02X%02X%02X", ar[0], ar[1], ar[2], ar[3], ar[4], ar[5]);
|
||||||
USE_SERIAL.println(macAddr);
|
if (LOGGING) Serial.print("[INFO] Wifi MAC Address:");
|
||||||
|
if (LOGGING) Serial.println(wifiMACAddr);
|
||||||
|
|
||||||
|
wifiState = WIFI_CONNECTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WIFI_CONNECTED:
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
|
wifiState = WIFI_DISCONNECTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (LOGGING) Serial.println("[ERROR] Invalid wifi state.");
|
||||||
|
wifiState = WIFI_DISCONNECTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void processLockState()
|
||||||
// wait for WiFi connection
|
{
|
||||||
if((WiFiMulti.run() == WL_CONNECTED)) {
|
switch (lockState) {
|
||||||
|
case LOCK_OFF:
|
||||||
|
digitalWrite(ARMED_LED_PIN, LED_OFF);
|
||||||
|
digitalWrite(ON_LED_PIN, LED_OFF);
|
||||||
|
digitalWrite(OFF_LED_PIN, LED_ON);
|
||||||
|
|
||||||
|
digitalWrite(RELAY_PIN, RELAY_OPEN);
|
||||||
|
break;
|
||||||
|
case LOCK_ARMED:
|
||||||
|
digitalWrite(ARMED_LED_PIN, LED_ON);
|
||||||
|
digitalWrite(ON_LED_PIN, LED_OFF);
|
||||||
|
digitalWrite(OFF_LED_PIN, LED_ON);
|
||||||
|
|
||||||
|
digitalWrite(RELAY_PIN, RELAY_OPEN);
|
||||||
|
|
||||||
|
if (digitalRead(OFF_BUTTON_PIN) == BUTTON_CLOSED) {
|
||||||
|
if (LOGGING) Serial.println("[INFO] Unarming interlock.");
|
||||||
|
lockState = LOCK_OFF_PRESSED;
|
||||||
|
} else if (digitalRead(ON_BUTTON_PIN) == BUTTON_CLOSED) {
|
||||||
|
if (LOGGING) Serial.println("[INFO] On button pressed.");
|
||||||
|
lockState = LOCK_ON_PRESSED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOCK_ON_PRESSED:
|
||||||
|
if (digitalRead(OFF_BUTTON_PIN) == BUTTON_CLOSED) {
|
||||||
|
if (LOGGING) Serial.println("[ERROR] Both buttons pressed, aborting.");
|
||||||
|
lockState = LOCK_OFF_PRESSED;
|
||||||
|
} else if (digitalRead(ON_BUTTON_PIN) == BUTTON_OPEN) {
|
||||||
|
if (LOGGING) Serial.println("[INFO] Turning machine on.");
|
||||||
|
lockState = LOCK_ON;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOCK_ON:
|
||||||
|
digitalWrite(ARMED_LED_PIN, LED_ON);
|
||||||
|
digitalWrite(ON_LED_PIN, LED_ON);
|
||||||
|
digitalWrite(OFF_LED_PIN, LED_OFF);
|
||||||
|
|
||||||
|
digitalWrite(RELAY_PIN, RELAY_CLOSED);
|
||||||
|
|
||||||
|
if (digitalRead(OFF_BUTTON_PIN) == BUTTON_CLOSED) {
|
||||||
|
if (LOGGING) Serial.println("[INFO] Off button pressed.");
|
||||||
|
lockState = LOCK_OFF_PRESSED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOCK_OFF_PRESSED:
|
||||||
|
if (digitalRead(OFF_BUTTON_PIN) == BUTTON_OPEN) {
|
||||||
|
if (LOGGING) Serial.println("[INFO] Turning machine off.");
|
||||||
|
lockState = LOCK_OFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (LOGGING) Serial.println("[ERROR] Invalid lock state.");
|
||||||
|
lockState = LOCK_OFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void processCommState()
|
||||||
|
{
|
||||||
|
static int commIdleCount = 0;
|
||||||
|
|
||||||
|
switch (commState) {
|
||||||
|
case COMM_INIT:
|
||||||
|
commIdleCount = 0;
|
||||||
|
commState = COMM_IDLE;
|
||||||
|
break;
|
||||||
|
case COMM_IDLE:
|
||||||
|
commIdleCount++;
|
||||||
|
if (commIdleCount >= COMM_IDLE_TIME) {
|
||||||
|
commState = COMM_SEND;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMM_SEND:
|
||||||
|
if (LOGGING) Serial.println("[INFO] HTTP begin.");
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
|
//http.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
|
||||||
|
http.begin(API_ROUTE + wifiMACAddr);
|
||||||
|
http.addHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
USE_SERIAL.print("[HTTP] begin...\n");
|
if (LOGGING) Serial.print("[INFO] HTTP POST: ");
|
||||||
// configure traged server and url
|
JsonObject& rootSerializer = jsonBuffer.createObject();
|
||||||
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
|
rootSerializer["lockState"] = lockState;
|
||||||
http.begin(String("http://172.17.32.164:3000/api/tool/") + macAddr); //HTTP
|
String postData = String();
|
||||||
|
rootSerializer.printTo(postData);
|
||||||
|
if (LOGGING) Serial.println(postData);
|
||||||
|
int httpCode = http.POST(postData);
|
||||||
|
|
||||||
USE_SERIAL.print("[HTTP] GET...\n");
|
|
||||||
// start connection and send HTTP header
|
|
||||||
int httpCode = http.GET();
|
|
||||||
|
|
||||||
// httpCode will be negative on error
|
|
||||||
if (httpCode > 0) {
|
if (httpCode > 0) {
|
||||||
// HTTP header has been send and Server response header has been handled
|
if (LOGGING) Serial.printf("[INFO] POST success, code: %d\n", httpCode);
|
||||||
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
|
|
||||||
|
|
||||||
// file found at server
|
|
||||||
if (httpCode == HTTP_CODE_OK) {
|
if (httpCode == HTTP_CODE_OK) {
|
||||||
|
if (LOGGING) Serial.print("[INFO] Resource found, parsing response: ");
|
||||||
String payload = http.getString();
|
String payload = http.getString();
|
||||||
USE_SERIAL.println(payload);
|
if (LOGGING) Serial.println(payload);
|
||||||
JsonObject& root = jsonBuffer.parseObject(payload);
|
JsonObject& rootDeserializer = jsonBuffer.parseObject(payload);
|
||||||
|
|
||||||
bool relayOn = root["relayOn"]; // true
|
bool armable = rootDeserializer["armable"];
|
||||||
bool ledOn = root["ledOn"]; // true
|
|
||||||
const char* date = root["date"]; // "2018-02-01"
|
|
||||||
|
|
||||||
USE_SERIAL.println(String("relayOn: ") + relayOn + String(" ledOn: ") + ledOn + String(" Date: ") + date);
|
|
||||||
|
|
||||||
digitalWrite(D2, !relayOn);
|
|
||||||
|
|
||||||
|
if (LOGGING) Serial.println("[INFO] Armable: " + String(armable));
|
||||||
|
} else {
|
||||||
|
if (LOGGING) Serial.println("[ERROR] Resource not found.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
if (LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
http.end();
|
commState = COMM_INIT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(10000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@ class Tool extends Component {
|
||||||
decodeStatus = status => {
|
decodeStatus = status => {
|
||||||
if (status === null) {
|
if (status === null) {
|
||||||
return { msg: 'Unknown! Connection error?', canArm: false, canDisarm: false, };
|
return { msg: 'Unknown! Connection error?', canArm: false, canDisarm: false, };
|
||||||
|
} else if (status.armable && !status.armed) {
|
||||||
|
return { msg: 'Arming...', canArm: false, canDisarm: true, };
|
||||||
|
} else if (!status.armable && status.armed) {
|
||||||
|
return { msg: 'Disarming...', canArm: true, canDisarm: false, };
|
||||||
} else if (!status.armed && !status.on) {
|
} else if (!status.armed && !status.on) {
|
||||||
return { msg: 'Off', canArm: true, canDisarm: false, };
|
return { msg: 'Off', canArm: true, canDisarm: false, };
|
||||||
} else if (status.armed && !status.on) {
|
} else if (status.armed && !status.on) {
|
||||||
|
|
|
@ -87,14 +87,14 @@ let toolStatus = lockoutData.lockouts.map(x => (
|
||||||
{
|
{
|
||||||
id: x.id,
|
id: x.id,
|
||||||
on: false,
|
on: false,
|
||||||
|
armable: false,
|
||||||
armed: false,
|
armed: false,
|
||||||
user: null,
|
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
console.log(toolStatus);
|
console.log(toolStatus);
|
||||||
|
|
||||||
const server = app.listen(8080, function () {
|
const server = app.listen(8080, () => {
|
||||||
console.log('Example app listening on port 8080!');
|
console.log('Example app listening on port 8080!');
|
||||||
});
|
});
|
||||||
const io = require('socket.io')(server);
|
const io = require('socket.io')(server);
|
||||||
|
@ -102,7 +102,7 @@ const io = require('socket.io')(server);
|
||||||
// Express http server stuff:
|
// Express http server stuff:
|
||||||
|
|
||||||
// TODO : remove on prod
|
// TODO : remove on prod
|
||||||
app.use(function(req, res, next) {
|
app.use((req, res, next) => {
|
||||||
res.header('Access-Control-Allow-Origin', '*');
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
||||||
next();
|
next();
|
||||||
|
@ -110,32 +110,34 @@ app.use(function(req, res, next) {
|
||||||
|
|
||||||
app.use('/', express.static('dist'));
|
app.use('/', express.static('dist'));
|
||||||
|
|
||||||
app.get('/api/tooldata', function (req, res) {
|
app.get('/api/tooldata', (req, res) => {
|
||||||
console.log('Request for tool data');
|
console.log('Request for tool data');
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.send(toolData);
|
res.send(toolData);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/user', function (req, res) {
|
app.get('/api/user', (req, res) => {
|
||||||
console.log('Request for user data');
|
console.log('Request for user data');
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.send(users[0]);
|
res.send(users[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/lockout/:mac', function (req, res) {
|
app.post('/api/lockout/:mac', (req, res) => {
|
||||||
const mac = req.params.mac;
|
const mac = req.params.mac;
|
||||||
|
|
||||||
const data = lockoutData.lockouts.find(x => x.mac === mac);
|
const lockout = lockoutData.lockouts.find(x => x.mac === mac);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
res.send(404);
|
res.send(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tool = toolStatus.find(x => x.id === lockout.id);
|
||||||
|
|
||||||
console.log('Request from MAC: ' + mac);
|
console.log('Request from MAC: ' + mac);
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.send(JSON.stringify(data));
|
res.send(JSON.stringify({ armable: tool.armable }));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Socket.io websocket stuff:
|
// Socket.io websocket stuff:
|
||||||
|
@ -159,11 +161,10 @@ io.on('connection', socket => {
|
||||||
const toolIndex = toolStatus.findIndex(x => x.id === toolId);
|
const toolIndex = toolStatus.findIndex(x => x.id === toolId);
|
||||||
let tool = toolStatus[toolIndex];
|
let tool = toolStatus[toolIndex];
|
||||||
|
|
||||||
if (action === 'arm' && !tool.armed && !tool.on) {
|
if (action === 'arm') {
|
||||||
tool.armed = true;
|
tool.armable = true;
|
||||||
} else if (action === 'disarm' && tool.armed) {
|
} else if (action === 'disarm') {
|
||||||
tool.armed = false;
|
tool.armable = false;
|
||||||
tool.on = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toolStatus[toolIndex] = tool;
|
toolStatus[toolIndex] = tool;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user