Compare commits

...

10 Commits

Author SHA1 Message Date
Tanner 38af4b3c7c Ignore aider 2026-06-13 16:30:19 -06:00
Tanner ae83f8e562 Pull data from stats API vestaboard 2025-10-06 01:25:21 +01:00
Tanner 3339bd07a2 Untrack .pyc files 2025-10-06 01:23:34 +01:00
Tanner 3f42c61352 Add gitignore 2025-10-06 01:23:11 +01:00
Tanner 66398d4359 Merge 2025-10-06 00:52:52 +01:00
tanner 9718807fb7 Rename protosign to protoboard 2025-09-28 17:29:18 -06:00
tanner fd4bc64587 fix: Encode message to UTF-8 for sign compatibility
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
2025-09-28 17:17:01 -06:00
tanner 4ac47db102 feat: Add API polling for dynamic sign display
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
2025-09-28 17:12:22 -06:00
tanner 8b4357c5fc feat: Add protosign script with send_sign for Vestaboard
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
2025-09-28 17:03:19 -06:00
tanner 49c043f6d6 feat: Add protosign.py for protocol signing 2025-09-28 17:03:17 -06:00
5 changed files with 229 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
# Python
# ======
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# node / npm / yarn
# =================
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor
*.swp
*.swo
# Firmware
# =======
# ESP-IDF
sdkconfig
sdkconfig.old
# Custom
# ======
data/
secrets.py
secrets.h
*.bin
output.*
out.*
*.csv
*.txt
*.json
.aider*
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from vestactrl import setup_digits, board_init_uart
import textwrap
import urllib2
import json
import time
def send_sign(text):
"""
Wraps and sends text to the Vestaboard.
"""
COLS = 22
ROWS = 6
# Wrap text to fit the board's width.
lines = textwrap.wrap(text, width=COLS)
# Truncate if the message is too long for the board's height.
if len(lines) > ROWS:
lines = lines[:ROWS]
special_chars = {
' ': '`0',
'\\w': '`1', # white
'\\r': '`2', # red
'\\o': '`3', # orange
'\\y': '`4', # yellow
'\\g': '`5', # green
'\\b': '`6', # blue
'\\v': '`7', # violet
'\\d': '`8', # degree
# '`9', # also degree
}
for code, color in special_chars.items():
lines = [line.replace(code, color) for line in lines]
# setup_digits handles displaying the lines on the board.
# It will also vertically center the block of text.
try:
setup_digits(lines, left_to_right_swap=False, real_hw=True)
except BaseException as e:
print "Error setting digits:" + str(e)
def poll_and_display():
"""
Polls the Protospace API and displays the sign message.
"""
last_message = ""
url = 'https://api.my.protospace.ca/stats/'
while True:
try:
response = urllib2.urlopen(url)
data = json.load(response)
message = data.get('vestaboard')
if message and message != last_message:
print "Updating sign with new message: " + message
send_sign(message.encode('utf-8'))
last_message = message
except (urllib2.URLError, ValueError, KeyError) as e:
print "Error: {}".format(e)
time.sleep(5)
if __name__ == '__main__':
# Initialize communication with the board.
board_init_uart()
poll_and_display()
BIN
View File
Binary file not shown.