Skip to content

Commit

Permalink
Add tagesschau news function, switch to pio
Browse files Browse the repository at this point in the history
  • Loading branch information
linusheck committed Jun 13, 2021
1 parent 688f75d commit c40ca21
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 63 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
esp_sketch/.pio/
1 change: 1 addition & 0 deletions esp_sketch/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.pio
13 changes: 13 additions & 0 deletions esp_sketch/extra_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Import("env")

import subprocess
from os.path import expanduser, join

home = expanduser("~")
esptool = join(home, ".platformio", "packages", "tool-esptoolpy", "esptool.py")

def on_upload(source, target, env):
file = str(source[0])
subprocess.run(["python", esptool, "write_flash", "-z", "0x00000", file])

env.Replace(UPLOADCMD=on_upload)
39 changes: 39 additions & 0 deletions esp_sketch/include/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

This directory is intended for project header files.

A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.

```src/main.c

#include "header.h"

int main (void)
{
...
}
```

Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.

In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.

Read more about using header files in official GCC documentation:

* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes

https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
46 changes: 46 additions & 0 deletions esp_sketch/lib/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.

The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").

For example, see a structure of the following two libraries `Foo` and `Bar`:

|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c

and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>

int main (void)
{
...
}

```

PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.

More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html
23 changes: 23 additions & 0 deletions esp_sketch/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp01]
platform = espressif8266
board = esp01
framework = arduino
lib_deps =
ESP8266WiFi
ESP8266WebServer
ESP8266HTTPClient
DNSServer
base64
https://github.com/tzapu/WiFiManager.git
upload_port = /dev/ttyUSB*
extra_scripts = post:extra_script.py
8 changes: 8 additions & 0 deletions esp_sketch/src/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#define STYLE "<style>body { font-family: monospace; background: beige; } button {border: 0; background-color: #000; color: #fff; line-height: 2.4rem; font-size: 1.2rem; width: 100%; font-family: monospace; } </style>"
#define PARAGRAPH "<p>Der tolle Gedichtedrucker</p>"
#define BACKEND_URL "poems.linus.space"
#define WIFI_NAME "Gedichtedrucker" // name of your settings WiFi hotspot
#define OPENWEATHERMAP_ID String("3247449") // OpenWeatherMap location id
#define OPENWEATHERMAP_UNITS String("metric") // OpenWeatherMap units
#define OPENWEATHERMAP_LANG String("de") // OpenWeatherMap language

115 changes: 52 additions & 63 deletions esp_sketch.ino → esp_sketch/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,40 +1,5 @@
#include <ESP8266WiFi.h>

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "SoftwareSerial.h"
#include <WiFiManager.h>

#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>

#include <base64.hpp>

// SORRY NOT SORRY FOR THIS CODE.

#define TX_PIN 5 // Arduino transmit YELLOW WIRE labeled RX on printer
#define RX_PIN 4 // Arduino receive GREEN WIRE labeled TX on printer

SoftwareSerial printerSerial(RX_PIN, TX_PIN);
WiFiManager wifiManager;

#define HEIGHT 24
#define WIDTH 48 // bytes
#define CHUNK_SIZE HEIGHT * WIDTH
String chunkSizeString = String(CHUNK_SIZE);

#define simplePrint(x) wakeUp(); printerSerial.print((char) 10); printerSerial.println(x); printerSerial.print((char) 10); printerSerial.print((char) 10);
#define STYLE "<style>body { font-family: monospace; background: beige; } button {border: 0; background-color: #000; color: #fff; line-height: 2.4rem; font-size: 1.2rem; width: 100%; font-family: monospace; } </style>"
#define PARAGRAPH "<p>SLOGAN OF YOUR PROJECT</p>"

// Have not tested this after inserting templates. If something doesn't work it's maybe because of these lines
const String BACKEND_URL = String("your.backend.url");
#define WIFI_NAME "" // name of your WiFi network
const String OPENWEATHERMAP_ID = String(""); // OpenWeatherMap location id
const String OPENWEATHERMAP_UNITS = String("metric"); // OpenWeatherMap units
const String OPENWEATHERMAP_LANG = String("en"); // OpenWeatherMap language

boolean wifiNotFound = false;
#include "main.h"
#include "config.h"

void setup() {
pinMode(12, OUTPUT);
Expand All @@ -57,34 +22,54 @@ void setup() {

void configModeCallback(WiFiManager *manager) {
wifiNotFound = true;
simplePrint(F("Did not found WiFi\nnetwork! Please\nconfigure it."));
simplePrint(F("Did not find WiFi network!\nPlease configure it."));
}

void loop() {
if (digitalRead(13) == LOW) {
uint64_t m = millis();
uint64_t debounceDelay = 50;
uint64_t lastDebounceTime = millis();
bool lastDebounceReading = LOW;
while (true) {
bool reading = digitalRead(13);

if (reading != lastDebounceReading) {
lastDebounceTime = millis();
lastDebounceReading = reading;
}
// We model the double / triple click using a state machine
// no click -> click -> double click -> triple click
static uint8_t state = NO_CLICK;
static uint64_t lastClick = millis();
static bool currentlyPressing = false;

static uint64_t debounceDelay = 50;
static uint64_t lastDebounceTime = millis();
static bool lastDebounceReading = HIGH;
bool reading = digitalRead(13);

if (reading != lastDebounceReading) {
lastDebounceTime = millis();
lastDebounceReading = reading;
}

if ((millis() - lastDebounceTime) > debounceDelay && reading == HIGH) {
uint64_t interval = millis() - m;
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading == LOW && !currentlyPressing) {
if (state < TRIPLE_CLICK) {
lastClick = millis();
state++;
currentlyPressing = true;
}
} else if (reading == HIGH) {
currentlyPressing = false;
if (state > NO_CLICK && (millis() - lastClick) > 1000) {
// PRINT
wakeUp();
setPrintingSpeed();
if (interval > 1000) {
printWeather();
} else {
printPoem();
switch (state) {
case NO_CLICK:
break;
case CLICK:
printPoem();
break;
case DOUBLE_CLICK:
printWeather();
break;
case TRIPLE_CLICK:
printNews();
break;
}
goToSleep();
break;
state = NO_CLICK;
}
}
}
Expand Down Expand Up @@ -123,7 +108,7 @@ void printPoem() {

// First of all, get the poem's name
String poemName;
if (http.begin(client, "http://" + BACKEND_URL + "/name")) {
if (http.begin(client, String("http://") + BACKEND_URL + "/name")) {
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
poemName = http.getString();
Expand All @@ -137,6 +122,10 @@ void printWeather() {
print("weather?id=" + OPENWEATHERMAP_ID + "&units=" + OPENWEATHERMAP_UNITS + "&lang=" + OPENWEATHERMAP_LANG);
}

void printNews() {
print("news?time=" + String(millis()));
}

void print(String name) {
WiFiClient client;
HTTPClient http;
Expand All @@ -152,22 +141,22 @@ void print(String name) {

String posString = String(pos);
// Now, print it chunk by chunk
if (http.begin(client, "http://" + BACKEND_URL + "/" + name +
"&length=" + chunkSizeString + "&from=" + pos)) {
if (http.begin(client, String("http://") + BACKEND_URL + "/" + name +
"&length=" + chunkSizeString + "&from=" + pos)) {
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String content = http.getString();
length = content.substring(0, content.indexOf("\n")).toInt();
String base64 = content.substring(content.indexOf("\n") + 1);

char src[base64.length()];
base64.toCharArray(src, base64.length());
unsigned char binary[CHUNK_SIZE];

for (int i = 0; i < CHUNK_SIZE; i++) {
binary[i] = 0;
}

decode_base64((unsigned char*) src, binary);

for (int i = 0; i < CHUNK_SIZE; i++) {
Expand All @@ -181,4 +170,4 @@ void print(String name) {
for (int i = 0; i < 4; i++) {
printerSerial.print((char) 10);
}
}
}
47 changes: 47 additions & 0 deletions esp_sketch/src/main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef MAIN_H
#define MAIN_H

#include <ESP8266WiFi.h>

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "SoftwareSerial.h"
#include <WiFiManager.h>

#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>

#include <base64.hpp>
#include <Arduino.h>

void setup();
void loop();
void configModeCallback(WiFiManager *manager);
void wakeUp();
void goToSleep();
void setPrintingSpeed();
void printPoem();
void printWeather();
void printNews();
void print(String name);

#define TX_PIN 5 // Arduino transmit YELLOW WIRE labeled RX on printer
#define RX_PIN 4 // Arduino receive GREEN WIRE labeled TX on printer

SoftwareSerial printerSerial(RX_PIN, TX_PIN);
WiFiManager wifiManager;

#define HEIGHT 24
#define WIDTH 48 // bytes
#define CHUNK_SIZE HEIGHT * WIDTH
String chunkSizeString = String(CHUNK_SIZE);

#define simplePrint(x) wakeUp(); printerSerial.print((char) 10); printerSerial.println(x); printerSerial.print((char) 10); printerSerial.print((char) 10);
boolean wifiNotFound = false;

#define NO_CLICK 0
#define CLICK 1
#define DOUBLE_CLICK 2
#define TRIPLE_CLICK 3

#endif
11 changes: 11 additions & 0 deletions esp_sketch/test/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

This directory is intended for PlatformIO Unit Testing and project tests.

Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.

More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

0 comments on commit c40ca21

Please sign in to comment.