Skip to content

Commit

Permalink
open up the data source apicast.hiveeyes/beeflight/forecast.
Browse files Browse the repository at this point in the history
and bring it improvised on Screen.
Thanks to amotl.
  • Loading branch information
MKO1640 committed Jun 2, 2020
1 parent a4fbc63 commit 60006e0
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
.venv*
.pio
.vscode
96 changes: 96 additions & 0 deletions lib/apicast/README.rst
@@ -0,0 +1,96 @@
#####################################
Apicast HTTP to Json data export for Arduino
#####################################


*****
About
*****
This code fetches data from the Apicast-Hiveeyes-Platform.
It converts data from the bee flight forecast of the German Weather Service (DWD)into the .Json format
Manny Thanks to Andreas Mot

Example of the API:
http://apicast.hiveeyes.org/beeflight/forecast/germany/berlin_brandenburg/potsdam

available locations for the forecast:

baden-wuerttemberg, Baden-Württemberg
freudenstadt, Freudenstadt im Schwarzwald
konstanz, Konstanz am Bodensee
lahr, Lahr
mannheim, Mannheim
oehringen, Öhringen
rheinstetten, Rheinstetten
stoetten, Stötten (Geislingen an der Steige)
stuttgart, Stuttgart (Flughafen)
bayern, Bayern
augsburg, Augsburg
bamberg, Bamberg
fuerstenzell, Fürstenzell
hof, Hof
hohenpeissenberg, Hohenpeißenberg
kempten, Kempten (Allgäu)
muenchen, München (Flughafen)
nuernberg, Nürnberg (Flughafen)
oberstdorf, Oberstdorf (Allgäu)
regensburg, Regensburg
straubing, Straubing
weiden, Weiden in der Oberpfalz
wuerzburg, Würzburg
berlin_brandenburg, Berlin und Brandenburg
angermuende, Angermünde
berlin, Berlin-Tempelhof
cottbus, Cottbus
lindenberg, Lindenberg (Tauche)
neuruppin, Neuruppin
potsdam, Potsdam
hessen, Hessen
frankfurt, Frankfurt/Main (Flughafen)
fritzlar, Fritzlar
offenbach, Offenbach/Main (Wetterpark)
wasserkuppe, Wasserkuppe
wettenberg, Wettenberg bei Gießen
mecklenburg-vorpommern, Mecklenburg-Vorpommern
arkona, Arkona (Putgarten)
greifswald, Greifswald
marnitz, Marnitz
rostock, Rostock-Warnemünde
schwerin, Schwerin
niedersachsen_bremen, Niedersachsen und Bremen
bremen, Bremen (Flughafen)
cuxhaven, Cuxhaven
emden, Emden
hannover, Hannover (Flughafen)
norderney, Norderney
nordrhein-westfalen, Nordrhein-Westfalen
aachen, Aachen-Orsbach
lippspringe, Bad Lippspringe
duesseldorf, Düsseldorf (Flughafen)
greven, Greven (Flughafen Münster/Osnabrück)
kahler_asten, Kahler Asten (Winterberg)
koeln, Köln (Flughafen Köln/Bonn)
rheinland-pfalz_saarland, Rheinland-Pfalz und Saarland
hahn, Hahn (Flughafen)
nuerburg, Nürburg-Barweiler
saarbruecken, Saarbrücken (Flughafen)
trier, Trier-Petrisberg
sachsen, Sachsen Sachsen-Anhalt
dresden, Dresden (Flughafen)
goerlitz, Görlitz
leipzig, Leipzig (Flughafen Leipzig/Halle)
sachsen-anhalt, Sachsen-Anhalt
magdeburg, Magdeburg
schleswig-holstein_hamburg, Schleswig-Holstein und Hamburg
fehmarn, Fehmarn
hamburg, Hamburg (Flughafen)
helgoland, Helgoland
kiel, Kiel-Holtenau
list, List auf Sylt
schleswig, Schleswig
thueringen, Thüringen
erfurt, Erfurt (Flughafen Erfurt-Weimar)
gera, Gera
meiningen, Meiningen


71 changes: 71 additions & 0 deletions lib/apicast/apicast_client.h
@@ -0,0 +1,71 @@
#ifndef APICAST_CLIENT_H_
#define APICAST_CLIENT_H_

#include <Arduino.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>

bool decode_beeflight(WiFiClient& json) {

// Allocate the JsonDocument
DynamicJsonDocument doc(5 * 1024);

// Deserialize the JSON document.
DeserializationError error = deserializeJson(doc, json);

// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return false;
}

Serial.println(" Decoding Apicast data");

JsonArray data = doc["data"];
int api_readings = data.size();

for (int i = 0; i < api_readings; i++) {

JsonObject reading = data[i];

beeflight[i].date = reading["Datum"].as<char*>();
beeflight[i].morning = reading["morgens"].as<char*>();
beeflight[i].noon = reading["mittags"].as<char*>();
beeflight[i].evening = reading["abends"].as<char*>();
}

return true;
}

bool obtain_apicast_data(WiFiClient& client) {

// Define URI.
// https://getkotori.org/docs/handbook/export/
HTTPClient http;
http.useHTTP10(true);
String server = apicast_server;

// TODO: Improve Kotori by requesting only last reading.
String uri = apicast_uri;

// Make HTTP request.
//http.begin(uri, test_root_ca); // HTTPS example connection
bool success;
http.begin(client, server, 80, uri);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
if (!decode_beeflight(http.getStream())) return false;
success = true;
Serial.println("Connection Apicast OK");
} else {
Serial.printf("Connection failed, error: %s", http.errorToString(httpCode).c_str());
success = false;
}

client.stop();
http.end();
return success;
}

#endif /* ifndef APCAST_CLIENT_H_ */
13 changes: 13 additions & 0 deletions lib/apicast/apicast_record.h
@@ -0,0 +1,13 @@
#ifndef APICAST_RECORD_H_
#define APICAST_RECORD_H_

#include <Arduino.h>

typedef struct {
String date;
String morning;
String noon;
String evening;
} Apicast_record_type;

#endif /* ifndef APICAST_RECORD_H_ */
67 changes: 44 additions & 23 deletions src/hiveeyes-epaper.ino
Expand Up @@ -30,6 +30,7 @@
#include "epaper_fonts.h"
#include "forecast_record.h"
#include "hive_record.h"
#include "apicast_record.h"
//#include "lang.h"
//#include "lang_cz.h" // Localisation (Czech)
//#include "lang_fr.h" // Localisation (French)
Expand Down Expand Up @@ -79,8 +80,8 @@ String version = "12.3"; // Version of this program
//################ VARIABLES ###########################

boolean LargeIcon = true, SmallIcon = false;
#define Large 11 // For icon drawing, needs to be odd number for best effect
#define Small 5 // For icon drawing, needs to be odd number for best effect
#define Large 8 // For icon drawing, needs to be odd number for best effect
#define Small 4 // For icon drawing, needs to be odd number for best effect
String time_str, date_str; // strings to hold time and received weather data
int wifi_signal, CurrentHour = 0, CurrentMin = 0, CurrentSec = 0;
long StartTime = 0;
Expand All @@ -97,6 +98,8 @@ int hive_readings;
Hive_record_type hive_data[max_readings_hiveeyes];
#include "hiveeyes_client.h"

Apicast_record_type beeflight[10];
#include "apicast_client.h"

#define autoscale_on true
#define autoscale_off false
Expand Down Expand Up @@ -138,7 +141,7 @@ void setup() {
// Obtain hive information.
Serial.println("get hiveeye Data");
obtain_hiveeyes_data(client);

obtain_apicast_data(client);
// Display data.
if (RxWeather && RxForecast) { // Only if received both Weather or Forecast proceed
StopWiFi(); // Reduces power consumption
Expand Down Expand Up @@ -176,6 +179,7 @@ void DisplayWeather() { // 4.2" e-paper display is 400x300 resol
if (WxConditions[0].Cloudcover > 0) CloudCover(350, 125, WxConditions[0].Cloudcover);
DrawAstronomySection(233, 74); // Astronomy section Sun rise/set, Moon phase and Moon icon
DrawHiveeyesSection(187); // DrawHiveeyesSection(y) Draw Hiveeyes Selection over full Screen size
DrawBeeflightSection(170, 233);
}
//#########################################################################################
void DrawHeadingSection() {
Expand All @@ -187,12 +191,29 @@ void DrawHeadingSection() {
DrawRSSI(97,10, wifi_signal);
display.drawLine(0, 12, SCREEN_WIDTH, 12, GxEPD_BLACK);
}
//#########################################################################################
void DrawBeeflightSection(int x, int y) {
u8g2Fonts.setFont(u8g2_font_helvB08_tf);
drawString(x, y, "morgens" , RIGHT);
drawString(x, y+10, beeflight[0].morning, RIGHT);
drawString(x, y+20, beeflight[1].morning, RIGHT);
drawString(x, y+30, beeflight[2].morning, RIGHT);
drawString(x+45, y, "mittags" , RIGHT);
drawString(x+45, y+10, beeflight[0].noon, RIGHT);
drawString(x+45, y+20, beeflight[1].noon, RIGHT);
drawString(x+45, y+30, beeflight[2].noon, RIGHT);
drawString(x+90, y, "abends" , RIGHT);
drawString(x+90, y+10, beeflight[0].evening, RIGHT);
drawString(x+90, y+20, beeflight[1].evening, RIGHT);
drawString(x+90, y+30, beeflight[2].evening, RIGHT);
}

//#########################################################################################
void DrawMainWeatherSection(int x, int y) {
DisplayDisplayWindSection(x - 115, y - 3, WxConditions[0].Winddir, WxConditions[0].Windspeed, 40);
DisplayDisplayWindSection(x - 130, y - 20, WxConditions[0].Winddir, WxConditions[0].Windspeed, 25);
DisplayWXicon(x + 5, y - 5, WxConditions[0].Icon, LargeIcon);
u8g2Fonts.setFont(u8g2_font_helvB10_tf);
DrawPressureAndTrend(x - 120, y + 58, WxConditions[0].Pressure, WxConditions[0].Trend);
DrawPressureAndTrend(x - 140, y + 28, WxConditions[0].Pressure, WxConditions[0].Trend);
u8g2Fonts.setFont(u8g2_font_helvB12_tf);
String Wx_Description = WxConditions[0].Forecast0;
if (WxConditions[0].Forecast1 != "") Wx_Description += " & " + WxConditions[0].Forecast1;
Expand Down Expand Up @@ -225,7 +246,7 @@ void DrawForecastSection(int x, int y) {
//u8g2Fonts.setFont(u8g2_font_helvB10_tf);
//DrawGraph(SCREEN_WIDTH / 400 * 30, SCREEN_HEIGHT / 300 * 221, SCREEN_WIDTH / 4, SCREEN_HEIGHT / 5, 900, 1050, Units == "M" ? TXT_PRESSURE_HPA : TXT_PRESSURE_IN, pressure_readings, max_readings, autoscale_on, barchart_off);
//DrawGraph(SCREEN_WIDTH / 400 * 158, SCREEN_HEIGHT / 300 * 221, SCREEN_WIDTH / 4, SCREEN_HEIGHT / 5, 10, 30, Units == "M" ? TXT_TEMPERATURE_C : TXT_TEMPERATURE_F, temperature_readings, max_readings, autoscale_on, barchart_off);
//DrawGraph(SCREEN_WIDTH / 400 * 288, SCREEN_HEIGHT / 300 * 221, SCREEN_WIDTH / 4, SCREEN_HEIGHT / 5, 0, 30, TXT_HUMIDITY_PERCENT, rain_readings, max_readings, autoscale_on, barchart_on);
DrawGraph(SCREEN_WIDTH / 400 * 288, SCREEN_HEIGHT / 300 * 221, SCREEN_WIDTH / 4, SCREEN_HEIGHT / 5, 0, 30, TXT_HUMIDITY_PERCENT, rain_readings, max_readings, autoscale_on, barchart_on);
}
//#########################################################################################
void DrawForecastWeather(int x, int y, int index) {
Expand All @@ -247,8 +268,8 @@ void DrawHiveeyesSection( int y) {
u8g2Fonts.setFont(u8g2_font_helvB12_tf);
drawString(SCREEN_WIDTH / 6, y + 6, "Hive1", CENTER);
u8g2Fonts.setFont(u8g2_font_helvB08_tf);
DrawBattery1(-5,y+29, hive_data[hive_readings-1].voltage ,3.0 ,4.0 );
DrawRSSI(64, y+27, hive_data[hive_readings-1].rssi);
DrawBattery1(-9,y+16, hive_data[hive_readings-1].voltage ,3.0 ,4.0 );
DrawRSSI(106, y+14, hive_data[hive_readings-1].rssi);
//Too Do! make void for Temp. Check all temp for Max and
u8g2Fonts.setFont(FONT(u8g2_font_helvB10));
drawString(120, y + 37, String(hive_data[2].temperature_inside_1, 1) + "°C", RIGHT);
Expand Down Expand Up @@ -278,7 +299,7 @@ void DrawRSSI(int x, int y, int rssi) {
xpos++;
}
display.fillRect(x, y - 1, 5, 1, GxEPD_BLACK);
drawString(x + 41, y - 8, String(rssi) + "dBm", CENTER);
//drawString(x + 41, y - 8, String(rssi) + "dBm", CENTER);
}
//#########################################################################################
void DrawBattery1(int x, int y, float voltage, float emptyV , float fullV) {
Expand All @@ -290,7 +311,7 @@ void DrawBattery1(int x, int y, float voltage, float emptyV , float fullV) {
display.fillRect(x + 34, y - 10, 2, 5, GxEPD_BLACK);
display.fillRect(x + 17, y - 10, 15 * percentage / 100.0, 6, GxEPD_BLACK);
//drawString(x + 62, y - 11, String(percentage) + "%", RIGHT);
drawString(x + 52, y -11, String(voltage, 2) + "V", CENTER);
//drawString(x + 52, y -11, String(voltage, 2) + "V", CENTER);
}
//#########################################################################################
void DrawMainWx(int x, int y) {
Expand All @@ -309,30 +330,30 @@ void DisplayDisplayWindSection(int x, int y, float angle, float windspeed, int C
int dxo, dyo, dxi, dyi;
display.drawLine(0, 15, 0, y + Cradius + 30, GxEPD_BLACK);
display.drawCircle(x, y, Cradius, GxEPD_BLACK); // Draw compass circle
display.drawCircle(x, y, Cradius + 1, GxEPD_BLACK); // Draw compass circle
display.drawCircle(x, y, Cradius * 0.7, GxEPD_BLACK); // Draw compass inner circle
display.drawCircle(x, y, Cradius - 3, GxEPD_BLACK); // Draw compass circle
//display.drawCircle(x, y, Cradius * 0.7, GxEPD_BLACK); // Draw compass inner circle
for (float a = 0; a < 360; a = a + 22.5) {
dxo = Cradius * cos((a - 90) * PI / 180);
dyo = Cradius * sin((a - 90) * PI / 180);
if (a == 45) drawString(dxo + x + 10, dyo + y - 10, TXT_NE, CENTER);
if (a == 135) drawString(dxo + x + 7, dyo + y + 5, TXT_SE, CENTER);
if (a == 225) drawString(dxo + x - 15, dyo + y, TXT_SW, CENTER);
if (a == 315) drawString(dxo + x - 15, dyo + y - 10, TXT_NW, CENTER);
dxi = dxo * 0.9;
dyi = dyo * 0.9;
display.drawLine(dxo + x, dyo + y, dxi + x, dyi + y, GxEPD_BLACK);
dxo = dxo * 0.7;
dyo = dyo * 0.7;
//if (a == 45) drawString(dxo + x + 10, dyo + y - 10, TXT_NE, CENTER);
//if (a == 135) drawString(dxo + x + 7, dyo + y + 5, TXT_SE, CENTER);
//if (a == 225) drawString(dxo + x - 15, dyo + y, TXT_SW, CENTER);
//if (a == 315) drawString(dxo + x - 15, dyo + y - 10, TXT_NW, CENTER);
dxi = dxo * 0.9;
dyi = dyo * 0.9;
display.drawLine(dxo + x, dyo + y, dxi + x, dyi + y, GxEPD_BLACK);
//dxo = dxo * 0.7;
//dyo = dyo * 0.7;
//dxi = dxo * 0.9;
//dyi = dyo * 0.9;
//display.drawLine(dxo + x, dyo + y, dxi + x, dyi + y, GxEPD_BLACK);
}
drawString(x, y - Cradius - 10, TXT_N, CENTER);
drawString(x, y + Cradius + 5, TXT_S, CENTER);
drawString(x - Cradius - 10, y - 3, TXT_W, CENTER);
drawString(x + Cradius + 8, y - 3, TXT_E, CENTER);
drawString(x - 2, y - 20, WindDegToDirection(angle), CENTER);
drawString(x + 3, y + 12, String(angle, 0) + "°", CENTER);
//drawString(x - 2, y - 18, WindDegToDirection(angle), CENTER);
//drawString(x + 3, y + 12, String(angle, 0) + "°", CENTER);
drawString(x + 3, y - 3, String(windspeed, 1) + (Units == "M" ? "m/s" : "mph"), CENTER);
}
//#########################################################################################
Expand Down
18 changes: 15 additions & 3 deletions src/hiveeyes_config.h
Expand Up @@ -14,8 +14,20 @@ String ReadingVoltage = "system.battery-voltage";
String ReadingWeight = "weight.0";
String ReadingRssi = "system.wifi.rssi";

// build uri complete
String hiveeyes_uri = uri + "?include="+ ReadingTemperature_outside + ","

//This Config is to get forecast beeflight Data from http://apicast.hiveeyes.org/

String apicast_server = "apicast.hiveeyes.org";
String apicast_uri_1 = "/beeflight/forecast/germany/";
// federal-state and Station
String apicast_uri_2 = "berlin_brandenburg/berlin";




// build uri´s complete please no Changes here!!!
String apicast_uri = apicast_uri_1 + apicast_uri_2;
String hiveeyes_uri = uri + "?include=" + ReadingTemperature_outside + ","
+ ReadingHumidity_outside + ","
+ ReadingTemperature_inside_1 + ","
+ ReadingTemperature_inside_2 + ","
Expand All @@ -25,4 +37,4 @@ String hiveeyes_uri = uri + "?include="+ ReadingTemperature_outside + ","
+ ReadingVoltage + ","
+ ReadingWeight + ","
+ ReadingRssi;

0 comments on commit 60006e0

Please sign in to comment.