@ -1 +1 @@ | |||
0.9.7 | |||
0.9.8 |
@ -1,214 +0,0 @@ | |||
/* | |||
JustWifi | |||
Wifi Manager for ESP8266 | |||
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com> | |||
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 3 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "JustWifi.h" | |||
#include <functional> | |||
bool JustWifi::connected() { | |||
return (WiFi.status() == WL_CONNECTED); | |||
} | |||
bool JustWifi::autoConnect() { | |||
unsigned long timeout; | |||
// Return if already connected | |||
if (connected()) return true; | |||
// Try to connect to last successful network | |||
if (WiFi.SSID().length() > 0) { | |||
ETS_UART_INTR_DISABLE(); | |||
wifi_station_disconnect(); | |||
ETS_UART_INTR_ENABLE(); | |||
_doCallback(MESSAGE_AUTO_CONNECTING, (char *) WiFi.SSID().c_str()); | |||
WiFi.mode(WIFI_STA); | |||
WiFi.begin(); | |||
// Check connection with timeout | |||
timeout = millis(); | |||
while (millis() - timeout < _connect_timeout) { | |||
_doCallback(MESSAGE_CONNECT_WAITING); | |||
if (WiFi.status() == WL_CONNECTED) break; | |||
delay(100); | |||
} | |||
if (WiFi.status() == WL_CONNECTED) { | |||
_mode = MODE_STATION; | |||
_doCallback(MESSAGE_CONNECTED); | |||
return true; | |||
} | |||
_doCallback(MESSAGE_AUTO_FAILED); | |||
} else { | |||
_doCallback(MESSAGE_AUTO_NOSSID); | |||
} | |||
_mode = MODE_NONE; | |||
return false; | |||
} | |||
bool JustWifi::connect() { | |||
unsigned long timeout; | |||
// Return if already connected | |||
if (connected()) return true; | |||
// Loop through configured networks | |||
for (unsigned char i=0; i<_network_count; i++) { | |||
// Skip if no SSID defined | |||
if (_network[i].ssid.length() == 0) continue; | |||
// TODO: Static IP options here | |||
// Connect | |||
_doCallback(MESSAGE_CONNECTING, (char *) _network[i].ssid.c_str()); | |||
WiFi.begin(_network[i].ssid.c_str(), _network[i].pass.c_str()); | |||
// Check connection with timeout | |||
timeout = millis(); | |||
while (millis() - timeout < _connect_timeout) { | |||
_doCallback(MESSAGE_CONNECT_WAITING); | |||
if (WiFi.status() == WL_CONNECTED) break; | |||
delay(100); | |||
} | |||
// Get out of the i loop if connected | |||
if (WiFi.status() == WL_CONNECTED) { | |||
break; | |||
} else { | |||
_mode = MODE_NONE; | |||
_doCallback(MESSAGE_CONNECT_FAILED, (char *) _network[i].ssid.c_str()); | |||
} | |||
} | |||
if (WiFi.status() == WL_CONNECTED) { | |||
//WiFi.setAutoConnect(true); | |||
//WiFi.setAutoReconnect(true); | |||
_mode = MODE_STATION; | |||
_doCallback(MESSAGE_CONNECTED); | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool JustWifi::startAP(char * ssid, char * pass) { | |||
// Return if already connected | |||
// if (connected()) return true; | |||
// TODO: Static IP options here | |||
_doCallback(MESSAGE_ACCESSPOINT_CREATING); | |||
WiFi.mode(WIFI_AP); | |||
if (strlen(pass) > 0) { | |||
if (strlen(pass) < 8 || strlen(pass) > 63) { | |||
_mode = MODE_NONE; | |||
_doCallback(MESSAGE_ACCESSPOINT_FAILED); | |||
return false; | |||
} | |||
WiFi.softAP(ssid, pass); | |||
} else { | |||
WiFi.softAP(ssid); | |||
} | |||
// TODO: Setup the DNS server redirecting all the queries to this IP | |||
_ssid = String(ssid); | |||
_mode = MODE_ACCESS_POINT; | |||
_doCallback(MESSAGE_ACCESSPOINT_CREATED); | |||
return true; | |||
} | |||
bool JustWifi::disconnect() { | |||
WiFi.disconnect(true); | |||
_mode = MODE_NONE; | |||
_doCallback(MESSAGE_DISCONNECTED); | |||
} | |||
bool JustWifi::cleanNetworks() { | |||
_network_count = 0; | |||
} | |||
bool JustWifi::addNetwork(char * ssid, char * pass) { | |||
if (_network_count == MAX_NETWORKS) return false; | |||
_network[_network_count].ssid = String(ssid); | |||
_network[_network_count].pass = String(pass); | |||
_network_count++; | |||
return true; | |||
} | |||
justwifi_mode_t JustWifi::getMode() { | |||
return _mode; | |||
} | |||
String JustWifi::getIP() { | |||
if (_mode == MODE_STATION) { | |||
return WiFi.localIP().toString(); | |||
} else if (_mode == MODE_ACCESS_POINT) { | |||
return WiFi.softAPIP().toString(); | |||
} | |||
return String(""); | |||
} | |||
String JustWifi::getNetwork() { | |||
if (_mode == MODE_STATION) { | |||
return WiFi.SSID(); | |||
} | |||
return _ssid; | |||
} | |||
void JustWifi::setConnectTimeout(unsigned long ms) { | |||
_connect_timeout = ms; | |||
} | |||
void JustWifi::onMessage(TMessageFunction fn) { | |||
_callback = fn; | |||
} | |||
void JustWifi::loop() { | |||
if ((WiFi.status() != WL_CONNECTED) && (_mode == MODE_STATION)) { | |||
_mode = MODE_NONE; | |||
_doCallback(MESSAGE_DISCONNECTED); | |||
} | |||
if ((WiFi.status() == WL_CONNECTED) && (_mode != MODE_STATION)) { | |||
_mode = MODE_STATION; | |||
_doCallback(MESSAGE_CONNECTED); | |||
} | |||
} | |||
void JustWifi::_doCallback(justwifi_messages_t message, char * parameter) { | |||
if (_callback != NULL) _callback(message, parameter); | |||
} |
@ -1,99 +0,0 @@ | |||
/* | |||
JustWifi | |||
Wifi Manager for ESP8266 | |||
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com> | |||
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 3 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef JustWifi_h | |||
#define JustWifi_h | |||
#include <functional> | |||
#include <ESP8266WiFi.h> | |||
extern "C" { | |||
#include "user_interface.h" | |||
} | |||
#define MAX_NETWORKS 3 | |||
#define WIFI_CONNECT_TIMEOUT 10000 | |||
struct network_t { | |||
String ssid; | |||
String pass; | |||
}; | |||
typedef enum { | |||
MODE_NONE, | |||
MODE_STATION, | |||
MODE_ACCESS_POINT | |||
} justwifi_mode_t; | |||
typedef enum { | |||
MESSAGE_AUTO_NOSSID, | |||
MESSAGE_AUTO_CONNECTING, | |||
MESSAGE_AUTO_FAILED, | |||
MESSAGE_CONNECTING, | |||
MESSAGE_CONNECT_WAITING, | |||
MESSAGE_CONNECT_FAILED, | |||
MESSAGE_CONNECTED, | |||
MESSAGE_ACCESSPOINT_CREATING, | |||
MESSAGE_ACCESSPOINT_FAILED, | |||
MESSAGE_ACCESSPOINT_CREATED, | |||
MESSAGE_DISCONNECTED | |||
} justwifi_messages_t; | |||
class JustWifi { | |||
public: | |||
typedef std::function<void(justwifi_messages_t, char *)> TMessageFunction; | |||
bool autoConnect(); | |||
bool connect(); | |||
bool startAP(char * ssid, char * pass); | |||
bool disconnect(); | |||
bool connected(); | |||
bool cleanNetworks(); | |||
bool addNetwork(char * ssid, char * pass); | |||
void setConnectTimeout(unsigned long ms); | |||
justwifi_mode_t getMode(); | |||
String getIP(); | |||
String getNetwork(); | |||
void onMessage(TMessageFunction fn); | |||
void loop(); | |||
private: | |||
network_t _network[MAX_NETWORKS]; | |||
String _ssid; | |||
justwifi_mode_t _mode = MODE_NONE; | |||
unsigned char _network_count = 0; | |||
unsigned long _connect_timeout = WIFI_CONNECT_TIMEOUT; | |||
TMessageFunction _callback = NULL; | |||
void _doCallback(justwifi_messages_t message, char * parameter = NULL); | |||
}; | |||
#endif |
@ -0,0 +1 @@ | |||
src |
@ -0,0 +1,28 @@ | |||
#!/bin/python | |||
import subprocess | |||
import socket | |||
from SCons.Script import DefaultEnvironment | |||
env = DefaultEnvironment() | |||
def is_valid_ip(ip): | |||
try: | |||
socket.inet_aton(ip) | |||
return True | |||
except socket.error: | |||
return False | |||
def before_build_spiffs(source, target, env): | |||
env.Execute("gulp buildfs2") | |||
def before_upload(source, target, env): | |||
upload_port = env.get('UPLOAD_PORT', False) | |||
if upload_port and upload_port[0] == '/': | |||
cmd = ["mosquitto_sub", "-t", upload_port, "-h", "192.168.1.10", "-N", "-C", "1"] | |||
ip = subprocess.check_output(cmd) | |||
if is_valid_ip(ip): | |||
env['UPLOAD_PORT'] = '"' + ip + '"' | |||
#env.AddPreAction("uploadfs", before_upload) | |||
#env.AddPreAction("upload", before_upload) | |||
env.AddPreAction(".pioenvs/%s/spiffs.bin" % env['PIOENV'], before_build_spiffs) |
@ -1,111 +1,66 @@ | |||
[env:sonoff-debug] | |||
platform = espressif | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SONOFF -D DEBUG | |||
[platformio] | |||
env_default = node-debug | |||
[env:sonoff-debug-ota] | |||
platform = espressif | |||
[common] | |||
platform = espressif8266 | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SONOFF -D DEBUG | |||
lib_install = 19,44,64,89,549,727 | |||
extra_script = pio_hooks.py | |||
[ota] | |||
upload_speed = 115200 | |||
upload_port = "192.168.4.1" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
[env:sonoff-debug] | |||
include = common | |||
board = esp01_1m | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF | |||
[env:sonoff-debug-ota] | |||
include = env:sonoff-debug,ota | |||
[env:slampher-debug] | |||
platform = espressif | |||
framework = arduino | |||
include = common | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SLAMPHER -D DEBUG | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSLAMPHER | |||
[env:slampher-debug-ota] | |||
platform = espressif | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SLAMPHER -D DEBUG | |||
upload_speed = 115200 | |||
upload_port = "192.168.4.1" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
include = env:slampher-debug,ota | |||
[env:s20-debug] | |||
platform = espressif | |||
framework = arduino | |||
include = common | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D S20 -D DEBUG | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DS20 | |||
[env:s20-debug-ota] | |||
platform = espressif | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D S20 -D DEBUG | |||
upload_speed = 115200 | |||
upload_port = "192.168.4.1" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
include = env:s20-debug,ota | |||
[env:node-debug] | |||
platform = espressif | |||
framework = arduino | |||
include = common | |||
board = nodemcuv2 | |||
lib_install = 89,64,19 | |||
build_flags = -D NODEMCUV2 -D DEBUG | |||
build_flags = -DNODEMCUV2 -DDEBUG_PORT=Serial | |||
[env:node-debug-ota] | |||
platform = espressif | |||
framework = arduino | |||
board = nodemcuv2 | |||
lib_install = 89,64,19 | |||
build_flags = -D NODEMCUV2 -D DEBUG | |||
upload_speed = 115200 | |||
upload_port = "192.168.4.1" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
include = env:node-debug,ota | |||
[env:ac-device] | |||
topic = /home/cellar/airconditioner/ip | |||
include = env:s20-debug-ota | |||
[env:washer-device] | |||
platform = espressif | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
topic = /home/cellar/washer/ip | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SONOFF -D DEBUG -D ENABLE_EMON -D ENABLE_DHT | |||
upload_speed = 115200 | |||
upload_port = "192.168.1.114" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
include = env:sonoff-debug-ota | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld -DDEBUG_PORT=Serial -DSONOFF -DENABLE_EMON=1 -DENABLE_DHT=1 | |||
[env:studio-lamp-device] | |||
platform = espressif | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
topic = /home/studio/lamp/ip | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SONOFF -D DEBUG | |||
upload_speed = 115200 | |||
upload_port = "192.168.1.114" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
include = env:sonoff-debug-ota | |||
[env:living-lamp-device] | |||
platform = espressif | |||
framework = arduino | |||
board = esp01_1m | |||
lib_install = 89,64,19 | |||
topic = /home/living/lamp/ip | |||
build_flags = -Wl,-Tesp8266.flash.1m256.ld | |||
build_flags = -D SONOFF -D DEBUG -D RF | |||
upload_speed = 115200 | |||
upload_port = "192.168.1.114" | |||
upload_flags = --auth=fibonacci --port 8266 | |||
include = env:sonoff-debug-ota |
@ -0,0 +1,5 @@ | |||
#ifdef DEBUG_PORT | |||
#define DEBUG_MSG(...) DEBUG_PORT.printf( __VA_ARGS__ ) | |||
#else | |||
#define DEBUG_MSG(...) | |||
#endif |
@ -0,0 +1,44 @@ | |||
/* | |||
RENTALITO | |||
NTP MODULE | |||
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#include <TimeLib.h> | |||
#include <NtpClientLib.h> | |||
#include <WiFiClient.h> | |||
// ----------------------------------------------------------------------------- | |||
// NTP | |||
// ----------------------------------------------------------------------------- | |||
void ntpConnect(WiFiEventStationModeGotIP ipInfo) { | |||
NTP.begin(NTP_SERVER, NTP_TIME_OFFSET, NTP_DAY_LIGHT); | |||
NTP.setInterval(NTP_UPDATE_INTERVAL); | |||
} | |||
void ntpSetup() { | |||
NTP.onNTPSyncEvent([](NTPSyncEvent_t error) { | |||
if (error) { | |||
if (error == noResponse) { | |||
DEBUG_MSG("[NTP] Error: NTP server not reachable\n"); | |||
} else if (error == invalidAddress) { | |||
DEBUG_MSG("[NTP] Error: Invalid NTP server address\n"); | |||
} | |||
} else { | |||
DEBUG_MSG("[NTP] Time: %s\n", (char *) NTP.getTimeDateString(NTP.getLastNTPSync()).c_str()); | |||
} | |||
}); | |||
static WiFiEventHandler e; | |||
e = WiFi.onStationModeGotIP(ntpConnect); | |||
} | |||
void ntpLoop() { | |||
now(); | |||
} |
@ -1,4 +1,4 @@ | |||
#define APP_NAME "Espurna" | |||
#define APP_VERSION "0.9.7" | |||
#define APP_VERSION "0.9.8" | |||
#define APP_AUTHOR "xose.perez@gmail.com" | |||
#define APP_WEBSITE "http://tinkerman.cat" |
@ -0,0 +1,107 @@ | |||
/* | |||
RENTALITO | |||
WEBSERVER MODULE | |||
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com> | |||
*/ | |||
#include <WebSocketsServer.h> | |||
#include <Hash.h> | |||
#include <ArduinoJson.h> | |||
WebSocketsServer webSocket = WebSocketsServer(81); | |||
// ----------------------------------------------------------------------------- | |||
// WEBSOCKETS | |||
// ----------------------------------------------------------------------------- | |||
bool webSocketSend(char * payload) { | |||
//DEBUG_MSG("[WEBSOCKET] Broadcasting '%s'\n", payload); | |||
webSocket.broadcastTXT(payload); | |||
} | |||
bool webSocketSend(uint8_t num, char * payload) { | |||
//DEBUG_MSG("[WEBSOCKET] Sending '%s' to #%d\n", payload, num); | |||
webSocket.sendTXT(num, payload); | |||
} | |||
void webSocketStart(uint8_t num) { | |||
char buffer[64]; | |||
sprintf(buffer, "%s %s", APP_NAME, APP_VERSION); | |||
DynamicJsonBuffer jsonBuffer; | |||
JsonObject& root = jsonBuffer.createObject(); | |||
root["app"] = buffer; | |||
root["manufacturer"] = String(MANUFACTURER); | |||
root["device"] = String(DEVICE); | |||
root["hostname"] = getSetting("hostname", HOSTNAME); | |||
root["network"] = getNetwork(); | |||
root["ip"] = getIP(); | |||
root["mqttStatus"] = mqttConnected() ? "1" : "0"; | |||
root["mqttServer"] = getSetting("mqttServer", MQTT_SERVER); | |||
root["mqttPort"] = getSetting("mqttPort", String(MQTT_PORT)); | |||
root["mqttUser"] = getSetting("mqttUser"); | |||
root["mqttPassword"] = getSetting("mqttPassword"); | |||
root["mqttTopic"] = getSetting("mqttTopic", MQTT_TOPIC); | |||
root["relayStatus"] = digitalRead(RELAY_PIN) == HIGH; | |||
#if ENABLE_RF | |||
root["rfChannel"] = getSetting("rfChannel", String(RF_CHANNEL)); | |||
root["rfDevice"] = getSetting("rfDevice", String(RF_DEVICE)); | |||
#endif | |||
#if ENABLE_EMON | |||
root["pwMainsVoltage"] = getSetting("pwMainsVoltage", String(EMON_MAINS_VOLTAGE)); | |||
root["pwCurrentRatio"] = getSetting("pwCurrentRatio", String(EMON_CURRENT_RATIO)); | |||
#endif | |||
JsonArray& wifi = root.createNestedArray("wifi"); | |||
for (byte i=0; i<3; i++) { | |||
JsonObject& network = wifi.createNestedObject(); | |||
network["ssid"] = getSetting("ssid" + String(i)); | |||
network["pass"] = getSetting("pass" + String(i)); | |||
} | |||
String output; | |||
root.printTo(output); | |||
webSocket.sendTXT(num, (char *) output.c_str()); | |||
} | |||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { | |||
switch(type) { | |||
case WStype_DISCONNECTED: | |||
DEBUG_MSG("[WEBSOCKET] #%u disconnected\n", num); | |||
break; | |||
case WStype_CONNECTED: | |||
#if DEBUG_PORT | |||
{ | |||
IPAddress ip = webSocket.remoteIP(num); | |||
DEBUG_MSG("[WEBSOCKET] #%u connected, ip: %d.%d.%d.%d, url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); | |||
} | |||
#endif | |||
webSocketStart(num); | |||
break; | |||
case WStype_TEXT: | |||
DEBUG_MSG("[WEBSOCKET] #%u sent: %s\n", num, payload); | |||
break; | |||
case WStype_BIN: | |||
DEBUG_MSG("[WEBSOCKET] #%u sent binary length: %u\n", num, length); | |||
break; | |||
} | |||
} | |||
void webSocketSetup() { | |||
webSocket.begin(); | |||
webSocket.onEvent(webSocketEvent); | |||
} | |||
void webSocketLoop() { | |||
webSocket.loop(); | |||
} |