Initial commit
This commit is contained in:
parent
a178ff5987
commit
649b9e0729
|
@ -0,0 +1,5 @@
|
|||
build
|
||||
deps
|
||||
*.tmp
|
||||
*.bak
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/../modules/mongoose-os/fw/include",
|
||||
"${workspaceRoot}/../modules/mongoose-os/common",
|
||||
"${workspaceRoot}/../modules/mjs"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"macFrameworkPath": []
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": 3
|
||||
}
|
15
README.md
15
README.md
|
@ -1,12 +1,19 @@
|
|||
# Setup WiFi via Web UI
|
||||
# SonOff module based on Mongoose-OS and using MQTT to integrate to some home automation
|
||||
# Setup via Web and in AP-mode
|
||||
|
||||
## Overview
|
||||
|
||||
- Do not configure WiFi - leave the module in AP (Access Point mode).
|
||||
- Mongoose OS starts a WiFi network called `Mongoose_XXXXXX` with password
|
||||
`Mongoose`. Switch your workstation to that WiFi network
|
||||
- Mongoose OS starts a WiFi network called `SONOFF_XXXXXX` with password
|
||||
- if STA is configured and gets access, the AP is disabled ~120 seconds after boot
|
||||
`Sonoff`. Switch your workstation to that WiFi network
|
||||
- Point your browser to http://192.168.4.1
|
||||
- You'll see a simple form to configure WiFi network & password
|
||||
- You'll see a simple form to configure WiFi network & password and some sonoff parameters
|
||||
- Integration into your home automation system based on MQTT, please configure
|
||||
- MQTT host
|
||||
- MQTT port
|
||||
- MQTT topic to send current switch status changes (published)
|
||||
- MQTT topic to subscribe to receive commands
|
||||
|
||||
![Screenshot](shot.png)
|
||||
|
||||
|
|
106
fs/index.html
106
fs/index.html
|
@ -15,51 +15,32 @@
|
|||
min-height: 7em; white-space: pre; padding: 0.5em; overflow: auto;
|
||||
}
|
||||
</style>
|
||||
<script src="zepto.min.js"></script>
|
||||
<script src="s_zepto.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="nav" tabindex="-1" onclick="this.focus()">
|
||||
<div class="container">
|
||||
<a class="pagename current" href="https://mongoose-os.com">Mongoose OS app</a>
|
||||
<a class="pagename current" href="https://mongoose-os.com">SONOFF / Mongoose</a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<div class="hero">
|
||||
<h1>WiFi setup via Web UI</h1>
|
||||
<p>This <a href="https://mongoose-os.com">Mongoose OS</a> app shows
|
||||
how to start a device in Access Point mode (AP) and configure Station mode
|
||||
via simple Web UI.</p>
|
||||
<p>This page communicates with the device via
|
||||
<a href="https://mongoose-os.com/docs/#/rpc/">Mongoose OS RPC mechanism</a>
|
||||
using HTTP/RESTful as a transport protocol. A small JavaScript library,
|
||||
<h1>WiFi setup</h1>
|
||||
<p>Configure your SONOFF device to communicate with your home automation without having this device
|
||||
connect to some unknown servers on the internet. We want you to keep you under control of your
|
||||
home!
|
||||
</p>
|
||||
<p>This product is based on the Sonoff devices sold by <a href="https://itead.cc">iTead</a>.
|
||||
The firmware has been replaced by a software based on <a href="https://mongoose-os.com">Mongoose OS</a>.
|
||||
This setup is developed by <a href="mailto:dirk.jahnke@mailbox.org">Dirk Jahnke</a> and can be found
|
||||
in a private gitea repository at <a href="https://gitea.pmpark.de/dirk/mg_sonoff.git">https://gitea.pmpark.de/dirk/mg_sonoff.git</a>.
|
||||
A small JavaScript library,
|
||||
<a href="http://zeptojs.com/">zepto</a>, is used as a drop-in replacement
|
||||
for jQuery, for making AJAX calls to the device.
|
||||
</p>
|
||||
|
||||
<p>Open <code>fs/index.html</code>, or right-click on this page and
|
||||
choose "view source".</p>
|
||||
|
||||
<p>
|
||||
First, this web page makes a call to the
|
||||
<code>http://DEVICE_IP/rpc/Config.Get</code> RESTful endpoint, which
|
||||
triggers <code>Config.Get</code> RPC service and returns a large JSON
|
||||
object (click <a target="_blank" href="/rpc/Config.Get">here</a> to see) with full device configuration. From that object, we take
|
||||
WiFi SSID and password, and stick them into the text inputs.
|
||||
</p>
|
||||
|
||||
<p>Second, we install a button click handler, which grabs values from the
|
||||
text inputs, creates a JSON string with the device configuration subtree
|
||||
that <code>Config.Set</code> RPC call expects,
|
||||
and calls a <code>/rpc/Config.Set</code> endpoint.
|
||||
</p>
|
||||
|
||||
<p>Similarly, you can call any other RPC service that device has. Call
|
||||
<code>RPC.List</code> to get a list of all RPC services available.
|
||||
</p>
|
||||
</div>
|
||||
<div class="row form">
|
||||
|
||||
<div class="col c4">
|
||||
<div class="form-control">
|
||||
<label for="ssid">WiFi Network:</label>
|
||||
|
@ -69,15 +50,53 @@
|
|||
<label for="pass">WiFi Password:</label>
|
||||
<input type="text" class="smooth" id="pass" name="pass" placeholder="Type WiFi password...">
|
||||
</div>
|
||||
<div class="form-control"><button href="#" class="btn btn-sm btn-c" id="save">Save WiFi settings</button></div>
|
||||
<div class="form-control"><button href="#" class="btn btn-sm btn-c" id="saveWifi">Save WiFi settings & reboot</button></div>
|
||||
</div>
|
||||
|
||||
<div class="col c8">
|
||||
<!-- <h3>Result:</h3> -->
|
||||
<div id="result"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row form">
|
||||
<div class="col c4">
|
||||
<div class="form-control">
|
||||
<label for="mqttHost">MQTT Host:</label>
|
||||
<input type="text" class="smooth" id="mqttHost" name="mqttHost" placeholder="Host name or IP with port ...">
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label for="mqttPass">MQTT Password:</label>
|
||||
<input type="text" class="smooth" id="mqttPass" name="mqttPass" placeholder="Type password ...">
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label for="mqttClientId">MQTT Client ID:</label>
|
||||
<input type="text" class="smooth" id="mqttClientId" name="mqttClientId" placeholder="Id of this device as a client at MQTT server ...">
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label for="pubTopic">Publication Topic:</label>
|
||||
<input type="text" class="smooth" id="mqttPubTopic" name="mqttPubTopic" placeholder="Topic name to publish status changes ...">
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label for="subTopic">Subscription Topic:</label>
|
||||
<input type="text" class="smooth" id="mqttSubTopic" name="mqttSubTopic" placeholder="Topic name to receive commands ...">
|
||||
</div>
|
||||
<div class="form-control"><button href="#" class="btn btn-sm btn-c" id="saveSonoff">Save device settings & reboot</button></div>
|
||||
</div>
|
||||
|
||||
<div class="col c4">
|
||||
<div id="more"></div>
|
||||
</div>
|
||||
|
||||
<div class="col c4">
|
||||
<h3>Device Info</h3>
|
||||
<div class="form-control">
|
||||
<label for="deviceID">Device ID:</label>
|
||||
<input type="text" class="smooth" id="mqttPubTopic" name="mqttPubTopic" readonly="readonly">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
@ -92,10 +111,16 @@
|
|||
log('Result: ' + JSON.stringify(data));
|
||||
$('#ssid').val(data.wifi.sta.ssid);
|
||||
$('#pass').val(data.wifi.sta.pass);
|
||||
$('#deviceID').val(data.device.id);
|
||||
$('#mqttHost').val(data.mqtt.server);
|
||||
$('#mqttPass').val(data.mqtt.pass);
|
||||
$('#mqttClientId').val(data.mqtt.client_id);
|
||||
$('#pubTopic').val(data.sonoff.switch_status_pub_topic);
|
||||
$('#subTopic').val(data.sonoff.command_sub_topic);
|
||||
},
|
||||
});
|
||||
|
||||
$('#save').on('click', function() {
|
||||
$('#saveWifi').on('click', function() {
|
||||
log('Calling /rpc/Config.Set ...');
|
||||
$.ajax({
|
||||
url: '/rpc/Config.Set',
|
||||
|
@ -109,6 +134,19 @@
|
|||
})
|
||||
});
|
||||
|
||||
$('#saveSonoff').on('click', function() {
|
||||
log('Calling /rpc/Config.Set ...');
|
||||
$.ajax({
|
||||
url: '/rpc/Config.Set',
|
||||
data: JSON.stringify({config: {mqtt: {enable: true, server: $('#mqttHost').val(), client_id: $('#mqttClientId').val()}, pass: $('#mqttPass').val()},sonoff: {switch_status_pub_topic: $('#pubTopic').val(), command_sub_topic: $('#subTopic').val()}}),
|
||||
type: 'POST',
|
||||
// contentType: 'application/json',
|
||||
success: function(data) {
|
||||
log('Success. Saving and rebooting ...');
|
||||
$.ajax({url: '/rpc/Config.Save', type: 'POST', data: JSON.stringify({"reboot": true})});
|
||||
},
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
39
mos.yml
39
mos.yml
|
@ -1,21 +1,54 @@
|
|||
author: mongoose-os
|
||||
description: Setup WiFi via Web UI
|
||||
name: mg_sonoff
|
||||
author: Dirk Jahnke
|
||||
description: Control sonoff devices without having them communicate to their internet servers. Instead integrate them into you own home automation based on MQTT or RPC.
|
||||
version: 1.0
|
||||
|
||||
libs_version: ${mos.version}
|
||||
modules_version: ${mos.version}
|
||||
mongoose_os_version: ${mos.version}
|
||||
|
||||
platforms: [esp8266]
|
||||
|
||||
arch: esp8266
|
||||
|
||||
filesystem:
|
||||
- fs
|
||||
|
||||
libs:
|
||||
- origin: https://github.com/mongoose-os-libs/ca-bundle
|
||||
- origin: https://github.com/mongoose-os-libs/i2c
|
||||
- origin: https://github.com/mongoose-os-libs/http-server
|
||||
- origin: https://github.com/mongoose-os-libs/ota-http-server
|
||||
- origin: https://github.com/mongoose-os-libs/mqtt
|
||||
- origin: https://github.com/mongoose-os-libs/rpc-service-config
|
||||
- origin: https://github.com/mongoose-os-libs/rpc-service-fs
|
||||
- origin: https://github.com/mongoose-os-libs/rpc-uart
|
||||
# - origin: https://github.com/mongoose-os-libs/rpc-uart
|
||||
- origin: https://github.com/mongoose-os-libs/rpc-mqtt
|
||||
- origin: https://github.com/mongoose-os-libs/wifi
|
||||
# - origin: https://github.com/mongoose-os-libs/mjs
|
||||
|
||||
|
||||
cdefs:
|
||||
MGOS_ENABLE_WEB_CONFIG: 1
|
||||
MGOS_ENABLE_FILE_UPLOAD: 1
|
||||
MGOS_ENABLE_TUNNEL: 0
|
||||
|
||||
config_schema:
|
||||
- ["http.enable", true]
|
||||
# - ["http.document_root", "/"]
|
||||
# - ["http.hidden_files", "s_*"]
|
||||
# - ["http.auth_file", "s_pass"]
|
||||
- ["wifi.ap.enable", true]
|
||||
- ["wifi.ap.ssid", "SONOFF_??????"]
|
||||
- ["wifi.ap.pass", "MySonoff"]
|
||||
# - ["wifi.sta.enable", false]
|
||||
- ["sonoff", "o", {title: "Sonoff specific parameters"}]
|
||||
- ["sonoff.switch_status_pub_topic", "s", "sonoff/??????/switch", {title: "Topic to publish switch status, ?????? is the device ID of this device"}]
|
||||
- ["sonoff.command_sub_topic", "s", "sonoff/??????/command", {title: "Topic to subscribe to receive commands for this device"}]
|
||||
|
||||
build_vars:
|
||||
# sonoff basic has 1MBytes flash only
|
||||
FLASH_SIZE: 1048576
|
||||
|
||||
tags:
|
||||
- c
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// Author: Dirk Jahnke
|
||||
// January 24, 2018
|
||||
//
|
||||
// Manage on board LED of SONOFF device
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mgos.h"
|
||||
#include "mgos_gpio.h"
|
||||
#include "mgos_sys_config.h"
|
||||
#include "mgos_timers.h"
|
||||
|
||||
#include "ledHandler.h"
|
||||
|
||||
static int ON_BOARD_LED = 13; /* sonoff basic LED pin */
|
||||
|
||||
static LEDStatus currentStatus = LED_OFF;
|
||||
static int numTicksLedHasThisState = 0;
|
||||
|
||||
void set_led_status(LEDStatus newStatus) {
|
||||
numTicksLedHasThisState = 0;
|
||||
currentStatus = newStatus;
|
||||
LOG(LL_DEBUG, ("set_led_status to %d", newStatus));
|
||||
}
|
||||
|
||||
static uint8_t led_timer_ticks = 0; /* for led blinker use */
|
||||
|
||||
static void blink_on_board_led_cb(void *arg) {
|
||||
switch (currentStatus) {
|
||||
case LED_OFF:
|
||||
mgos_gpio_write(ON_BOARD_LED, 1); // off
|
||||
break;
|
||||
case LED_ON:
|
||||
mgos_gpio_write(ON_BOARD_LED, 0); // on
|
||||
break;
|
||||
case LED_BLINK_SLOW:
|
||||
++numTicksLedHasThisState = 0;
|
||||
if (numTicksLedHasThisState >= 4) {
|
||||
numTicksLedHasThisState = 0;
|
||||
mgos_gpio_toggle(ON_BOARD_LED);
|
||||
}
|
||||
break;
|
||||
case LED_BLINK_FAST:
|
||||
// toggle LED each tick
|
||||
mgos_gpio_toggle(ON_BOARD_LED);
|
||||
break;
|
||||
default:
|
||||
LOG(LL_ERROR, ("Invalid current LED status: %d -- ignored", currentStatus));
|
||||
break;
|
||||
}
|
||||
(void) arg;
|
||||
}
|
||||
|
||||
void init_led_handler() {
|
||||
mgos_gpio_set_mode(ON_BOARD_LED, MGOS_GPIO_MODE_OUTPUT);
|
||||
mgos_set_timer(250, MGOS_TIMER_REPEAT, blink_on_board_led_cb, NULL);
|
||||
LOG(LL_DEBUG, ("LED handler initialized"));
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Author: Dirk Jahnke
|
||||
// January 24, 2018
|
||||
//
|
||||
// Manage on board LED of SONOFF device
|
||||
//
|
||||
#ifndef ledHandler_h_included
|
||||
#define ledHandler_h_included
|
||||
|
||||
enum LEDStatus {
|
||||
LED_OFF = 0, // permanently off
|
||||
LED_ON = 1, // permanently on
|
||||
LED_BLINK_SLOW = 2, // on 0,5x / second (1s on, 1s off)
|
||||
LED_BLINK_FAST = 3 // on 2x / second (250ms on, 250ms off)
|
||||
};
|
||||
|
||||
extern void set_led_status(LEDStatus newStatus);
|
||||
extern void init_led_handler();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "common/platform.h"
|
||||
#include "common/cs_file.h"
|
||||
#include "mgos_app.h"
|
||||
#include "mgos_gpio.h"
|
||||
#include "mgos_sys_config.h"
|
||||
#include "mgos_timers.h"
|
||||
#include "mgos_hal.h"
|
||||
#include "mgos_dlsym.h"
|
||||
#include "mgos_mqtt.h"
|
||||
#include "mjs.h"
|
||||
|
||||
#include "ledHandler.h"
|
||||
|
||||
|
||||
bool mqtt_conn_flag = false;
|
||||
|
||||
int mqtt_connected(void) {
|
||||
return (int) mqtt_conn_flag;
|
||||
}
|
||||
|
||||
//static void pub(struct mg_connection *c, const char *fmt, ...) {
|
||||
//char msg[200];
|
||||
//struct json_out jmo = JSON_OUT_BUF(msg, sizeof(msg));
|
||||
//va_list ap;
|
||||
//int n;
|
||||
//va_start(ap, fmt);
|
||||
//n = json_vprintf(&jmo, fmt, ap);
|
||||
//va_end(ap);
|
||||
//mg_mqtt_publish(c, get_cfg()->mqtt.pub, 0, MG_MQTT_QOS(0), msg, n);
|
||||
//LOG(LL_INFO, ("%s -> %s", get_cfg()->mqtt.pub, msg));
|
||||
//}
|
||||
|
||||
static void mqtt_ev_handler(struct mg_connection *c, int ev, void *p, void *user_data) {
|
||||
struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p;
|
||||
if (ev == MG_EV_MQTT_CONNACK) {
|
||||
LOG(LL_INFO, ("MQTT connected: %d", msg->connack_ret_code));
|
||||
mqtt_conn_flag = true;
|
||||
//if (get_cfg()->mqtt.pub == NULL) {
|
||||
//LOG(LL_ERROR, ("Run 'mos config-set mqtt.pub=... '"));
|
||||
//} else {
|
||||
//pub(c, "{timestamp:%.3lf, mem_free:%d}", mg_time(), mgos_get_free_heap_size() ); /* post uptime */
|
||||
//}
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
mqtt_conn_flag = false;
|
||||
}
|
||||
(void) user_data;
|
||||
(void) c;
|
||||
}
|
||||
|
||||
enum mgos_app_init_result mgos_app_init(void) {
|
||||
init_led_handler();
|
||||
mgos_mqtt_add_global_handler(mqtt_ev_handler, NULL);
|
||||
LOG(LL_DEBUG, ("SONOFF app initialized"));
|
||||
return MGOS_APP_INIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue