diff --git a/Adafruit_Thermal.py b/Adafruit_Thermal.py index 46b0448..551e251 100644 --- a/Adafruit_Thermal.py +++ b/Adafruit_Thermal.py @@ -50,7 +50,7 @@ class Adafruit_Thermal(Serial): lineSpacing = 8 barcodeHeight = 50 printMode = 0 - defaultHeatTime = 180 + defaultHeatTime = 120 firmwareVersion = 268 writeToStdout = False @@ -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') diff --git a/forecast.py b/forecast.py index 3d9da85..6353101 100755 --- a/forecast.py +++ b/forecast.py @@ -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) diff --git a/main.py b/main.py index 9ebff71..2494677 100755 --- a/main.py +++ b/main.py @@ -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) @@ -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 @@ -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) @@ -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 @@ -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) @@ -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') diff --git a/sudoku-gfx.py b/sudoku-gfx.py index 2a7ac12..e955bbf 100755 --- a/sudoku-gfx.py +++ b/sudoku-gfx.py @@ -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. @@ -55,14 +55,14 @@ 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) @@ -70,7 +70,7 @@ def makepuzzle(board): 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) @@ -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 [] @@ -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 [] @@ -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 @@ -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 @@ -183,7 +183,7 @@ 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 @@ -191,14 +191,14 @@ def boardforentries(entries): 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]))