Skip to content

Commit

Permalink
Merge pull request #97 from mrjones-plip/oled-lib-refactor
Browse files Browse the repository at this point in the history
oled refactor Adafruit_SSD1306 -> luma.oled
  • Loading branch information
mrjones-plip authored Jun 8, 2021
2 parents 7ce0ccb + 3371f66 commit ebe82af
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 187 deletions.
14 changes: 14 additions & 0 deletions I2C.bme280.oled/YANPIWS.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=YANPIWS
After=network-online.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/YANPIWS/I2C.bme280.oled/remote_all.py -b 1 -ip 192.168.2.30 -id1 57 -id2 74
# todo - the After above doesn't seem to work so we put this sleep in here :(
ExecStartPre=/bin/sleep 10
ExecStop=/usr/bin/python3 /home/pi/YANPIWS/I2C.bme280.oled/clear_scren.py -b 1
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.etarget
27 changes: 27 additions & 0 deletions I2C.bme280.oled/clear_scren.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/python3

from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
import argparse
import atexit


parser = argparse.ArgumentParser()

# Rev 2 Pi, Pi 2 & Pi 3 uses bus 1
# Rev 1 Pi uses bus 0
# Orange Pi Zero uses bus 0 for pins 1-5 (other pins for bus 1 & 2)
parser.add_argument('--bus', '-b', default=0, type=int, help='Bus Number, defaults to 0')

args = parser.parse_args()
bus_number = args.bus


if __name__ == "__main__":
serial = i2c(port=bus_number, address=0x3C)

device = ssd1306(serial)

with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline="black", fill="black")
12 changes: 11 additions & 1 deletion I2C.bme280.oled/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ device IDs after running `i2cdetect 0` or `i2cdetect 1`. These are likley `76` f
It defaults to `--bus/-b` of `1` and `--device/-d` of `0x76`. Likely if you're on a Pi, you
won't need to change anything, so you can just call it with out any arguments.
1. `remote_all.py` takes teh following arguments:
1. `remote_all.py` takes teh following arguments:
```$xslt
usage: remote_all.py [-h] [--bus BUS] [--remote_ip REMOTE_IP]
[--temp_id1 TEMP_ID1] [--temp_id2 TEMP_ID2]
Expand All @@ -84,6 +84,16 @@ device IDs after running `i2cdetect 0` or `i2cdetect 1`. These are likley `76` f
* * * * * cd /var/www/html/I2C.bme280.oled; /usr/bin/python3 live_temp_hum_bme280.py
* * * * * /usr/bin/python3 /var/www/html/I2C.bme280.oled/remote_all.py -ip 192.168.68.105 -id1 73 -id2 231
```
todo - implement this systmed based crontab:
```
* * * * * cd /var/www/html/I2C.bme280.oled; /usr/bin/python3 remote_temps_humid.py -b 0 -ip 10.0.40.219 -id1 96 -id2 97
# at 8pm turn off screen
0 20 * * * /usr/bin/systemctl stop weathercaster
# at 6am start screen
0 6 * * * /usr/bin/systemctl start weathercaster
```
If you need more help - read up on the "Long Start" below.
Expand Down
202 changes: 101 additions & 101 deletions I2C.bme280.oled/remote_all.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
#!/usr/bin/python
#!/usr/bin/python3


# grab args from CLI
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
from PIL import ImageFont
import os
import argparse
import json
import time
import logging.handlers

my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address='/dev/log')
my_logger.addHandler(handler)

parser = argparse.ArgumentParser()

Expand All @@ -21,117 +32,106 @@
parser.add_argument('--temp_id2', '-id2', type=int, help='remote temp ID #2, defaults to 63')

args = parser.parse_args()

yanpiws_ip = args.remote_ip
yanpiws_temp_1 = args.temp_id1
yanpiws_temp_2 = args.temp_id2

bus_number = args.bus

temp1url = 'http://' + str(yanpiws_ip) + '/ajax.php?content=humidity&id=' + str(yanpiws_temp_1)
temp2url = 'http://' + str(yanpiws_ip) + '/ajax.php?content=humidity&id=' + str(yanpiws_temp_2)
forecastUrl = 'http://' + str(yanpiws_ip) + '/ajax.php?content=forecast_full_json'
sunsetUrl = 'http://' + str(yanpiws_ip) + '/ajax.php?content=sunset'
sunriseUrl = 'http://' + str(yanpiws_ip) + '/ajax.php?content=sunrise'
datetimeUrl = 'http://' + str(yanpiws_ip) + '/ajax.php?content=datetime'


def get_string_from_url(url):
import urllib.request
raw_html = urllib.request.urlopen(url).read().decode('utf-8').rstrip()
return raw_html

# fetch the cooked up html -> strings
import json
temp1 = json.loads(get_string_from_url(temp1url))

if temp1[0]['temp'] != 'NA':
temp1final = str(int(float(temp1[0]['temp']))) + temp1[0]['label']
else:
temp1final = 'NA'

if yanpiws_temp_2 != None:
temp2 = json.loads(get_string_from_url(temp2url))
if temp2[0]['temp'] != 'NA':
temp2final = ' ' + str(int(float(temp2[0]['temp']))) + temp2[0]['label']
else:
temp2final = ''
else:
temp2final = ''

forecast = json.loads(get_string_from_url(forecastUrl))

sunset = json.loads(get_string_from_url(sunsetUrl))
sunrise = json.loads(get_string_from_url(sunriseUrl))
def get_forecast():
forecastUrl = 'http://' + str(yanpiws_ip) + '/ajax.php?content=forecast_full_json'
return json.loads(get_string_from_url(forecastUrl))

date_time = json.loads(get_string_from_url(datetimeUrl))

import os
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# set full puth for incling libs below
full_path = os.path.dirname(os.path.abspath(__file__)) + "/"
def get_sunrise_sunset(string):
url = 'http://' + str(yanpiws_ip) + '/ajax.php?content=' + string
data = json.loads(get_string_from_url(url))
string = data[string].split(' ')[0]
return string

# Raspberry Pi pin configuration:
RST = None # on the PiOLED this pin isnt used
# Note the following are only used with SPI:
DC = 23
SPI_PORT = 0
SPI_DEVICE = 0

# Rev 2 Pi, Pi 2 & Pi 3 uses bus 1
# Rev 1 Pi uses bus 0
# Orange Pi Zero uses bus 0 for pins 1-5 (other pins for bus 1 & 2)
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_bus=bus_number)

# Initialize library.
disp.begin()

# Clear display.
disp.clear()
disp.display()

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((-20,-20,width,height), outline=0, fill=0)

# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height-padding

# Load default font.
font = ImageFont.truetype(full_path + "Lato-Heavy.ttf", 10)
font_small = ImageFont.truetype(full_path + "Lato-Heavy.ttf", 12)
# Alternatively load a TTF font. Make sure the .ttf font file is in the same directory as the python script!
# Some other nice fonts to try: http://www.dafont.com/bitmap.php
# font = ImageFont.truetype('Minecraftia.ttf', 8)

# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)
sunriseFinal = sunrise['sunrise'].split(' ')[0]
sunsetFinal = sunset['sunset'].split(' ')[0]

# render the data
draw.text((0, top ), date_time['date'] + ' ' + date_time['time'] , font=font_small, fill=255)
draw.text((0, top + 17), temp1final + temp2final + ' ' + sunriseFinal + ' ' + sunsetFinal, font=font_small, fill=255)
draw.text((0, top + 35), 'H: ' + str(int(forecast[0]['temperatureHigh'])) + ' L: '
+ str(int(forecast[0]['temperatureLow'])) + ' ' + forecast[0]['icon'], font=font_small, fill=255)
draw.text((0, top + 52), 'H: ' + str(int(forecast[1]['temperatureHigh'])) + ' L: '
+ str(int(forecast[1]['temperatureLow'])) + ' ' + forecast[1]['icon'], font=font_small, fill=255)

# Display image.
disp.image(image)
disp.display()
def get_temp_string(temp_id):
if temp_id != None:
url = 'http://' + str(yanpiws_ip) + '/ajax.php?content=humidity&id=' + str(temp_id)
temp = json.loads(get_string_from_url(url))
if temp[0]['temp'] != 'NA':
the_string = ' ' + str(int(float(temp[0]['temp']))) + temp[0]['label']
else:
the_string = ''
else:
the_string = ''

return the_string


def get_date_time():
url = 'http://' + str(yanpiws_ip) + '/ajax.php?content=datetime'
date_time = json.loads(get_string_from_url(url))
string = date_time['date'] + ' ' + date_time['time']
return string


def show_info(device):
first_line = get_date_time()
temp1final = get_temp_string(yanpiws_temp_1)
temp2final = get_temp_string(yanpiws_temp_2)
sunrise_final = get_sunrise_sunset('sunrise')
sunset_final = get_sunrise_sunset('sunset')
forecast = get_forecast()

full_path = os.path.dirname(os.path.abspath(__file__)) + "/"
font2 = ImageFont.truetype(full_path + "Lato-Heavy.ttf", 12)

second_line = temp1final + temp2final + ' ' + sunrise_final + ' ' + sunset_final
third_line = 'H: ' + str(int(forecast[0]['temperatureHigh'])) + ' L: ' + str(int(forecast[0]['temperatureLow'])) +\
' ' + forecast[0]['icon']
fourth_line = 'H: ' + str(int(forecast[1]['temperatureHigh'])) + ' L: ' + str(int(forecast[1]['temperatureLow'])) +\
' ' + forecast[1]['icon']

with canvas(device) as draw:
# draw.rectangle(device.bounding_box, outline="white", fill="black")
draw.text((0, 0), first_line, font=font2, fill="white")
draw.text((0, 17), second_line, font=font2, fill="white")
draw.text((0, 35), third_line, font=font2, fill="white")
draw.text((0, 52), fourth_line, font=font2, fill="white")


def full_stack():
import traceback, sys
exc = sys.exc_info()[0]
stack = traceback.extract_stack()[:-1] # last one would be full_stack()
if exc is not None: # i.e. an exception is present
del stack[-1] # remove call of full_stack, the printed exception
# will contain the caught exception caller instead
trc = 'Traceback (most recent call last):\n'
stackstr = trc + ''.join(traceback.format_list(stack))
if exc is not None:
stackstr += ' ' + traceback.format_exc().lstrip(trc)
return stackstr


def main(device):

while True:
show_info(device)
time.sleep(50)


if __name__ == "__main__":
try:
my_logger.debug('YANPIWS: Starting')
serial = i2c(port=bus_number, address=0x3C)
device = ssd1306(serial)

main(device)
except KeyboardInterrupt:
my_logger.debug("YANPIWS: Stopping(Ctrl + C)")
pass
finally:
my_logger.debug("YANPIWS exit trace: " + full_stack())
Loading

0 comments on commit ebe82af

Please sign in to comment.