Skip to content
This repository was archived by the owner on May 16, 2023. It is now read-only.
Merged
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: 2 additions & 5 deletions Adafruit_Thermal.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Adafruit_Thermal(Serial):
lineSpacing = 8
barcodeHeight = 50
printMode = 0
defaultHeatTime = 180
defaultHeatTime = 120
firmwareVersion = 268
writeToStdout = False

Expand Down Expand Up @@ -549,11 +549,8 @@ def printBitmap(self, w, h, bitmap, LaaT=False):
# passing the result to this function.
def printImage(self, image_file, LaaT=False):
from PIL import Image
# image = Image.open(image_file)
image = image_file

if isinstance(image_file, str):
image = Image.open(image_file)

if image.mode != '1':
image = image.convert('1')

Expand Down
112 changes: 55 additions & 57 deletions forecast.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,72 @@
#!/usr/bin/python

# Weather forecast for Raspberry Pi w/Adafruit Mini Thermal Printer.
# Retrieves data from DarkSky.net's API, prints current conditions and
# forecasts for next two days. See timetemp.py for a different
# weather example using nice bitmaps.
# Written by Adafruit Industries. MIT license.
#
# Required software includes Adafruit_Thermal and PySerial libraries.
# Other libraries used are part of stock Python install.
#
# Resources:
# http://www.adafruit.com/products/597 Mini Thermal Receipt Printer
# http://www.adafruit.com/products/600 Printer starter pack

from __future__ import print_function
from Adafruit_Thermal import *
from datetime import date
from datetime import datetime
import calendar
import urllib, json
import urllib.request
import json

API_KEY = "YOUR_API_KEY"
printer = Adafruit_Thermal("/dev/serial0", 19200, timeout=5)
def getLink(dailyOrHourly):
latitude = "38.8894" #limit to four decimal digits
longitude = "-77.0352" #limit to four decimal digits
mainLink = "https://api.weather.gov/points/" + latitude + "," + longitude
response_main = urllib.request.urlopen(mainLink)
raw_data_main = response_main.read().decode()
data_main = json.loads(raw_data_main)
properties_main = data_main['properties']
dailyLink = properties_main["forecast"]
hourlyLink = properties_main["forecastHourly"]
if dailyOrHourly == "daily":
return dailyLink
elif dailyOrHourly == "hourly":
return hourlyLink

LAT = "40.726019"
LONG = "-74.00536"
url_daily = getLink("daily")
response_daily = urllib.request.urlopen(url_daily)
# status & reason
# print(response_daily.status, response_daily.reason)

# Dumps one forecast line to the printer
def forecast(idx):
raw_data_daily = response_daily.read().decode()
data_daily = json.loads(raw_data_daily)
forecast_periods_daily = data_daily['properties']['periods']

date = datetime.fromtimestamp(int(data['daily']['data'][idx]['time']))

day = calendar.day_name[date.weekday()]
lo = data['daily']['data'][idx]['temperatureMin']
hi = data['daily']['data'][idx]['temperatureMax']
cond = data['daily']['data'][idx]['summary']
printer.print(day + ': low ' + str(lo) )
printer.print(deg)
printer.print(' high ' + str(hi))
printer.print(deg)
printer.println(' ' + cond.replace(u'\u2013', '-').encode('utf-8')) # take care of pesky unicode dash
current_period_isDayTime = forecast_periods_daily[0]['isDaytime']

printer = Adafruit_Thermal("/dev/serial0", 19200, timeout=5)
deg = chr(0xf8) # Degree symbol on thermal printer
if current_period_isDayTime:
day_index = 0
night_index = 1
else:
day_index = 1
night_index = 0

url = "https://api.darksky.net/forecast/"+API_KEY+"/"+LAT+","+LONG+"?exclude=[alerts,minutely,hourly,flags]&units=us"
response = urllib.urlopen(url)
data = json.loads(response.read())
day_name = forecast_periods_daily[day_index]['name']
hi_temp = forecast_periods_daily[day_index]['temperature']
night_name = forecast_periods_daily[night_index]['name']
lo_temp = forecast_periods_daily[night_index]['temperature']
current_detailed_forecast = forecast_periods_daily[0]['detailedForecast']

# Print heading
printer.inverseOn()
printer.print('{:^32}'.format("DarkSky.Net Forecast"))
printer.inverseOff()

# Print current conditions
printer.boldOn()
printer.print('{:^32}'.format('Current conditions:'))
printer.boldOff()
url_hourly = getLink("hourly")
response_hourly = urllib.request.urlopen(url_hourly)
# status & reason
#print(response_hourly.status, response_hourly.reason)

raw_data_hourly = response_hourly.read().decode()
data_hourly = json.loads(raw_data_hourly)
forecast_periods_hourly = data_hourly['properties']['periods']
temperature = forecast_periods_hourly[0]['temperature']

temp = data['currently']['temperature']
cond = data['currently']['summary']
printer.print(temp)
printer.print(deg)
printer.println(' ' + cond)
d = date.today()
week_day = calendar.day_name[date(d.year,d.month,d.day).weekday()]
month_text = calendar.month_name[d.month]
printer.underlineOn()
printer.print("It's " + week_day + ", " + month_text + " " + str(d.day) + "\n")
printer.underlineOff()
printer.boldOn()

# Print forecast
printer.print('{:^32}'.format('Forecast:'))
printer.print(day_name + "'s Forecast \n")
printer.boldOff()
forecast(0)
forecast(1)

printer.print("Current temperature: " + str(temperature) + " F \n")
printer.print("High temperature: " + str(hi_temp) + " F \n")
printer.print("Low temperature: " + str(lo_temp) + " F \n")
printer.print(current_detailed_forecast + "\n")
printer.feed(3)
25 changes: 15 additions & 10 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3

# Main script for Adafruit Internet of Things Printer 2. Monitors button
# for taps and holds, performs periodic actions (Twitter polling by default)
Expand All @@ -19,6 +19,8 @@
import subprocess, time, socket
from PIL import Image
from Adafruit_Thermal import *
from datetime import date
import calendar

ledPin = 18
buttonPin = 23
Expand All @@ -33,7 +35,7 @@
# Called when button is briefly tapped. Invokes time/temperature script.
def tap():
GPIO.output(ledPin, GPIO.HIGH) # LED on while working
subprocess.call(["python", "timetemp.py"])
subprocess.call(["python3", "forecast.py"])
GPIO.output(ledPin, GPIO.LOW)


Expand All @@ -51,7 +53,7 @@ def hold():
# Invokes twitter script.
def interval():
GPIO.output(ledPin, GPIO.HIGH)
p = subprocess.Popen(["python", "twitter.py", str(lastId)],
p = subprocess.Popen(["python3", "twitter.py", str(lastId)],
stdout=subprocess.PIPE)
GPIO.output(ledPin, GPIO.LOW)
return p.communicate()[0] # Script pipes back lastId, returned to main
Expand All @@ -61,8 +63,11 @@ def interval():
# Invokes weather forecast and sudoku-gfx scripts.
def daily():
GPIO.output(ledPin, GPIO.HIGH)
subprocess.call(["python", "forecast.py"])
subprocess.call(["python", "sudoku-gfx.py"])
subprocess.call(["python3", "forecast.py"])
d = date.today()
weekday = calendar.day_name[date(d.year,d.month,d.day).weekday()]
if weekday == "Saturday" or weekday == "Sunday":
subprocess.call(["python3", "sudoku-gfx.py"])
GPIO.output(ledPin, GPIO.LOW)


Expand Down Expand Up @@ -159,9 +164,9 @@ def daily():
# Every 30 seconds, run Twitter scripts. 'lastId' is passed around
# to preserve state between invocations. Probably simpler to do an
# import thing.
if t > nextInterval:
nextInterval = t + 30.0
result = interval()
if result is not None:
lastId = result.rstrip('\r\n')
# if t > nextInterval:
# nextInterval = t + 30.0
# result = interval()
# if result is not None:
# lastId = result.rstrip('\r\n')

36 changes: 18 additions & 18 deletions sudoku-gfx.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
#
# Sudoku Generator and Solver in 250 lines of python
# Copyright (c) 2006 David Bau. All rights reserved.
Expand Down Expand Up @@ -55,22 +55,22 @@ def main():

def makepuzzle(board):
puzzle = []; deduced = [None] * 81
order = random.sample(xrange(81), 81)
order = random.sample(range(81), 81)
for pos in order:
if deduced[pos] is None:
puzzle.append((pos, board[pos]))
deduced[pos] = board[pos]
deduce(deduced)
random.shuffle(puzzle)
for i in xrange(len(puzzle) - 1, -1, -1):
for i in range(len(puzzle) - 1, -1, -1):
e = puzzle[i]; del puzzle[i]
rating = checkpuzzle(boardforentries(puzzle), board)
if rating == -1: puzzle.append(e)
return boardforentries(puzzle)

def ratepuzzle(puzzle, samples):
total = 0
for i in xrange(samples):
for i in range(samples):
state, answer = solveboard(puzzle)
if answer is None: return -1
total += len(state)
Expand Down Expand Up @@ -113,7 +113,7 @@ def deduce(board):
stuck, guess, count = True, None, 0
# fill in any spots determined by direct conflicts
allowed, needed = figurebits(board)
for pos in xrange(81):
for pos in range(81):
if None == board[pos]:
numbers = listbits(allowed[pos])
if len(numbers) == 0: return []
Expand All @@ -122,13 +122,13 @@ def deduce(board):
guess, count = pickbetter(guess, count, [(pos, n) for n in numbers])
if not stuck: allowed, needed = figurebits(board)
# fill in any spots determined by elimination of other locations
for axis in xrange(3):
for x in xrange(9):
for axis in range(3):
for x in range(9):
numbers = listbits(needed[axis * 9 + x])
for n in numbers:
bit = 1 << n
spots = []
for y in xrange(9):
for y in range(9):
pos = posfor(x, y, axis)
if allowed[pos] & bit: spots.append(pos)
if len(spots) == 0: return []
Expand All @@ -141,11 +141,11 @@ def deduce(board):

def figurebits(board):
allowed, needed = [e is None and 511 or 0 for e in board], []
for axis in xrange(3):
for x in xrange(9):
for axis in range(3):
for x in range(9):
bits = axismissing(board, x, axis)
needed.append(bits)
for y in xrange(9):
for y in range(9):
allowed[posfor(x, y, axis)] &= bits
return allowed, needed

Expand All @@ -161,17 +161,17 @@ def axisfor(pos, axis):

def axismissing(board, x, axis):
bits = 0
for y in xrange(9):
for y in range(9):
e = board[posfor(x, y, axis)]
if e is not None: bits |= 1 << e
return 511 ^ bits

def listbits(bits):
return [y for y in xrange(9) if 0 != bits & 1 << y]
return [y for y in range(9) if 0 != bits & 1 << y]

def allowed(board, pos):
bits = 511
for axis in xrange(3):
for axis in range(3):
x = axisfor(pos, axis)
bits &= axismissing(board, x, axis)
return bits
Expand All @@ -183,22 +183,22 @@ def pickbetter(b, c, t):
else: return (b, c + 1)

def entriesforboard(board):
return [(pos, board[pos]) for pos in xrange(81) if board[pos] is not None]
return [(pos, board[pos]) for pos in range(81) if board[pos] is not None]

def boardforentries(entries):
board = [None] * 81
for pos, n in entries: board[pos] = n
return board

def boardmatches(b1, b2):
for i in xrange(81):
for i in range(81):
if b1[i] != b2[i]: return False
return True

def printboard(board):
bg.paste(img, (0, 0)) # Numbers are cropped off right side
for row in xrange(9):
for col in xrange(9):
for row in range(9):
for col in range(9):
n = board[posfor(row, col)]
if n is not None:
bg.paste(numbers[n], (xcoord[col], ycoord[row]))
Expand Down