Skip to content

Instantly share code, notes, and snippets.

@yoursunny
Last active February 24, 2021 14:15
Show Gist options
  • Save yoursunny/bf1905b484d2b9049275524cc46c6f1f to your computer and use it in GitHub Desktop.
Save yoursunny/bf1905b484d2b9049275524cc46c6f1f to your computer and use it in GitHub Desktop.
Watch @EmojiTetra Live on ESP32 OLED Display https://yoursunny.com/t/2018/EmojiTetra-OLED/
#!/usr/bin/python3
# Watch @EmojiTetra Live on ESP32 OLED Display
# https://yoursunny.com/t/2018/EmojiTetra-OLED/
import datetime
import re
import twitter
from http.server import HTTPServer, BaseHTTPRequestHandler
twttr = twitter.Api(consumer_key='XXXXXXXXXXXXXXXXXXXXXXXXX',
consumer_secret='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
access_token_key='88888888-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
access_token_secret='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/robots.txt':
self.handleRobotsTxt()
elif self.path == '/emojitetra.txt':
self.handleEmojiTetra()
else:
self.send_response(404)
self.end_headers()
def handleRobotsTxt(self):
self.send_response(200)
self.send_header('Content-Type', 'text/plain')
self.end_headers()
self.wfile.write('User-Agent: *\nDisallow: /\n'.encode('ascii'))
def handleEmojiTetra(self):
timeline = twttr.GetUserTimeline(
screen_name='EmojiTetra', count=5, trim_user=True)
ok = False
for tweet in timeline:
lines = tweet.text.split('\n')
if len(lines) != 11:
continue
ts = datetime.datetime.strptime(
tweet.created_at, '%a %b %d %H:%M:%S %z %Y').replace(tzinfo=None)
since = (datetime.datetime.utcnow() - ts).total_seconds()
score = lines[8][8:].strip()
output = '{}\n{}\n'.format(since, score)
for i, line in enumerate(lines):
for ch in line[:7]:
if ch == '\u25fd':
output += '.'
else:
output += 'X'
output += '\n'
ok = True
break
if not ok:
self.send_response(503)
self.end_headers()
return
self.send_response(200)
self.send_header('Content-Type', 'text/plain')
self.end_headers()
self.wfile.write(output.encode('ascii'))
def run(port=8000):
httpd = HTTPServer(('', port), Handler)
httpd.serve_forever()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='EmojiTetra HTTP server.')
parser.add_argument('--port', type=int, default=8000,
help='listening port number')
args = parser.parse_args()
run(port=args.port)
// Watch @EmojiTetra Live on ESP32 OLED Display
// https://yoursunny.com/t/2018/EmojiTetra-OLED/
#include <HTTPClient.h>
#include <U8g2lib.h> // https://github.com/olikraus/U8g2_Arduino/tree/e4178df6b8c69f1880d6d44719a286540e9e94a5
#include <WiFi.h>
const char* WIFI_SSID = "my-wifi";
const char* WIFI_PASS = "my-password";
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, 15, 4, 16);
void
setup()
{
Serial.begin(115200);
Serial.println();
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.println("WiFi connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(WiFi.status());
}
Serial.println("WiFi OK");
delay(1000);
u8g2.begin();
u8g2.setFont(u8g2_font_helvR08_tf);
u8g2.setDisplayRotation(U8G2_R3);
}
void
display(const String& r)
{
u8g2.clearBuffer();
int pos0 = r.indexOf('\n');
u8g2.drawStr(0, 8, r.substring(0, pos0).c_str());
int pos1 = r.indexOf('\n', pos0 + 1);
u8g2.drawStr(0, 18, r.substring(pos0 + 1, pos1).c_str());
pos0 = pos1 + 1;
for (int i = 0; i < 11; ++i) {
pos1 = r.indexOf('\n', pos0);
for (int j = 0; j < pos1 - pos0; ++j) {
int x = j * 9;
int y = 28 + i * 9;
if (r[pos0 + j] == 'X') {
u8g2.drawBox(x, y, 8, 8);
}
}
pos0 = pos1 + 1;
}
u8g2.sendBuffer();
}
void
loop()
{
Serial.println("HTTP request");
HTTPClient http;
http.begin("http://house-server.example:8000/emojitetra.txt");
int httpCode = http.GET();
Serial.print("HTTP code ");
Serial.println(httpCode);
if (httpCode == 200) {
String payload = http.getString();
Serial.println(payload);
display(payload);
}
http.end();
delay(15000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment