diff --git a/display_test.py b/display_test.py new file mode 100644 index 0000000..0199f1b --- /dev/null +++ b/display_test.py @@ -0,0 +1,9 @@ +import dot3k.lcd as lcd +import st7036 + +# Initialize the LCD with SPI configuration +try: + lcd = st7036.st7036(register_select_pin=25, spi_bus=0, spi_chip_select=0) # Ensure these values match your setup +except Exception as e: + print(f"Failed to initialize Display-O-Tron LCD: {e}") + lcd = None diff --git a/docker/.env.sample b/docker/.env.sample index d6b6759..9abf5aa 100644 --- a/docker/.env.sample +++ b/docker/.env.sample @@ -2,4 +2,5 @@ JAMS_URL=https://jams.jams JAMS_API_TOKEN=your_jams_api_token PG_USER=jolt PG_PASS=jolt -PRINTER_IDENTIFIER=/dev/usb/lp0 \ No newline at end of file +PRINTER_IDENTIFIER=/dev/usb/lp0 +USE_DISPLAY=False \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index 783b5b9..d4c8969 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,8 +1,16 @@ # Use the official Python image from the Docker Hub -FROM python:3.12-slim - -# Install libusb and other USB dependencies -RUN apt-get update && apt-get install -y libusb-1.0-0-dev usbutils +FROM python:3.12 + +# Install system dependencies for USB and GPIO +RUN apt-get update && \ + apt-get install -y \ + libusb-1.0-0-dev \ + usbutils \ + build-essential \ + python3-dev \ + python3-setuptools \ + python3-wheel && \ + rm -rf /var/lib/apt/lists/* # Set the working directory WORKDIR /jolt @@ -19,6 +27,9 @@ COPY ./requirements.txt . # Copy the check_db.py file into the container COPY ./check_db.py . +# Copy the check_db.py file into the container +COPY ./display_test.py . + # Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt @@ -28,8 +39,11 @@ RUN chmod +x entrypoint.sh # Make check_db.py executable RUN chmod +x check_db.py +# Make check_db.py executable +RUN chmod +x display_test.py + # Make port 5000 available to the world outside this container EXPOSE 5000 # Run flask app with gunicorn -CMD ["bash", "entrypoint.sh"] \ No newline at end of file +CMD ["python3", "display_test.py"] \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 8d457e7..0a1258f 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -4,6 +4,7 @@ services: container_name: jolt-server restart: unless-stopped command: ./entrypoint.sh + privileged: true # Only needed if using display ports: - "5000:5000" environment: @@ -11,8 +12,15 @@ services: - JAMS_URL=https://jams.jams - JAMS_API_TOKEN=your_jams_api_token - PRINTER_IDENTIFIER='/dev/usb/lp0' + - USE_DISPLAY=False volumes: - /path/to/db_migrations:/jolt/migrations + # Optional for Display + - /sys/class/gpio:/sys/class/gpio + - /dev/mem:/dev/mem + - /dev/gpiomem:/dev/gpiomem + - /dev/spidev0.0:/dev/spidev0.0 + - /dev/i2c-1:/dev/i2c-1 depends_on: - jolt-db jolt-db: diff --git a/jolt/__init__.py b/jolt/__init__.py index 9930e16..32e5cdf 100644 --- a/jolt/__init__.py +++ b/jolt/__init__.py @@ -7,9 +7,10 @@ from dotenv import load_dotenv from flask import Flask -from jolt.extensions import db, migrate, WSS +from jolt.extensions import db, migrate, WSS, DISPLAY from jolt.routes import bp as routes_bp from jolt.print_queue_handler import PrintQueueHandler +from jolt import helper JAMS_URL = None @@ -36,6 +37,11 @@ def create_app(): JAMS_API_TOKEN = os.getenv('JAMS_API_TOKEN', 'jams_api_token') PRINTER_IDENTIFIER = os.getenv('PRINTER_IDENTIFIER', '/dev/usb/lp0') + use_display = os.getenv('USE_DISPLAY', False) + if use_display: + DISPLAY.init() + DISPLAY.show_text(helper.get_local_ip()) + Http_headers['Authorization'] = JAMS_API_TOKEN # Initialise DB diff --git a/jolt/display.py b/jolt/display.py new file mode 100644 index 0000000..3dd8a0d --- /dev/null +++ b/jolt/display.py @@ -0,0 +1,21 @@ +import dot3k.lcd as lcd +import time + +class Display: + def init(self): + lcd.clear() + + def show_text(self, text): + lcd.clear() + + if len(text) <= 16: + lcd.write(text) + else: + self.scroll_text(text) + + def scroll_text(self, text): + while True: + for i in range(len(text) - 15): + lcd.clear() + lcd.write(text[i:i+16]) + time.sleep(0.2) \ No newline at end of file diff --git a/jolt/extensions.py b/jolt/extensions.py index f67e84d..91baef4 100644 --- a/jolt/extensions.py +++ b/jolt/extensions.py @@ -1,7 +1,9 @@ from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from jolt.websocket_server import WebsocketServer +from jolt.display import Display db = SQLAlchemy() migrate = Migrate() -WSS = WebsocketServer() \ No newline at end of file +WSS = WebsocketServer() +DISPLAY = Display() \ No newline at end of file diff --git a/jolt/helper.py b/jolt/helper.py new file mode 100644 index 0000000..1ea2628 --- /dev/null +++ b/jolt/helper.py @@ -0,0 +1,10 @@ +import socket +import psutil + + +def get_local_ip(): + for interface, addresses in psutil.net_if_addrs().items(): + for address in addresses: + if address.family == socket.AF_INET and not address.address.startswith("127."): + return address.address + return "127.0.0.1" \ No newline at end of file diff --git a/jolt/routes.py b/jolt/routes.py index 53e6066..08ab976 100644 --- a/jolt/routes.py +++ b/jolt/routes.py @@ -4,7 +4,7 @@ bp = Blueprint('routes', __name__) -@bp.route('/') +@bp.route('/test') def test(): success, error = print_image_label('Bot Test', 'Test Event') if success: diff --git a/jolt/websocket_server.py b/jolt/websocket_server.py index f6c3a88..f704c8d 100644 --- a/jolt/websocket_server.py +++ b/jolt/websocket_server.py @@ -4,8 +4,8 @@ from urllib.parse import urlencode import jolt import psutil -import socket from jolt.enums import RequestType +from jolt import helper class WebsocketServer(): def __init__(self): @@ -60,7 +60,7 @@ def process_incoming_message(self, message): ram_usage = memory_info.percent disk_info = psutil.disk_usage('/') disk_usage = disk_info.percent - local_ip = self.get_local_ip() + local_ip = helper.get_local_ip() from jolt import PQH response_body = { @@ -79,13 +79,6 @@ def process_incoming_message(self, message): return None - def get_local_ip(self): - for interface, addresses in psutil.net_if_addrs().items(): - for address in addresses: - if address.family == socket.AF_INET and not address.address.startswith("127."): - return address.address - return "127.0.0.1" - def build_websocket_message(self, type, body): return { 'TYPE': type.name, diff --git a/requirements.txt b/requirements.txt index 2b42d58..bf196a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,8 @@ Flask-Migrate psycopg2-binary psutil requests -gunicorn \ No newline at end of file +gunicorn +RPi.GPIO +dot3k +st7036 +spidev \ No newline at end of file