Pi-Hole stats displayed on an e-paper display


#1

Whats Used

  • ESPaper Plus - $50
  • Arduino IDE - $free

What it is

A few months back I posted a project here on the forums for a desk ornament I put together using a small OLED display and an ESP-32 which shows stats by parsing data from a JSON request to the PiHole API.

Since then I came across a kit by @squix78 which includes an e-paper display with an integrated ESP-8266. I wanted to remove the astronomy data and see if the code from the previous post could be adapted to this device.

The code is simply adding the drawPiHole() function, referencing to it in the main program and finally commenting out the drawAstronomy() function from the original code. As both the ESP-32 from the original project and the ESP-8266 used here are similiar (both manufactured by Espressif, Arduino compatible & have integrated Wi-Fi)

screenshot_1 (2)

Code

#include <ArduinoJson.h>
const char* piHolehost         = "192.168.0.2"; // Pi-Hole IP Address

void drawPiHole() {
if((WiFi.status() == WL_CONNECTED)) {
	HTTPClient http;
	http.begin("http://"+ String(piHolehost) +"/admin/api.php?summary");
	int httpCode = http.GET();
	if(httpCode > 0) {
            if(httpCode == HTTP_CODE_OK) {
            String piHoleString1 = http.getString();
            const size_t bufferSize = JSON_OBJECT_SIZE(9) + 230;
            DynamicJsonBuffer jsonBuffer(bufferSize);
            JsonObject& root = jsonBuffer.parseObject(piHoleString1);
            JsonObject& response = root["response"];
            JsonObject& response_data0 = response["data"][0];
            const char* domains_being_blocked = root["domains_being_blocked"]; 
            const char* dns_queries_today = root["dns_queries_today"]; 
            const char* ads_blocked_today = root["ads_blocked_today"]; 
            const char* ads_percentage_today = root["ads_percentage_today"]; 
            const char* unique_domains = root["unique_domains"]; 
            const char* queries_forwarded = root["queries_forwarded"]; 
            const char* queries_cached = root["queries_cached"]; 
            const char* clients_ever_seen = root["clients_ever_seen"]; 
            const char* unique_clients = root["unique_clients"]; 
            gfx.setFont(ArialMT_Plain_10);
            gfx.setTextAlignment(TEXT_ALIGN_LEFT);
            gfx.drawString(15, 72, "Ads Blocked Today: " + String(ads_blocked_today));
            gfx.drawString(15, 84, "Domains Blocked: " + String(domains_being_blocked));
            gfx.drawString(15, 96, "Percentage of Ads: " + String(ads_percentage_today) + "%");
            http.end();
        }} else {
}
}

if((WiFi.status() == WL_CONNECTED)) {
    HTTPClient http2;
    http2.begin("http://"+ String(piHolehost) +"/admin/api.php?recentBlocked"); //HTTP
    int httpCode2 = http2.GET();
    if(httpCode2 > 0) {
       if(httpCode2 == HTTP_CODE_OK) {
         String piHoleString2 = http2.getString();           
         gfx.drawString(150, 72, "Last Blocked:");
         gfx.drawString(150, 84, String(piHoleString2));
         http2.end();
       }
   } else {
       gfx.drawString(100, 84, "Cant Connect");
  }
}

}

Logo

Every 10 minutes the screen refreshes with a loading screen by default as it connects to the WUnderground API, and now also Pi-Hole API as well. Wanted to add the PiHole logo to that loading screen so I saved the original logo from the website and traced over it in Gimp until eventually I was able to export a .xbm file which rendered pretty cleanly on the display. This .xbm file can be opened with a text editor, and then copy/pasted directly into the Arduino projects code

The code included with the kit, and free on GitHub, includes a weathericons.h file for displaying weather logos already, so we can simply paste the .xbm data exported data there, and reference it in the updateData() function.

.XBM Exported from Gimp

#define piHoleLogo_width 54
#define piHoleLogo_height 78
static char piHoleLogo_bits[] = {
   0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
   0x00, 0x18, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,
   0xe0, 0x07, 0x00, 0x30, 0x00, 0x20, 0x00, 0x38, 0x04, 0x00, 0x20, 0x00,
   0x40, 0x00, 0x06, 0x04, 0x00, 0x60, 0x00, 0x40, 0x00, 0x01, 0x04, 0x00,
   0x40, 0x00, 0x80, 0x80, 0x00, 0x04, 0x00, 0xc0, 0x00, 0x80, 0x40, 0x00,
   0x02, 0x00, 0x80, 0x01, 0x82, 0x41, 0x00, 0x02, 0x00, 0x00, 0x01, 0x04,
   0x21, 0x00, 0x02, 0x00, 0x00, 0x02, 0x08, 0x31, 0x00, 0x01, 0x00, 0x00,
   0x0c, 0x10, 0x11, 0x80, 0x00, 0x00, 0x00, 0x08, 0x20, 0x0a, 0xc0, 0x00,
   0x00, 0x00, 0x10, 0x40, 0x4a, 0x60, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x2a,
   0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x26, 0x1c, 0x00, 0x00, 0x00, 0x00,
   0x0f, 0x13, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcb, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xf0, 0xea, 0x03, 0x00, 0x00, 0x00, 0x00, 0x38,
   0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xae, 0xaa, 0x0e, 0x00, 0x00, 0x00,
   0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0xab, 0xaa, 0x1a, 0x00,
   0x00, 0x00, 0xc0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xc0, 0xaa, 0xaa,
   0xea, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xb0,
   0xaa, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0xc0, 0x07, 0x00,
   0x00, 0xac, 0xaa, 0xaa, 0xaa, 0x0e, 0x00, 0x00, 0x02, 0x00, 0x00, 0xe0,
   0x1f, 0x00, 0x00, 0xab, 0xaa, 0xaa, 0xaa, 0x3a, 0x00, 0x80, 0x00, 0x00,
   0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x2a, 0xaa, 0xaa, 0xba, 0xea, 0x00, 0x20,
   0x80, 0x07, 0x00, 0xf8, 0xff, 0x01, 0xb0, 0xeb, 0xac, 0xaa, 0xb6, 0xaa,
   0x03, 0xf8, 0xff, 0x3b, 0x00, 0xfe, 0xff, 0x07, 0xac, 0xaa, 0xe6, 0xea,
   0xab, 0xaa, 0x0e, 0xfc, 0xff, 0x07, 0x7f, 0xfc, 0xff, 0x0f, 0xaa, 0xaa,
   0x0a, 0x00, 0xac, 0xaa, 0x1a, 0xfe, 0xff, 0x1f, 0x00, 0xfc, 0xff, 0x1f,
   0xaa, 0xaa, 0x1a, 0x00, 0xac, 0xaa, 0x3a, 0xff, 0xff, 0x1f, 0x00, 0xfe,
   0xff, 0x3f, 0xa9, 0xaa, 0x2a, 0x00, 0xaa, 0xaa, 0x2a, 0xff, 0xff, 0x3f,
   0x00, 0xfe, 0xff, 0x3f, 0xa9, 0xaa, 0x2a, 0x00, 0xaa, 0xaa, 0x2a, 0xff,
   0xff, 0x3f, 0x00, 0xfe, 0xff, 0x3f, 0xaa, 0xaa, 0x1a, 0x00, 0xaa, 0xaa,
   0x3a, 0xfe, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x1f, 0xae, 0xaa, 0x1a, 0x00,
   0xac, 0xaa, 0x1a, 0xfc, 0xff, 0x0f, 0x7f, 0xfc, 0xff, 0x1f, 0xac, 0xaa,
   0xca, 0xab, 0xa9, 0xaa, 0x0e, 0xf8, 0xff, 0x37, 0x00, 0xf6, 0xff, 0x07,
   0xb0, 0xaa, 0xbe, 0xaa, 0xbe, 0xaa, 0x03, 0xe0, 0xff, 0x0f, 0x00, 0xe0,
   0xff, 0x01, 0xc0, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0x00, 0x80, 0xff, 0x03,
   0x00, 0x00, 0x60, 0x00, 0x00, 0xab, 0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00,
   0xfe, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0xbc, 0xaa, 0xaa, 0xaa, 0x0e,
   0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xb0, 0xaa, 0xaa,
   0xaa, 0x03, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0,
   0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x60, 0x00, 0x00,
   0x00, 0x00, 0xab, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10,
   0x00, 0x00, 0x00, 0x00, 0xac, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x28,
   0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xaa, 0x03, 0x00, 0x00, 0x00,
   0x00, 0x80, 0xff, 0x00, 0x00, 0x00 };

screenshot_2

By calling gfx.drawXbm with the appropriate variables (horizontal placement,vertical placement, width, height, xbm data) the logo is now on the screeen as well!

Had a blast working with this kit and learning more about e-displays. This project and some others are on my blog @ https://arejay.codes if you’d like more information on this or other projects.

pictures


#2

Nice!! Would like this multiple times if I could. @jacob.salmela Good for a link?


#3

Definitely. I already had it in mind to throw it on our GitHub README. Pretty awesome @arejay!