Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSV Support #73

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ Finally, you can set the environment variable `MODE` to `alternate` for Inkyshot
You can put number of minutes in the `ALTERNATE_FREQUENCY` environment variable in order to configure Inkyshot to update periodically.
By default, the first display is quote mode and you can instead chose weather by setting `current_display` tag to `weather` on the device.

#### Custom quotes CSV Support :
Use `CSV_MESSAGE` to put custom quotes in this format: `This is Quote 1;This is Quote2;This is the last Quote`.

Use `CSV_LOCAL_NAME` to refer to a path of a CSV file with custom quotes (don't forget the .csv extention).

The delimiter is `;` by default but setting `CSV_DELIMITER` let you change it. For example, setting `\n` as delimiter allows you to put one quote per line instead of separated with `;`.

### Hostname

By default the device will be assigned the hostname `inkyshot` so it can be easily found on a network. This can be changed with the `SET_HOSTNAME` environment variable.
Expand Down
66 changes: 65 additions & 1 deletion inkyshot/update-display.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
from pathlib import Path
import os
from os import environ
from os.path import exists
from random import randint
import sys
import textwrap
import time
import csv

from font_amatic_sc import AmaticSC
from font_caladea import Caladea
Expand Down Expand Up @@ -141,6 +144,22 @@ def get_current_display():
logging.error(err)
return current_display

def get_csv_index():
"""Query device supervisor API to retrieve the csv_index (to override citation choice)"""
# This function can be merged with get_current_display() by accepting a variable as the key to get.
url = f"{BALENA_SUPERVISOR_ADDRESS}/v2/device/tags?apikey={BALENA_SUPERVISOR_API_KEY}"
headers = {"Accept": "application/json"}
csv_index = None
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
if "tags" in data:
csv_index = next((t['value'] for t in data['tags'] if t['name'] == "csv_index"), None)
except requests.exceptions.RequestException as err:
logging.error(err)
return csv_index

def get_location():
"""Return coordinate and location info based on IP address"""
url = "https://ipinfo.io"
Expand Down Expand Up @@ -224,6 +243,31 @@ def set_current_display(val):
except requests.exceptions.RequestException as err:
logging.error(f"Failed to set current display to {val}. Error is: {err}")

def set_csv_index(val):
"""Update the csv_index to get a random one to increment each display update"""
# First get device identifier for future call
url_device = f"https://api.balena-cloud.com/v5/device?$filter=uuid eq '{BALENA_DEVICE_UUID}'&$select=id"
url_device_tag = "https://api.balena-cloud.com/v5/device_tag"
headers = {"Accept": "application/json", "Authorization": f"Bearer {BALENA_API_KEY}"}
try:
response = requests.get(url_device, headers=headers)
if response.status_code == 200:
data = response.json()
device_id = data['d'][0]['id'] if 'd' in data and len(data['d']) > 0 else None
request_data = {"device": device_id, "tag_key": "csv_index", "value": val } #I don't understand why you put it twice in set_currrent_display()
csv_index = get_csv_index()
if csv_index:
if csv_index == val:
# No need to modify the tag
return None
# Let's modify the existing tag with the new val
requests.patch(url_device_tag, data=request_data, headers=headers)
else:
# No tag exists yet, so let's create it
requests.post(url_device_tag, data=request_data, headers=headers)
except requests.exceptions.RequestException as err:
logging.error(f"Failed to set current display to {val}. Error is: {err}")

def temp_to_str(temp, scale):
"""Prepare the temperature to draw based on the defined scale: Celcius or Fahrenheit"""
if scale == 'F':
Expand Down Expand Up @@ -349,6 +393,26 @@ def temp_to_str(temp, scale):
# If message was set but blank, use the device name
if message == "":
message = os.environ['DEVICE_NAME']
elif 'CSV_MESSAGE' in os.environ :
csv_list = os.environ['CSV_MESSAGE'].split(delimiter = os.environ['CSV_DELIMITER'] if 'CSV_DELIMITER' in os.environ else ";" ) # Works with \n also (if csv is 1 column of X rows)
elif 'CSV_LOCAL_NAME' in os.environ :
# If user wants to use a local file instead
path_to_csv_file = "/usr/app/quotes/"+os.environ['CSV_LOCAL_NAME']
if exists(path_to_csv_file) :
with open(path_to_csv_file) as csvfile : # TODO: May be broken, need to be tested with relative path
csv_list = list(csv.reader(csvfile, delimiter = os.environ['CSV_DELIMITER'] if 'CSV_DELIMITER' in os.environ else ";"))
if csv_list :
number_of_quotes = len(csv_list)
csv_index = get_csv_index()
if csv_index :
# User want to choose which quote will be displayed, he overrides it by setting the csv_index value
message = csv_list[csv_index]
# Update index for tomorrow and cycle
set_csv_index(csv_index+1 if csv_index!= number_of_quotes-1 else 0)
else :
csv_index = randint(0,number_of_quotes-1)
set_csv_index(csv_index)
message = csv_list[csv_index]
elif message is None:
try:
response = requests.get(
Expand Down Expand Up @@ -377,7 +441,7 @@ def temp_to_str(temp, scale):

if FONT_SIZE <= 17:
FONT_SIZE = 8
FONT = ImageFont.truetype("/usr/app/fonts/Grand9KPixel.ttf", FONT_SIZE)
FONT = ImageFont.truetype(Grand9KPixel, FONT_SIZE)

# We're using the test character here to work out how many characters
# can fit on the display when using the chosen font
Expand Down