Skip to content

Instantly share code, notes, and snippets.

@sergejmueller
Created May 3, 2017 18:38
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergejmueller/81397faacb7796340ce658a4a9b5422d to your computer and use it in GitHub Desktop.
Save sergejmueller/81397faacb7796340ce658a4a9b5422d to your computer and use it in GitHub Desktop.
ESP8266 + SSD1306 ♥ FRITZ!Box API
/*
* ESP8266 + SSD1306 ♥ FRITZ!Box API
*
* Ausgabe der aktuell über die FRITZ!DECT 200 Steckdose
* entnommenen Leistung als Prozentwert auf einem SSD1306 OLED Display.
* Praxisbeispiel: Durch die Solaranlage eingespeiste Leistung abrufen
* und auf dem OLED Display in Form eines Prozentwertes einblenden.
*
* Referenzen:
* http://www.instructables.com/id/Wemos-D1-Mini-096-SSD1306-OLED-Display-Using-SPI/
* http://www.open4me.de/index.php/2016/10/fritzbox-esp8266-laesst-telefon-klingeln/
* https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AHA-HTTP-Interface.pdf
*
*/
#include <ESP8266WiFi.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266HTTPClient.h>
#define OLED_MOSI D7 //Connect to D1 on OLED
#define OLED_CLK D5 //Connect to D0 on OLED
#define OLED_DC D1 //Connect to DC on OLED
#define OLED_CS D8 //Connect to CS on OLED
#define OLED_RESET D3 //Connect to RES on OLED
Adafruit_SSD1306 display( OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS );
HTTPClient http;
const char* WIFI_SSID = "XXXXX";
const char* WIFI_PASS = "XXXXX";
const char* FRITZBOX_AIN = "XXXXX";
const char* FRITZBOX_PASS = "XXXXX";
const String FRITZBOX_DOMAIN = "http://fritz.box";
const int POWER_MAX = 244000;
const unsigned long UPDATE_INTERVAL = 60L * 1000L;
String fritzboxSID = "";
unsigned long lastConnection = 0;
void setup() {
Serial.begin( 115200 );
connectWiFi();
display.begin( SSD1306_SWITCHCAPVCC );
// display.setRotation( 2 );
display.display();
delay( 100 );
}
void loop() {
if ( millis() - lastConnection <= UPDATE_INTERVAL ) {
return;
}
if ( WiFi.status() != WL_CONNECTED ) {
return;
}
int switchPower = getSwitchPower();
if ( switchPower != -1 ) {
renderPercentage( switchPower );
}
lastConnection = millis();
}
void connectWiFi() {
if ( WiFi.status() == WL_CONNECTED ) {
return;
}
WiFi.mode( WIFI_STA );
WiFi.begin( WIFI_SSID, WIFI_PASS );
if ( WiFi.waitForConnectResult() != WL_CONNECTED ) {
Serial.println( "WiFi connection failed" );
}
}
void getSID() {
// Get Challenge
http.begin( FRITZBOX_DOMAIN + "/login_sid.lua" );
int retCode = http.GET();
if ( retCode != 200 ) {
Serial.println( "Get Challengd failed! " + String( retCode ) );
return;
}
String result = http.getString();
String challenge = result.substring( result.indexOf( "<Challenge>" ) + 11, result.indexOf( "<Challenge>" ) + 19);
// Calculate Response
String reponseASCII = challenge + "-" + FRITZBOX_PASS;
String responseHEX = "";
for ( unsigned int i = 0; i < reponseASCII.length(); i++ ) {
responseHEX = responseHEX + String( reponseASCII.charAt( i ), HEX ) + "00";
}
MD5Builder md5;
md5.begin();
md5.addHexString( responseHEX );
md5.calculate();
String response = challenge + "-" + md5.toString();
// Login and get SID
http.begin( FRITZBOX_DOMAIN + "/login_sid.lua?user=&response=" + response );
retCode = http.GET();
if ( retCode != 200 ) {
Serial.println( "Get Sid failed! " + String( retCode ) );
return;
}
result = http.getString();
fritzboxSID = result.substring( result.indexOf( "<SID>" ) + 5, result.indexOf( "<SID>" ) + 21 );
}
int getSwitchPower() {
if ( ! fritzboxSID.length() ) {
getSID();
}
http.begin( FRITZBOX_DOMAIN + "/webservices/homeautoswitch.lua?ain=" + FRITZBOX_AIN + "&switchcmd=getswitchpower&sid=" + fritzboxSID );
if ( http.GET() != 200 ) {
Serial.println( "Get getswitchpower failed!" );
return -1;
}
String result = http.getString();
result.trim();
return result.toInt();
}
void renderPercentage( int switchPower ) {
int powerPercentage = round( switchPower * 100 / POWER_MAX );
Serial.println( switchPower );
Serial.println( powerPercentage );
if ( powerPercentage >= 100 ) {
display.setTextSize( 7 );
display.setCursor( 1, 7 );
} else if ( powerPercentage >= 10 ) {
display.setTextSize(9);
display.setCursor( 14, 0);
} else {
display.setTextSize(9);
display.setCursor( display.width() / 2, 0);
}
display.clearDisplay();
display.setTextColor( WHITE );
display.println( powerPercentage );
display.display();
}
@gordonBimig
Copy link

Hello Sergej,

thanks a lot for publishing this code snippet. I'm currently working on a project (smart home standalone controller) where I' trying to unite the control (on/off basically) of all in house smart devices by a dedicated battery powered controller. Got a lot covered via ifttt webhooks but the AVM DECT 200 plugs are missing. So I thought a little adjustment to your code should do the job but unfortunately I can't even get it compiled :-(
The compiler says: exit status 1: 'MD5Builder' was not declared in this scope

I see that your code is made for the esp8266 board. Apparently it uses different libraries than the esp32?
I'm a Arduino/ESP beginner and was wondering if you could give me some advise how to solve this issue?

Regards

Gord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment