From 52d89d001d4ad5cfa01889a2d98bfbfa0376f88b Mon Sep 17 00:00:00 2001 From: Evan Typanski Date: Sun, 17 Feb 2019 16:44:33 -0500 Subject: [PATCH] Initial commit --- ESP8266EscapeRoom.cpp | 7 ++++ ESP8266EscapeRoom.h | 15 +++++++ ESP8266EscapeRoom.ino | 93 ++++++++++++++++++++++++++++++++++++++++++ escape-room-server.py | 94 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 ESP8266EscapeRoom.cpp create mode 100644 ESP8266EscapeRoom.h create mode 100644 ESP8266EscapeRoom.ino create mode 100644 escape-room-server.py diff --git a/ESP8266EscapeRoom.cpp b/ESP8266EscapeRoom.cpp new file mode 100644 index 0000000..0cc68b8 --- /dev/null +++ b/ESP8266EscapeRoom.cpp @@ -0,0 +1,7 @@ +#include "ESP8266EscapeRoom.h" +#include + +/*ESP8266EscapeRoom::ESP8266EscapeRoom(int rx, int tx) { + SoftwareSerial esp(7, 6); + wifi(esp); +}*/ diff --git a/ESP8266EscapeRoom.h b/ESP8266EscapeRoom.h new file mode 100644 index 0000000..3a9e444 --- /dev/null +++ b/ESP8266EscapeRoom.h @@ -0,0 +1,15 @@ +#ifndef __ESP8266EscapeRoom_H__ +#define __ESP8266EscapeRoom_H__ + +#include "Arduino.h" +#include "ESP8266.h" +#include + +class ESP8266EscapeRoom { + public: + ESP8266EscapeRoom(int rx, int tx); + + private: + ESP8266 wifi; +}; +#endif diff --git a/ESP8266EscapeRoom.ino b/ESP8266EscapeRoom.ino new file mode 100644 index 0000000..874bc79 --- /dev/null +++ b/ESP8266EscapeRoom.ino @@ -0,0 +1,93 @@ +/** + * @example TCPClientSingle.ino + * @brief The TCPClientSingle demo of library WeeESP8266. + * @author Wu Pengfei + * @date 2015.02 + * + * @par Copyright: + * Copyright (c) 2015 ITEAD Intelligent Systems Co., Ltd. \n\n + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. \n\n + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "ESP8266.h" +#include + +#define SSID "wahoo" +#define PASSWORD "" +#define HOST_NAME "172.27.108.103" +#define HOST_PORT (1337) + +SoftwareSerial esp(7, 6); +ESP8266 wifi(esp); + +void setup(void) +{ + Serial.begin(115200); + Serial.print("setup begin\r\n"); + + Serial.print("FW Version:"); + Serial.println(wifi.getVersion().c_str()); + + if (wifi.setOprToStationSoftAP()) { + Serial.print("to station + softap ok\r\n"); + } else { + Serial.print("to station + softap err\r\n"); + } + + if (wifi.joinAP(SSID, PASSWORD)) { + Serial.print("Join AP success\r\n"); + Serial.print("IP:"); + Serial.println( wifi.getLocalIP().c_str()); + } else { + Serial.print("Join AP failure\r\n"); + } + + if (wifi.disableMUX()) { + Serial.print("single ok\r\n"); + } else { + Serial.print("single err\r\n"); + } + + Serial.print("setup end\r\n"); +} + +void loop(void) +{ + uint8_t buffer[7] = {0}; + + if (wifi.createTCP(HOST_NAME, HOST_PORT)) { + Serial.print("create tcp ok\r\n"); + } else { + Serial.print("create tcp err\r\n"); + } + + char *hello = "BKS DNE"; + wifi.send((const uint8_t*)hello, strlen(hello)); + + uint32_t len = wifi.recv(buffer, sizeof(buffer), 10000); + Serial.println(len); + if (len > 0) { + Serial.print("Received:["); + for(uint32_t i = 0; i < len; i++) { + Serial.print((char)buffer[i]); + } + Serial.print("]\r\n"); + } + + if (wifi.releaseTCP()) { + Serial.print("release tcp ok\r\n"); + } else { + Serial.print("release tcp err\r\n"); + } + delay(5000); +} + diff --git a/escape-room-server.py b/escape-room-server.py new file mode 100644 index 0000000..aa233c4 --- /dev/null +++ b/escape-room-server.py @@ -0,0 +1,94 @@ +# Escape room wifi server +# Served from port 1337 +# Protocol: +# +# All requests must be 7 characters with 2x 3 letter codes +# +# Each puzzle has 3 letter code: +# Morse: MRS +# Books: BKS +# Time machine: TIM +# Gears: GRS +# +# Given 3 letter code, 3 letter code follows after a space to indicate request +# DNE: Mark puzzle as done on server and Adafruit +# GET: Get the status of puzzle +# RST: Mark puzzle as NOT done on server and Adafruit +# +# Example requests: +# MRS DNE: Change morse code status to complete +# TIM RST: Change time machine status to incomplete +# BKS GET: Get status of book puzzle +# +# Given a request, this server responds in a 7 byte code as follows: +# puzzle_code status +# Where puzzle_code is the puzzle passed in and status is DNE for done or INC for not done +# BKS DNE: Means books puzzle is done +# +# Note this means DNE commands should always return the puzzle name then DNE +# and RST commands always return puzzle name then INC +# GET commands will return the status, either DNE (done) or INC (incomplete) +# +# Invalid commands are responded to with INVALID + +import socket + +PUZZLE_FEEDS = { + "MRS": "morse_feed", + "TIM": "time_feed", + "BKS": "books_feed", + "GRS": "gears_feed" +} + +# TODO: Set puzzle status on Adafruit IO to done +def puzzle_done(puzzle): + print("done", puzzle) + return puzzle + " DNE" + +# TODO: Get puzzle status from Adafruit IO +def puzzle_get(puzzle): + print("get", puzzle) + return puzzle + " DNE" + +# TODO: Set puzzle status on Adafruit IO to incomplete +def puzzle_reset(puzzle): + print("reset", puzzle) + return puzzle + " RST" + +PORT = 1337 + +COMMAND_FUNCTIONS = { + "DNE": puzzle_done, + "GET": puzzle_get, + "RST": puzzle_reset +} + +# Setup socket +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.bind(("0.0.0.0", PORT)) + +while True: + s.listen(1) + conn, addr = s.accept() + # Connection received, process connection + # We know that nothing will be more than 16 bytes (not even more than 8 but you know) + # So why not just limit it to that? :) + data = conn.recv(16).decode() + try: + puzzle, command = data.split() + if puzzle not in PUZZLE_FEEDS or command not in COMMAND_FUNCTIONS: + print("Invalid command received:", data) + conn.send("INVALID".encode()) + conn.close() + continue + # Don't repeat yourself? Well too bad. + except ValueError: + print("Invalid command received:", data) + conn.send("INVALID".encode()) + conn.close() + continue + + response = COMMAND_FUNCTIONS[command](puzzle) + conn.send(response.encode()) + conn.close() + print("Connection processed successfully")