master
VogelT 2 years ago
parent a5211a1d49
commit 38aa10975f

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="io.sloeber.core.sketch.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="io.sloeber.core.sketch.0" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="io.sloeber.core.sketch.0" name="Release" parent="io.sloeber.core.configuration.release">
<folderInfo id="io.sloeber.core.sketch.0." name="/" resourcePath="">
<toolChain id="io.sloeber.core.toolChain.release.496733976" name="Arduino Toolchain (Sloeber edition)" superClass="io.sloeber.core.toolChain.release">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="io.sloeber.targetplatform.809105027" name="Arduino Target" osList="all" superClass="io.sloeber.targetplatform"/>
<builder buildPath="${workspace_loc:/ledalexacontrol}/Release" id="io.sloeber.sketch.builder.168208145" keepEnvironmentInBuildfile="false" name="Arduino sketch builder" parallelBuildOn="false" superClass="io.sloeber.sketch.builder"/>
<tool id="io.sloeber.tool.sketch.compiler.cpp.1839160483" name="Arduino C++ Compiler" superClass="io.sloeber.tool.sketch.compiler.cpp">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="io.sloeber.compiler.cpp.sketch.option.incpath.205549865" name="Include Paths (-I)" superClass="io.sloeber.compiler.cpp.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/core/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/fauxmoesp/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/Hash/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESP8266WiFi/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESPAsyncWebServer-master/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESPAsyncTCP-master/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/HttpClient}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.cpp.sketch.input.2019800643" name="CPP source files" superClass="io.sloeber.compiler.cpp.sketch.input"/>
</tool>
<tool id="io.sloeber.tool.compiler.c.1279072246" name="Arduino C Compiler" superClass="io.sloeber.tool.compiler.c">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="io.sloeber.compiler.c.sketch.option.incpath.1240873657" name="Include Paths (-I)" superClass="io.sloeber.compiler.c.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/core/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/fauxmoesp/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/Hash/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESP8266WiFi/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESPAsyncWebServer-master/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESPAsyncTCP-master/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/HttpClient}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.c.sketch.input.1740515185" name="C Source Files" superClass="io.sloeber.compiler.c.sketch.input"/>
</tool>
<tool id="io.sloeber.tool.sketch.compiler.s.2062074077" name="Arduino Assembler" superClass="io.sloeber.tool.sketch.compiler.s">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="io.sloeber.compiler.asm.sketch.option.incpath.1276372851" name="Include Paths (-I)" superClass="io.sloeber.compiler.asm.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/core/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/fauxmoesp/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/Hash/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESP8266WiFi/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESPAsyncWebServer-master/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/ESPAsyncTCP-master/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ledalexacontrol/libraries/HttpClient}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.S.sketch.input.1535868986" name="Assembly source files" superClass="io.sloeber.compiler.S.sketch.input"/>
</tool>
<tool id="io.sloeber.tool.ar.1288121665" name="Arduino archiver" superClass="io.sloeber.tool.ar"/>
<tool id="io.sloeber.tool.combine.1777660143" name="Arduino combiner" superClass="io.sloeber.tool.combine"/>
<tool id="io.sloeber.tool.objcopy.eep.410718358" name="Arduino tool objcopy command" superClass="io.sloeber.tool.objcopy.eep"/>
<tool id="io.sloeber.tool.size.118295777" name="Arduino tool Print Size" superClass="io.sloeber.tool.size"/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/**/._*" resourcePath="libraries/**/._*">
<toolChain id="io.sloeber.core.toolChain5.776514380" superClass="io.sloeber.core.toolChain5">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/**/._*.2020776111" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/test*/**" resourcePath="libraries/?*/**/test*/**">
<toolChain id="io.sloeber.core.toolChain3.1407685364" superClass="io.sloeber.core.toolChain3">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/test*/**.1545829366" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/?xtras/**" resourcePath="libraries/?*/**/?xtras/**">
<toolChain id="io.sloeber.core.toolChain2.1432679330" superClass="io.sloeber.core.toolChain2">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/?xtras/**.159739638" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/?xamples/**" resourcePath="libraries/?*/**/?xamples/**">
<toolChain id="io.sloeber.core.toolChain1.793905366" superClass="io.sloeber.core.toolChain1">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/?xamples/**.1918610063" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/third-party/**" resourcePath="libraries/?*/**/third-party/**">
<toolChain id="io.sloeber.core.toolChain4.1478589851" superClass="io.sloeber.core.toolChain4">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/third-party/**.1984495410" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/utility/*/*" resourcePath="libraries/?*/utility/*/*">
<toolChain id="io.sloeber.core.toolChain6.700157409" superClass="io.sloeber.core.toolChain6">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/utility/*/*.1727963381" name=""/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="libraries/ESPAsyncWebServer-master/travis|libraries/ESPAsyncTCP-master/ssl|libraries/ESPAsyncTCP-master/.github|libraries/fauxmoesp/docs|libraries/?*/**/?xamples/**|libraries/?*/**/?xtras/**|libraries/?*/**/test*/**|libraries/?*/**/third-party/**|libraries/**/._*|libraries/?*/utility/*/*" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="ledalexacontrol.io.sloeber.core.sketch.2020068257" name="Arduino sketch" projectType="io.sloeber.core.sketch"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="uploadWithProgrammerWithoutBuild" path="Release" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>${sloeber.make_location}make</buildCommand>
<buildArguments/>
<buildTarget>uploadWithProgrammerWithoutBuild</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="BurnBootLoader" path="Release" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>${sloeber.make_location}make</buildCommand>
<buildArguments/>
<buildTarget>BurnBootLoader</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

@ -0,0 +1,2 @@
/Release/
/sloeber.ino.cpp

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ledalexacontrol</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>io.sloeber.core.inoToCpp</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>io.sloeber.arduinonature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>core/core</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266</locationURI>
</link>
<link>
<name>core/variant</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.2/variants/d1_mini</locationURI>
</link>
<link>
<name>libraries/ESP8266WiFi</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi</locationURI>
</link>
<link>
<name>libraries/ESPAsyncTCP-master</name>
<type>2</type>
<location>C:/Users/vogelt/Documents/Arduino/libraries/ESPAsyncTCP-master</location>
</link>
<link>
<name>libraries/ESPAsyncWebServer-master</name>
<type>2</type>
<location>C:/Users/vogelt/Documents/Arduino/libraries/ESPAsyncWebServer-master</location>
</link>
<link>
<name>libraries/Hash</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.2/libraries/Hash</locationURI>
</link>
<link>
<name>libraries/HttpClient</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/libraries/HttpClient/2.2.0</locationURI>
</link>
<link>
<name>libraries/fauxmoesp</name>
<type>2</type>
<location>C:/Users/vogelt/Documents/Arduino/libraries/fauxmoesp</location>
</link>
</linkedResources>
</projectDescription>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="io.sloeber.core.sketch.0" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider class="io.sloeber.core.toolchain.ArduinoLanguageProvider" console="false" env-hash="1166240687636990227" id="io.sloeber.languageSettingsProvider" keep-relative-paths="false" name="Arduino Compiler Settings" parameter="${COMMAND} -E -P -v -dD -D__IN_ECLIPSE__ &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=windows-1252

@ -0,0 +1,37 @@
Config.Release.board.BOARD.ID=d1_mini
Config.Release.board.BOARD.MENU.CpuFrequency=80
Config.Release.board.BOARD.MENU.Debug=Disabled
Config.Release.board.BOARD.MENU.DebugLevel=None____
Config.Release.board.BOARD.MENU.FlashErase=none
Config.Release.board.BOARD.MENU.FlashSize=4M1M
Config.Release.board.BOARD.MENU.LwIPVariant=v2mss536
Config.Release.board.BOARD.MENU.UploadSpeed=921600
Config.Release.board.BOARD.MENU.VTable=flash
Config.Release.board.BOARD.MENU.baud=getMenuItemIDFromMenuItemName did not find menu item with name "115200" for menu ID "baud" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.dbg=getMenuItemIDFromMenuItemName did not find menu item with name "Disabled" for menu ID "dbg" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.eesz=getMenuItemIDFromMenuItemName did not find menu item with name "4MB (FS:2MB OTA:~1019KB)" for menu ID "eesz" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.exception=getMenuItemIDFromMenuItemName did not find menu item with name "Disabled (new aborts on oom)" for menu ID "exception" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.ip=getMenuItemIDFromMenuItemName did not find menu item with name "v2 Lower Memory" for menu ID "ip" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.lvl=getMenuItemIDFromMenuItemName did not find menu item with name "None" for menu ID "lvl" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.mmu=getMenuItemIDFromMenuItemName did not find menu item with name "32KB cache + 32KB IRAM (balanced)" for menu ID "mmu" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.non32xfer=getMenuItemIDFromMenuItemName did not find menu item with name "Use pgm_read macros for IRAM/PROGMEM" for menu ID "non32xfer" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.ssl=getMenuItemIDFromMenuItemName did not find menu item with name "All SSL ciphers (most compatible)" for menu ID "ssl" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.stacksmash=getMenuItemIDFromMenuItemName did not find menu item with name "Disabled" for menu ID "stacksmash" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.vt=getMenuItemIDFromMenuItemName did not find menu item with name "Flash" for menu ID "vt" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.wipe=getMenuItemIDFromMenuItemName did not find menu item with name "Only Sketch" for menu ID "wipe" and for boardID "d1_mini"!
Config.Release.board.BOARD.MENU.xtal=getMenuItemIDFromMenuItemName did not find menu item with name "160 MHz" for menu ID "xtal" and for boardID "d1_mini"!
Config.Release.board.BOARD.TXT=${SLOEBER_HOME}/arduinoPlugin/packages/esp8266/hardware/esp8266/2.4.2/boards.txt
Config.Release.board.PROGRAMMER.NAME=
Config.Release.board.UPLOAD.PORT=COM11
Config.Release.compile.sloeber.extra.all=
Config.Release.compile.sloeber.extra.archive=
Config.Release.compile.sloeber.extra.assembly=
Config.Release.compile.sloeber.extra.c.compile=
Config.Release.compile.sloeber.extra.compile=
Config.Release.compile.sloeber.extra.cpp.compile=
Config.Release.compile.sloeber.extra.link=
Config.Release.compile.sloeber.size.custom=
Config.Release.compile.sloeber.size.type=RAW_RESULT
Config.Release.compile.sloeber.warning_level=NONE
Config.Release.compile.sloeber.warning_level.custom=
Config.Release.other.IS_VERSION_CONTROLLED=false

@ -0,0 +1,118 @@
#include "Arduino.h"
#include <fauxmoESP.h>
#include <ESP8266WiFi.h>
fauxmoESP fauxmo;
// Replace with your network credentials
const char *ssid = "FRITZ!BoxWZ";
const char *password = "40360548708873074408";
IPAddress ip(192, 168, 178, 14);
IPAddress subnet(255, 255, 255, 0);
IPAddress gateway(192, 168, 178, 1);
const char* serverhost = "192.168.178.12";
void httpConnect() {
WiFiClient client;
Serial.printf("\n[Connecting to %s ... ", serverhost);
if (client.connect(serverhost,88))
{
Serial.println("connected]");
client.println("PUT /ledDemoOn");
delay(10000);
client.println("PUT /ledDemoOff");
delay(10000);
Serial.println("[Response:]");
while (client.connected() || client.available())
{
if (client.available())
{
String line = client.readStringUntil('\n');
Serial.println(line);
}
}
client.stop();
Serial.println("\n[Disconnected]");
}
else
{
Serial.println("connection failed!]");
client.stop();
}
delay(5000);
}
void setup() {
Serial.begin(115200);
if (connectWifi()) {
fauxmo.addDevice("LED Schrank");
fauxmo.addDevice("LED Fernseher");
fauxmo.addDevice("LED Demo");
fauxmo.enable(true);
//fauxmo.onMessage(fn)
fauxmo.onMessage([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
httpConnect();
// HttpClient client;
//
// if (state == true) {
// client.begin("http://192.168.178.12:88/ledDemoOn"); //Specify request destination
// } else {
// client.begin("http://192.168.178.12:88/ledDemoOff"); //Specify request destination
// }
// int httpCode = client.GET();
// String payload = client.getString();
// Serial.println(payload);
// Serial.println("Test");
// client.end();
});
}
}
// ------------ FINISH -----------------
boolean connectWifi() {
boolean stat = true;
// Connect to Wi-Fi
WiFi.config(ip, gateway, subnet); // uncomment for dynamic IP
WiFi.begin(ssid, password);
int count = 0;
while (WiFi.status() != WL_CONNECTED) {
count++;
digitalWrite(D4, LOW);
delay(1000);
digitalWrite(D4, HIGH);
Serial.println("Connecting to WiFi..");
if (count == 10) {
stat = false;
break;
}
}
if (stat == true) {
digitalWrite(D4, LOW);
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
}
return stat;
}
void loop() {
fauxmo.handle();
}

@ -0,0 +1,12 @@
credentials.h
utils
# Precompiled Headers
*.gch
*.pch
# PlatformIO folders
.pio*
pio
.clang_complete
.gcc-flags.json

@ -0,0 +1,35 @@
# fauxmoESP change log
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [2.1.0] 2017-02-15
### Added
- ESPAsyncWebServer to manage TCP connections
### Fixed
- Memory leaks in UDP and TCP connections
## [2.0.0] 2017-01-05
### Added
- Different discovery strategies to maximize device discovery
- UDP polling required (call handle() in your loop)
### Changed
- ```onMessage``` callback signature changed to add device_id
### Removed
- Removed dependency on ESPAsyncUDP for compatibility with current stable release of Arduino Code for ESP8266
## [1.0.0] 2016-11-26
### Added
- Support for multiple virtual devices
### Changed
- ```onMessage``` callback signature has changed to allow passing the device name
### Deprecated
- ```setDeviceName``` no longer exists, use ```addDevice``` instead
## [0.1.0] 2016-11-21
- Initial working version

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.

@ -0,0 +1,89 @@
# fauxmoESP
Amazon Alexa support for ESP8266 devices.
This is a library for ESP8266-based devices that emulates a Belkin WeMo device and thus allows you to control them using this protocol, in particular from Alexa-powered devices like the Amazon Echo or the Dot.
This library is a port of Maker Musings' [Fauxmo Python library][6].
**Current Version is 2.1.0**, this version shows some backwards incompatibilities with version 1.0.0. Check the examples to rewrite your code if you were using a previous version and read the [changelog](CHANGELOG.md).
## Dependencies
This library uses [ESPAsyncTCP][3] and [ESPAsyncWebServer][4] libraries by [me-no-dev][5].
### PlatformIO
If you are using PlatformIO (check the section bellow on how to compile it) you can install them by adding the dependencies to your ```platformio.ini``` file:
```
lib_deps =
ESPAsyncTCP
ESPAsyncWebServer
```
### Arduino IDE
You will need to install the required library from sources. Your best option is to download the library as a ZIP file and install it using the option under "Sketch > Include Library > Add .ZIP Library...".
You can look for it manually but I have gathered the URL here for convenience:
|Library|Repository|ZIP|
|-|-|-|
|**ESPAsyncTCP** by Hristo Gochkov|[GIT](https://github.com/me-no-dev/ESPAsyncTCP)|[ZIP](https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip)|
|**ESPAsyncWebServer** by Hristo Gochkov|[GIT](https://github.com/me-no-dev/ESPAsyncWebServer)|[ZIP](https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip)||
## Usage
The library is very easy to use, basically instantiate an object, connect to the Wifi, add one or more virtual devices and bind the callback to get the messages. An schematic example could be:
```
#include <fauxmoESP.h>
fauxmoESP fauxmo;
void setup() {
Serial.begin(115200);
... connect to wifi ...
fauxmo.addDevice("light one");
fauxmo.addDevice("light two");
fauxmo.addDevice("light three");
fauxmo.addDevice("light four");
fauxmo.onMessage([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
});
}
void loop() {
fauxmoESP.handle();
}
```
(Check the examples folder)
Then run the "discover devices" option from your Alexa app or web (in the Smart Home section). A new device with the name you have configured should appear. Tell Alexa to switch it on or off and check your terminal ;)
## Device discovery
Device discovery can be incomplete when you have lots of devices defined. Since version 2.0.0 different strategies are used to maximize the chance of getting all of them discovered during the first round.
Tests have been run with up to 16 devices with success but your experience might be different. If not all of them are discovered on the first run, execute the Discover Devices option again from your Alexa app or tell your Echo/Dot to do it. Once they pop up in your devices list (even if they are flagged as "Offline") they should work just fine.
The strategies the library uses to improve discoverability are:
* Space UDP responses to help Echo/Dot and the device itself to perform setup queries
* Repeat UDP responses for devices not queried
* Randomize UDP responses
[1]:https://github.com/esp8266/Arduino
[2]:http://docs.platformio.org/en/stable/platforms/espressif8266.html#using-arduino-framework-with-staging-version
[3]:https://github.com/me-no-dev/ESPAsyncTCP
[4]:https://github.com/me-no-dev/ESPAsyncWebServer
[5]:https://github.com/me-no-dev
[6]:https://github.com/makermusings/fauxmo

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<root xmlns="urn:Belkin:device-1-0">
<device>
<deviceType>urn:Belkin:device:controllee:1</deviceType>
<friendlyName>%s</friendlyName>
<manufacturer>Belkin International Inc.</manufacturer>
<modelName>FauxmoESP</modelName>
<modelNumber>2.0.0</modelNumber>
<UDN>uuid:Socket-1_0-%s</UDN>
<serviceList>
<service>
<serviceType>urn:Belkin:service:basicevent:1</serviceType>
<serviceId>urn:Belkin:serviceId:basicevent1</serviceId>
<controlURL>/upnp/control/basicevent1</controlURL>
<eventSubURL>/upnp/event/basicevent1</eventSubURL>
<SCPDURL>/eventservice.xml</SCPDURL>
</service>
</serviceList>
</device>
</root>

@ -0,0 +1,82 @@
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"
#include "credentials.h"
#define SERIAL_BAUDRATE 115200
#define LED 2
fauxmoESP fauxmo;
// -----------------------------------------------------------------------------
// Wifi
// -----------------------------------------------------------------------------
void wifiSetup() {
// Set WIFI module to STA mode
WiFi.mode(WIFI_STA);
// Connect
Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
// Wait
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println();
// Connected!
Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}
void setup() {
// Init serial port and clean garbage
Serial.begin(SERIAL_BAUDRATE);
Serial.println();
Serial.println();
// Wifi
wifiSetup();
// LED
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
// Fauxmo
fauxmo.addDevice("light one");
fauxmo.addDevice("light two");
fauxmo.addDevice("light three");
fauxmo.addDevice("light four");
// fauxmoESP 2.0.0 has changed the callback signature to add the device_id, this WARRANTY
// it's easier to match devices to action without having to compare strings.
fauxmo.onMessage([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
digitalWrite(LED, !state);
});
}
void loop() {
// Since fauxmoESP 2.0 the library uses the "compatibility" mode by
// default, this means that it uses WiFiUdp class instead of AsyncUDP.
// The later requires the Arduino Core for ESP8266 staging version
// whilst the former works fine with current stable 2.3.0 version.
// But, since it's not "async" anymore we have to manually poll for UDP
// packets
fauxmo.handle();
static unsigned long last = millis();
if (millis() - last > 5000) {
last = millis();
Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap());
}
}

@ -0,0 +1,26 @@
{
"name": "FauxmoESP",
"keywords": "belkin,wemo,fauxmo,esp8266,alexa,amazon,echo,dot",
"description": "Amazon Alexa support for ESP8266 (Amazon Echo & Dot)",
"repository": {
"type": "git",
"url": "https://bitbucket.org/xoseperez/fauxmoesp.git"
},
"version": "2.1.0",
"license": "MIT",
"exclude": "tests",
"frameworks": "arduino",
"platforms": "espressif8266",
"dependencies": [
{ "name": "ESPAsyncTCP" }
],
"authors": {
"name": "Xose Perez",
"email": "xose.perez@gmail.com",
"url": "http://tinkerman.cat",
"maintainer": true
},
"examples": [
"examples/*/src/*.ino"
]
}

@ -0,0 +1,9 @@
name=FauxmoESP
version=2.1.0
author=Xose Perez
maintainer=Xose Perez
sentence=Amazon Alexa support for ESP8266
paragraph=Amazon Alexa support for ESP8266
category=Other
url=https://bitbucket.org/xoseperez/fauxmoESP
architectures=*

@ -0,0 +1,207 @@
/*
FAUXMO ESP 2.0.0
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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 <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"
void fauxmoESP::_sendUDPResponse(unsigned int device_id) {
fauxmoesp_device_t device = _devices[device_id];
DEBUG_MSG_FAUXMO("[FAUXMO] UDP response for device #%d (%s)\n", _current, device.name);
char buffer[16];
IPAddress ip = WiFi.localIP();
sprintf(buffer, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
char response[strlen(UDP_TEMPLATE) + 40];
sprintf_P(response, UDP_TEMPLATE,
buffer,
_base_port + _current,
device.uuid,
device.uuid
);
_udp.beginPacket(_remoteIP, _remotePort);
_udp.write(response);
_udp.endPacket();
}
void fauxmoESP::_nextUDPResponse() {
while (_roundsLeft) {
if (_devices[_current].hit == false) break;
if (++_current == _devices.size()) {
--_roundsLeft;
_current = 0;
}
}
if (_roundsLeft > 0) {
_sendUDPResponse(_current);
if (++_current == _devices.size()) {
--_roundsLeft;
_current = 0;
}
}
}
void fauxmoESP::_handleUDPPacket(IPAddress remoteIP, unsigned int remotePort, uint8_t *data, size_t len) {
if (!_enabled) return;
data[len] = 0;
if (strstr((char *) data, UDP_SEARCH_PATTERN) == (char *) data) {
if (strstr((char *) data, UDP_DEVICE_PATTERN) != NULL) {
#ifdef DEBUG_FAUXMO
char buffer[16];
sprintf(buffer, "%d.%d.%d.%d", remoteIP[0], remoteIP[1], remoteIP[2], remoteIP[3]);
DEBUG_MSG_FAUXMO("[FAUXMO] Search request from %s\n", buffer);
#endif
// Set hits to false
for (unsigned int i = 0; i < _devices.size(); i++) {
_devices[i].hit = false;
}
// Send responses
_remoteIP = remoteIP;
_remotePort = remotePort;
_current = random(0, _devices.size());
_roundsLeft = UDP_RESPONSES_TRIES;
}
}
}
void fauxmoESP::_handleSetup(AsyncWebServerRequest *request, unsigned int device_id) {
if (!_enabled) return;
DEBUG_MSG_FAUXMO("[FAUXMO] Device #%d /setup.xml\n", device_id);
_devices[device_id].hit = true;
fauxmoesp_device_t device = _devices[device_id];
char response[strlen(SETUP_TEMPLATE) + 50];
sprintf_P(response, SETUP_TEMPLATE, device.name, device.uuid);
request->send(200, "text/xml", response);
}
void fauxmoESP::_handleContent(AsyncWebServerRequest *request, unsigned int device_id, char * content) {
if (!_enabled) return;
DEBUG_MSG_FAUXMO("[FAUXMO] Device #%d /upnp/control/basicevent1\n", device_id);
fauxmoesp_device_t device = _devices[device_id];
if (strstr(content, "<BinaryState>0</BinaryState>") != NULL) {
if (_callback) _callback(device_id, device.name, false);
}
if (strstr(content, "<BinaryState>1</BinaryState>") != NULL) {
if (_callback) _callback(device_id, device.name, true);
}
}
void fauxmoESP::addDevice(const char * device_name) {
fauxmoesp_device_t new_device;
unsigned int device_id = _devices.size();
// Copy name
new_device.name = strdup(device_name);
// Create UUID
char uuid[15];
sprintf(uuid, "444556%06X%02X\0", ESP.getChipId(), device_id); // "DEV" + CHIPID + DEV_ID
new_device.uuid = strdup(uuid);
// TCP Server
new_device.server = new AsyncWebServer(_base_port + device_id);
new_device.server->on("/setup.xml", HTTP_GET, [this, device_id](AsyncWebServerRequest *request){
_handleSetup(request, device_id);
});
new_device.server->on("/upnp/control/basicevent1", HTTP_POST,
[](AsyncWebServerRequest *request) {
request->send(200);
},
NULL,
[this, device_id](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
data[len] = 0;
_handleContent(request, device_id, (char *) data);
}
);
new_device.server->begin();
// Attach
_devices.push_back(new_device);
DEBUG_MSG_FAUXMO("[FAUXMO] Device '%s' added (#%d)\n", device_name, device_id);
}
void fauxmoESP::handle() {
int len = _udp.parsePacket();
if (len > 0) {
IPAddress remoteIP = _udp.remoteIP();
unsigned int remotePort = _udp.remotePort();
uint8_t data[len];
_udp.read(data, len);
_handleUDPPacket(remoteIP, remotePort, data, len);
}
if (_roundsLeft > 0) {
if (millis() - _lastTick > UDP_RESPONSES_INTERVAL) {
_lastTick = millis();
_nextUDPResponse();
}
}
}
void fauxmoESP::enable(bool enable) {
DEBUG_MSG_FAUXMO("[FAUXMO] %s\n", enable ? "Enabled" : "Disabled");
_enabled = enable;
}
fauxmoESP::fauxmoESP(unsigned int port) {
_base_port = port;
// UDP Server
_udp.beginMulticast(WiFi.localIP(), UDP_MULTICAST_IP, UDP_MULTICAST_PORT);
}

@ -0,0 +1,132 @@
/*
FAUXMO ESP 2.0.0
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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.
*/
#ifndef FAUXMOESP_h
#define FAUXMOESP_h
#define DEFAULT_TCP_BASE_PORT 52000
#define UDP_MULTICAST_IP IPAddress(239,255,255,250)
#define UDP_MULTICAST_PORT 1900
#define TCP_MAX_CLIENTS 10
#define UDP_SEARCH_PATTERN "M-SEARCH"
#define UDP_DEVICE_PATTERN "urn:Belkin:device:**"
#define UDP_RESPONSES_INTERVAL 250
#define UDP_RESPONSES_TRIES 5
const char UDP_TEMPLATE[] PROGMEM =
"HTTP/1.1 200 OK\r\n"
"CACHE-CONTROL: max-age=86400\r\n"
"DATE: Sun, 20 Nov 2016 00:00:00 GMT\r\n"
"EXT:\r\n"
"LOCATION: http://%s:%d/setup.xml\r\n"
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
"01-NLS: %s\r\n"
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
"ST: urn:Belkin:device:**\r\n"
"USN: uuid:Socket-1_0-%s::urn:Belkin:device:**\r\n\r\n";
const char SETUP_TEMPLATE[] PROGMEM =
"<?xml version=\"1.0\"?>"
"<root><device>"
"<deviceType>urn:Belkin:device:controllee:1</deviceType>"
"<friendlyName>%s</friendlyName>"
"<manufacturer>Belkin International Inc.</manufacturer>"
"<modelName>FauxmoESP</modelName>"
"<modelNumber>2.0.0</modelNumber>"
"<UDN>uuid:Socket-1_0-%s</UDN>"
"</device></root>";
const char HEADERS[] PROGMEM =
"HTTP/1.1 200 OK\r\n"
"CONTENT-LENGTH: %d\r\n"
"CONTENT-TYPE: text/xml\r\n"
"DATE: Sun, 01 Jan 2017 00:00:00 GMT\r\n"
"LAST-MODIFIED: Sat, 01 Jan 2017 00:00:00 GMT\r\n"
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
"X-USER-AGENT: redsonic\r\n"
"CONNECTION: close\r\n\r\n"
"%s\r\n";
#ifdef DEBUG_FAUXMO
#define DEBUG_MSG_FAUXMO(...) DEBUG_FAUXMO.printf( __VA_ARGS__ )
#else
#define DEBUG_MSG_FAUXMO(...)
#endif
#include <Arduino.h>
#include <ESPAsyncWebServer.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <WiFiUdp.h>
#include <functional>
#include <vector>
typedef std::function<void(unsigned char, const char *, bool)> TStateFunction;
typedef struct {
char * name;
char * uuid;
bool hit;
AsyncWebServer * server;
} fauxmoesp_device_t;
class fauxmoESP {
public:
fauxmoESP(unsigned int port = DEFAULT_TCP_BASE_PORT);
void addDevice(const char * device_name);
void onMessage(TStateFunction fn) { _callback = fn; }
void enable(bool enable);
void handle();
private:
bool _enabled = true;
unsigned int _base_port = DEFAULT_TCP_BASE_PORT;
std::vector<fauxmoesp_device_t> _devices;
WiFiUDP _udp;
TStateFunction _callback = NULL;
unsigned int _roundsLeft = 0;
unsigned int _current = 0;
unsigned long _lastTick;
IPAddress _remoteIP;
unsigned int _remotePort;
void _sendUDPResponse(unsigned int device_id);
void _nextUDPResponse();
void _handleUDPPacket(const IPAddress remoteIP, unsigned int remotePort, uint8_t *data, size_t len);
void _handleSetup(AsyncWebServerRequest *request, unsigned int device_id);
void _handleContent(AsyncWebServerRequest *request, unsigned int device_id, char * content);
};
#endif

@ -0,0 +1,2 @@
spec.o: \
C:/workspace/Arduino/.metadata/.plugins/org.eclipse.cdt.managedbuilder.core/spec.cpp

@ -2,7 +2,7 @@
<project>
<configuration id="io.sloeber.core.sketch.0" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider class="io.sloeber.core.toolchain.ArduinoLanguageProvider" console="false" env-hash="-191870581023958806" id="io.sloeber.languageSettingsProvider" keep-relative-paths="false" name="Arduino Compiler Settings" parameter="${COMMAND} -E -P -v -dD -D__IN_ECLIPSE__ &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="io.sloeber.core.toolchain.ArduinoLanguageProvider" console="false" env-hash="-261678073289054212" id="io.sloeber.languageSettingsProvider" keep-relative-paths="false" name="Arduino Compiler Settings" parameter="${COMMAND} -E -P -v -dD -D__IN_ECLIPSE__ &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

Loading…
Cancel
Save