diff --git a/config-server.dockerfile b/config-server.dockerfile index 15ed6c9d..fd855835 100644 --- a/config-server.dockerfile +++ b/config-server.dockerfile @@ -28,4 +28,4 @@ RUN python3 -m pip install -v \ # prep app code WORKDIR /code COPY . . -CMD ["python3", "config_webserver.py"] \ No newline at end of file +CMD ["python3", "src/config_webserver.py"] \ No newline at end of file diff --git a/config_webserver.py b/config_webserver.py deleted file mode 100644 index 7e6eaa2f..00000000 --- a/config_webserver.py +++ /dev/null @@ -1,3 +0,0 @@ -from src.config_server.server import app - -app.run(debug=True, host='0.0.0.0', port=8080) diff --git a/docker-compose.yml b/docker-compose.yml index d3176c33..cd014300 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ volumes: services: bitbot: - platform: linux/arm64/v7 + #platform: linux/arm64/v7 privileged: true restart: unless-stopped network_mode: "host" # alows us to show IP address @@ -23,7 +23,7 @@ services: # - BITBOT_OUTPUT=disk, waveshare.epd2in7b_V2, inky config-editor: - platform: linux/arm64/v7 + #platform: linux/arm64/v7 restart: unless-stopped build: dockerfile: config-server.dockerfile diff --git a/docs/app_install.md b/docs/app_install.md index 0da45565..324c7a4a 100644 --- a/docs/app_install.md +++ b/docs/app_install.md @@ -57,8 +57,8 @@ Test the app python3 -m run ``` -Add cron jobs to start the [app](/run.py) and [config-server](/src/configuration/config_webserver.py) after reboot +Add cron jobs to start the [app](/run.py) and [config-server](/src/config_webserver.py) after reboot ```sh (crontab -l 2>/dev/null; echo "@reboot sleep 30 && cd /home/pi/bitbot && python3 run.py") | crontab - -(crontab -l 2>/dev/null; echo "@reboot sleep 30 && cd /home/pi/bitbot && python3 src/configuration/config_webserver.py") | crontab - +(crontab -l 2>/dev/null; echo "@reboot sleep 30 && cd /home/pi/bitbot && python3 src/config_webserver.py") | crontab - ``` diff --git a/docs/device_usage.md b/docs/device_usage.md index eb26931c..c0901bac 100644 --- a/docs/device_usage.md +++ b/docs/device_usage.md @@ -1,34 +1,38 @@ -# 📈 How to configure your new crypto-watcher +# 📈 Configure your **Crypto Watcher** + +## Physical setup 1. Remove the screen protector that is covering the e-paper display (there is a red tab at the bottom-left) -2. **Connect a micro-usb** cable 🔌 to the raspberry pi board on your crypto-watcher -3. **Wait a minute** ⌚ or so for it to boot up -4. The device will display a short **intro sequence** 📺 for you to follow -5. From another device, **connect** to the `bitbot-{nnn}` access point - - ⚠️ on mobile decives, you may need to disable mobile data here -6. if you are not automaticaly shown the config web page, open your browser and goto google.com. the page should then load. +1. **Connect a micro-usb** cable 🔌 to the raspberry pi board on your crypto-watcher +1. **Wait a minute** ⌚ or so for it to boot up + +## First tine setup +1. A short **intro sequence** 📺 may be displayed (this only happens once) +1. From another device, *connect* to the `bitbot-{nnn}` **wifi access point** + - ⚠️ on **mobile decives**, you may need to **disable mobile data here** +1. if you are not automaticaly shown the config web page, open your browser and goto google.com. the page should then load. - ⚠️ if this fails please use `http://10.41.0.1` in the browser url -7. Select your home **wifi access point name** 🛜 -8. Enter your **wifi password** 🙈 -9. **Wait** for the device to reboot ♻️ (this may take 1-2 mins) +1. Select your **home wifi access point name** 🛜 +1. Enter your **wifi password** 🙈 +1. **Wait** for the device to reboot ♻️ (this may take 1-2 mins) * you many need to go **back to #5, or restart** the device if there's no action within **5 minutes** * Your crypto-watcher will **refresh** the screen once it has **loaded up and connected** to the internet. - * The device is set up to **refresh** every **ten minutes**. - * The dispayed instrument defaults to **Bitmex BTC/USD**. + * The device is set up to **refresh** every **thirty minutes**. + * The dispayed instrument defaults to **Coinbase BTC/USD**. > More detailed [instructions with screenshots can be found here](wifi_setup.md) # ⚙️ Advanced Configuration -### Configuration for your crypto-watcher is stored in a `config.ini` file on the raspberry Pi +### Visit [http://bitbot:8080](http://bitbot:8080) in your browser to **edit the configuration** - - Visit [http://bitbot:8080](http://bitbot:8080) in your browser to **edit the configuration** + - Configuration for your crypto-watcher is stored in a `config.ini` file on the raspberry Pi - Edit the config file directly see [💾 **Config** Options](docs/config_options.md) - A list of **supported crypto-exchanges** can be found [here](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) - Please see your selected exchange for the ***instruments that it supports*** -### Bitbot uses [Style Files](../config/mpl_styles/base.mplstyle) to control the chart layout. +### Bitbot uses **matplotlib [Style Files](../config/mpl_styles/base.mplstyle)** to control the chart layout. - edit these if you're feeling experimental, Examples of the ***styling*** options can be [found here](https://matplotlib.org/stable/tutorials/introductory/customizing.html#the-default-matplotlibrc-file) -### Inky Impression **Button** support +### Inky Impression **Button** support - toggle_picure_frame_mode - refresh_display - toggle_volume diff --git a/requirements.txt b/requirements.txt index b5329584..763af91c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ mplfinance>=0.12.10b0 watchdog==6.0.0 ccxt==4.4.40 inky==2.0.0 -yfinance==0.2.51 +yfinance==0.2.54 tzlocal python-dateutil diff --git a/src/config_server/server.py b/src/config_server/server.py index 39beca0d..7afc5617 100644 --- a/src/config_server/server.py +++ b/src/config_server/server.py @@ -4,8 +4,8 @@ import pathlib import time import uuid -from src.configuration.bitbot_files import BitBotFiles -from src.configuration.bitbot_config import load_config_ini +from configuration.bitbot_files import BitBotFiles +from configuration.bitbot_config import load_config_ini from flask import Flask, jsonify, render_template, request, redirect, send_from_directory, url_for from PIL import Image import ccxt diff --git a/src/config_webserver.py b/src/config_webserver.py new file mode 100644 index 00000000..2fd35449 --- /dev/null +++ b/src/config_webserver.py @@ -0,0 +1,3 @@ +from config_server.server import app + +app.run(debug=True, host='0.0.0.0', port=8081) diff --git a/src/configuration/bitbot_config.py b/src/configuration/bitbot_config.py index 740884bc..08b22fb5 100644 --- a/src/configuration/bitbot_config.py +++ b/src/configuration/bitbot_config.py @@ -192,7 +192,7 @@ def read_dict(self, dict): # 🌱 intro setup def on_first_run(self, action): - if self.config["first_run"]['enabled'] == "true": + if self.config.get('first_run', 'enabled', fallback=None) == "true": action() self.set('first_run', 'enabled', "false") self.save() @@ -205,7 +205,7 @@ def intro_background(self): # 📺 youtube subs setup def youtube_subs_enabled(self): - return self.config['youtube_subs']["enabled"] == 'true' + return self.config.get('youtube_subs', 'enabled', fallback=None) == 'true' def youtube_channelid(): return "UCAotflAHrgfuhK9Rw-C_-Ug" diff --git a/src/configuration/network_utils.py b/src/configuration/network_utils.py index abe84f76..ca7b871a 100644 --- a/src/configuration/network_utils.py +++ b/src/configuration/network_utils.py @@ -1,5 +1,6 @@ -from .log_decorator import info_log import socket +from .log_decorator import info_log +import http.client as httplib import time @@ -17,17 +18,21 @@ def get_ip(): return ip -def network_connected(hostname="google.com"): +def network_connected(hostname="8.8.8.8") -> bool: # 📡 test if internet is available + conn = httplib.HTTPSConnection(hostname, timeout=5) try: - host = socket.gethostbyname(hostname) - socket.create_connection((host, 80), 2).close() + conn.request("HEAD", "/") return True - except Exception: - time.sleep(1) - return False - + except Exception as e: + return network_error(e) + finally: + conn.close() +@info_log +def network_error(exception): + return False + @info_log def wait_for_internet_connection(action): connection_error_shown = False diff --git a/src/display/inky.py b/src/display/inky.py index b8434ecd..8df85d44 100644 --- a/src/display/inky.py +++ b/src/display/inky.py @@ -24,6 +24,8 @@ def show(self, image): self.display.set_border(self.display.WHITE) case "black": self.display.set_border(self.display.BLACK) + case "red": + self.display.set_border(self.display.RED) # 🌀 rotate/resize the image image = self.apply_rotation(image) diff --git a/src/display/waveshare.py b/src/display/waveshare.py index f7a65f5f..c6b92a4c 100644 --- a/src/display/waveshare.py +++ b/src/display/waveshare.py @@ -48,6 +48,9 @@ def show(self, image): time.sleep(1) epd.display(epd.getbuffer(black_image), epd.getbuffer(color_image)) epd.sleep() + except TypeError: # hax to deal with waveshare epd diver API variation + epd.display(epd.getbuffer(image)) + epd.sleep() finally: self.lock.release()