def fill_up(): # Filled bulb inkyphat.pieslice((margin_bottom + bulb_space, margin_left + bulb_space, margin_bottom + bulb_space + bulb_fill, margin_left + bulb_space + bulb_fill), 0, 360, 2, 2) # Filled tube inkyphat.rectangle((60, 42, 190, 61), 2, 2) inkyphat.pieslice((180, 42, 202, 62), 270, 90, 2, 2)
def draw_therm(): inkyphat.arc((margin_bottom, margin_left, margin_bottom + bulb_width, margin_right + bulb_width), 0, 360, 1) inkyphat.arc( (margin_bottom - 1, margin_left - 1, margin_bottom + bulb_width + 1, margin_right + bulb_width + 1), 0, 360, 1) inkyphat.rectangle((tube_x - (bulb_width / 2), tube_y, (fill_max - tube_width), (tube_y + tube_width)), 0, 0) inkyphat.line((tubeline_top_x, tubeline_top_y, fill_max - tube_width / 2, tubeline_top_y), 1, 1) inkyphat.line( (tubeline_top_x, (tubeline_top_y - 1), fill_max - tube_width / 2, (tubeline_top_y - 1)), 1, 1) inkyphat.line((tubeline_top_x, tubeline_bottom_y, (fill_max - tube_width / 2), tubeline_bottom_y), 1, 1) inkyphat.line( (tubeline_top_x, (tubeline_bottom_y + 1), fill_max - tube_width / 2, (tubeline_bottom_y + 1)), 1, 1) inkyphat.arc( ((fill_max - tube_width), tubeline_top_y, fill_max, tubeline_bottom_y), 270, 90, 1) inkyphat.arc(((fill_max - tube_width + 1), tubeline_top_y - 1, fill_max + 1, tubeline_bottom_y + 1), 270, 90, 1)
def draw_subject(rect, label, font): inkyphat.rectangle(rect, fill=inkyphat.WHITE) left, top, right, bottom = rect y_middle = (top + bottom)/2 fw, fh = font.getsize(label) y = y_middle - fh/2 inkyphatwidget.textutil.print_width_limited((left, y), label, inkyphat.BLACK, font, right - left - 1)
def display_info(text, rotate = True): title = "%s %s" % (text, time.strftime('%d/%m %H:%M')) local_IP = "IP loc.: %s" % (read_local_ip()) public_IP = "IP pub.: %s" % (read_public_ip()) info_CPU = "CPU: T. {:2.0f} C, load {:2.0f} %".format(read_CPU_temp(), cpu_percent()) if has_inky: inkyphat.clear() font18 = inkyphat.ImageFont.truetype(inkyphat.fonts.FredokaOne, 18) font20 = inkyphat.ImageFont.truetype(inkyphat.fonts.FredokaOne, 20) font24 = inkyphat.ImageFont.truetype(inkyphat.fonts.FredokaOne, 24) if rotate: inkyphat.set_rotation(180) inkyphat.rectangle((0, 0, 212, 30), red, red) width, height = font20.getsize(title) d, r = divmod(width, 2) inkyphat.text((106-d, 3), title, white, font=font20) inkyphat.rectangle((0, 31, 212, 104), white, white) inkyphat.text((5, 31), local_IP, black, font=font18) inkyphat.text((5, 53), public_IP, black, font=font18) inkyphat.text((5, 78), info_CPU, red, font=font18) inkyphat.show() else: print(title) print(local_IP) print(public_IP) print(temp_CPU) return local_IP, public_IP, info_CPU
def draw_ticket_id(rect, label, font): inkyphat.rectangle(rect, fill=inkyphat.WHITE) left, top, right, bottom = rect y_middle = (top + bottom)/2 fw, fh = font.getsize(label) x = right - fw y = y_middle - fh/2 inkyphat.text((x, y), label, inkyphat.BLACK, font)
def draw_error(rect, exc, font=None): left, top, right, bottom = rect inkyphat.rectangle(rect, fill=inkyphat.WHITE) icon = Image.open(os.path.join(resource_dir, 'error.png')) inkyphat.paste(icon, (left, top), inkyphat.create_mask(icon)) inkyphatwidget.textutil.print_width_limited( (left + 16, top), "%s (%s)" % (exc, type(exc).__name__), inkyphat.RED, font, right - left - 16) inkyphatwidget.request()
def draw(rect, state, title, font): left, top, right, bottom = rect inkyphat.rectangle(rect, fill=inkyphat.WHITE) text_left = left icon = status_icon.get(state, None) if icon: inkyphat.paste(icon, (left, top), inkyphat.create_mask(icon)) text_left += 16 inkyphatwidget.textutil.print_width_limited( (text_left, top), title, inkyphat.BLACK, font, right - text_left) inkyphatwidget.request()
def new_image(self, **kwargs): self.offset_x = kwargs.get("offset_x", None) self.offset_y = kwargs.get("offset_y", None) if self.pixel_size - (self.border * 2) > min(inkyphat.WIDTH, inkyphat.HEIGHT): print("QR code is too large for Inky pHAT, it probably wont scan! Try `box_size=1`") if self.offset_x is None: self.offset_x = (inkyphat.WIDTH // 2) - (self.pixel_size // 2) if self.offset_y is None: self.offset_y = (inkyphat.HEIGHT // 2) - (self.pixel_size // 2) box = (self.offset_x, self.offset_y, self.offset_x + self.pixel_size - 1, self.offset_y + self.pixel_size - 1) inkyphat.rectangle(box, fill=inkyphat.WHITE)
def display_title(text): now_time = strftime('%d/%m %H:%M') title_string = text + " " + now_time if not has_inky: print(title_string) return clear_display() inkyphat.rectangle((0, 0, 212, 30), inkyphat.RED, inkyphat.RED) width, height = font20.getsize(title_string) d, r = divmod(width, 2) inkyphat.text((106 - d, 3), title_string, inkyphat.WHITE, font=font20) return
def draw_weather(): weather = get_weather() if weather == None: print 'No weather!' return if ROTATE_180 == True: inkyphat.set_rotation(180) # TODO configurable color inkyphat.set_colour('red') inkyphat.set_border(inkyphat.RED) # background inkyphat.rectangle((0, 0, inkyphat.WIDTH, inkyphat.HEIGHT), inkyphat.RED) # draw columns # (assuming get_weather has returned using NUM_COLS) for i in range(0, NUM_COLS): # draw time label time = weather['hours'][i]['time'] w, h = timeFont.getsize(time) draw_shadowed_text(get_x(w, i), 4, time, timeFont) # draw icon try: # This could be optimized to not load the same file more than once img = Image.open('assets/' + weather['hours'][i]['icon'] + '.png') inkyphat.paste(img, (get_x(30, i), 22)) # drawing icons without transparency as it didn't work with whatever gimp was producing except: print 'Error with icon:' + weather['hours'][i]['icon'] # draw temperature label temp = weather['hours'][i]['temperature'] w, h = temperatureFont.getsize(temp) draw_shadowed_text(get_x(w, i), 56, temp, temperatureFont) # TODO multiple lines if too long draw_shadowed_text(5, 84, weather['summary'], summaryFont) inkyphat.show()
def fill_up(): global currtemp # inkyphat.pieslice((), 0, 360, 2, 2) # Filled bulb inkyphat.pieslice( (margin_bottom + bulb_space, margin_left + bulb_space, margin_bottom + bulb_space + bulb_fill, margin_left + bulb_space + bulb_fill), 0, 360, 2, 2) # Filled tube #inkyphat.rectangle((tubeline_top_x - (bulb_width / 2), tubeline_top_y + bulb_space, (fill_max - tube_width + tube_width / 2), (tubeline_bottom_y - bulb_space)), 2, 2) if currtemp <= 0: inv = currtemp * -1 inkyphat.rectangle( (tubeline_top_x - (bulb_width / 2), tubeline_top_y + bulb_space, (fmax - 100 - (inv * 2)), (tubeline_bottom_y - bulb_space)), 2, 2) else: inkyphat.rectangle( (tubeline_top_x - (bulb_width / 2), tubeline_top_y + bulb_space, (fmax - 140 + 40 + (currtemp * 2)), (tubeline_bottom_y - bulb_space)), 2, 2)
def drawrect(self, row, col): box = self.pixel_box(row, col) inkyphat.rectangle(box, fill=inkyphat.BLACK)
def viv_display(th, tr, tc, hh): # display readinga and any alerts on inkyphat #logger.debug("Setting inkyphat") iclear(0) # load background image inkyphat.set_image(Image.open("/home/pi/snake-back.png")) # set font sizes font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 28) smallfont = ImageFont.truetype(inkyphat.fonts.FredokaOne, 10) midfont = ImageFont.truetype(inkyphat.fonts.FredokaOne, 16) # Top left box for hot-end temp inkyphat.rectangle([2, 2, 70, 25], fill=inkyphat.BLACK, outline=1) inkyphat.rectangle([2, 2, 70, 70], fill=None, outline=1) #top left message = "HOT" inkyphat.text((20, 3), message, inkyphat.WHITE, midfont) if th > 28 and th < 31: inkyphat.text((8, 25), str(th), inkyphat.BLACK, font) else: inkyphat.text((8, 25), str(th), inkyphat.RED, font) #Middle box for roof temp inkyphat.rectangle([74, 2, 142, 25], fill=inkyphat.BLACK, outline=1) # top middle inkyphat.rectangle([74, 2, 142, 70], fill=None, outline=1) message = "ROOF" inkyphat.text((88, 3), message, inkyphat.WHITE, midfont) if tr > 34 and tr < 37: inkyphat.text((81, 25), str(tr), inkyphat.BLACK, font) else: inkyphat.text((81, 25), str(tr), inkyphat.RED, font) # Right box for cool end temp inkyphat.rectangle([146, 2, 210, 25], fill=inkyphat.BLACK, outline=1) # top middle inkyphat.rectangle([146, 2, 210, 70], fill=None, outline=1) message = "COOL" inkyphat.text((156, 3), message, inkyphat.WHITE, midfont) if tc > 21 and tc < 27: inkyphat.text((152, 25), str(tc), inkyphat.BLACK, font) else: inkyphat.text((152, 25), str(tc), inkyphat.RED, font) # Bottom left box for humidity inkyphat.rectangle([12, 74, 55, 100], fill=inkyphat.BLACK, outline=1) # top middle inkyphat.rectangle([12, 74, 102, 100], fill=None, outline=1) message = "Hum" inkyphat.text((16, 80), message, inkyphat.WHITE, midfont) if hh > 20 and hh < 75: inkyphat.text((62, 78), str(hh) + "%", inkyphat.BLACK, midfont) else: inkyphat.text((62, 78), str(hh) + "%", inkyphat.RED, midfont) # Bottom middle for time rightnow = dt.now() inkyphat.text((110, 70), str("%02d" % (rightnow.hour, )) + ":" + str("%02d" % (rightnow.minute, )), inkyphat.RED, font) #print("Displaying on inkyphat") inkyphat.show()
def main(): """Shows basic usage of the Google Calendar API. Creates a Google Calendar API service object and outputs a list of the next 10 events on the user's calendar. """ credentials = get_credentials() http = credentials.authorize(httplib2.Http()) service = discovery.build('calendar', 'v3', http=http) now = datetime.datetime.utcnow().isoformat( ) + 'Z' # 'Z' indicates UTC time print('Getting the upcoming 3 events') eventsResult = service.events().list( calendarId= '*****@*****.**', timeMin=now, maxResults=3, singleEvents=True, orderBy='startTime').execute() events = eventsResult.get('items', []) #inkyphat.set_border(inkyphat.BLACK) inkyphat.set_rotation(180) inkyphat.rectangle((0, 0, inkyphat.WIDTH, inkyphat.HEIGHT), fill=inkyphat.WHITE) font = ImageFont.truetype( "/usr/share/fonts/truetype/freefont/FreeSans.ttf", 14) fontBold = ImageFont.truetype( "/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 14) fontBoldBig = ImageFont.truetype( "/usr/share/fonts/truetype/freefont/FreeSansBold.ttf", 15) offset_x, offset_y = 5, 0 hasCurEvent = False if not events: print('No upcoming events found.') text = "No upcoming events found." inkyphat.text((offset_x, offset_y), text, inkyphat.RED, font=font) for event in events: start = parse(event['start'].get('dateTime', event['start'].get('date'))) end = parse(event['end'].get('dateTime', event['end'].get('date'))) print(start, end, event['summary']) colour = inkyphat.BLACK prefix = 'Next ' if start < datetime.datetime.now( tzlocal()) and end > datetime.datetime.now(tzlocal()): hasCurEvent = True colour = inkyphat.RED #text = "{} - {}: {}".format(start.strftime('%a %H:%M'), end.strftime('%H:%M'), event['summary']) text = "{} - {}:".format(start.strftime('%a %H:%M'), end.strftime('%H:%M')) inkyphat.text((offset_x, offset_y), text, colour, font=fontBold) offset_y += fontBold.getsize(text)[1] + 2 text = event['summary'] inkyphat.text((offset_x + 10, offset_y), text, colour, font=font) offset_y += font.getsize(text)[1] + 2 if offset_y >= inkyphat.HEIGHT: break curTime = datetime.datetime.now(tzlocal()).strftime('%H:%M') timeOffset = fontBoldBig.getsize(curTime) timeBox = [ inkyphat.WIDTH - timeOffset[0] - 8, inkyphat.HEIGHT - timeOffset[1], inkyphat.WIDTH, inkyphat.HEIGHT ] inkyphat.rectangle(timeBox, fill=inkyphat.RED if hasCurEvent else inkyphat.BLACK) inkyphat.text( (inkyphat.WIDTH - timeOffset[0] - 6, inkyphat.HEIGHT - timeOffset[1]), curTime, inkyphat.WHITE, font=fontBoldBig) inkyphat.show()
def draw_status(rect, status_id): inkyphat.rectangle(rect, fill=inkyphat.WHITE) left, top, right, bottom = rect icon = status_icon.get(status_id) if icon: inkyphat.paste(icon, (left, top), inkyphat.create_mask(icon))
def updateTube(): threading.Timer(90, updateTube).start() # Get tube data url = 'https://api.tfl.gov.uk/line/mode/tube/status' response = requests.get(url) data = json.loads(response.text) for item in data: print(item['name']) print(item['lineStatuses'][0]['statusSeverity']) # draw header inkyphat.rectangle([0, 0, 19, 131], fill=inkyphat.BLACK, outline=inkyphat.BLACK) draw_text((2, 9), "tubetron", font=2, colour=inkyphat.WHITE, rotation=90, size=18) top = 0 #loop through each tube line for i in range(0, 11): y = (i * 15) + 25 text = data[i]['name'] if text == "Hammersmith & City": text = "H'Smth & City" if text == "Metropolitan": text = "M'politan" if text == "Waterloo & City": text = "W'loo & City" draw_text((y, 23), text, rotation=90) if data[i]['lineStatuses'][0]['statusSeverity'] < 8: inkyphat.ellipse([y, 5, y + 10, 15], fill=inkyphat.RED, outline=inkyphat.BLACK) if data[i]['lineStatuses'][0]['statusSeverity'] > 7 and data[i][ 'lineStatuses'][0]['statusSeverity'] < 10: inkyphat.ellipse([y, 5, y + 10, 15], fill=None, outline=inkyphat.BLACK) inkyphat.ellipse([y + 3, 8, y + 7, 13], fill=inkyphat.BLACK, outline=inkyphat.BLACK) if data[i]['lineStatuses'][0]['statusSeverity'] == 10: inkyphat.ellipse([y, 5, y + 10, 15], fill=None, outline=inkyphat.BLACK) utc = datetime.now() + timedelta(hours=1) bst = pytz.timezone('Europe/London') fmt = '%H:%M %d/%m/%y' time = bst.localize(utc).strftime(fmt) # timestamp print(time) inkyphat.rectangle([191, 0, 213, 131], fill=inkyphat.BLACK, outline=inkyphat.BLACK) draw_text((196, 6), time, colour=inkyphat.WHITE, rotation=90, size=16) # write to inkyphat inkyphat.show()
sprite = text_mask.crop((s_x, s_y, s_x + num_width, s_y + num_height)) inkyphat.paste(colour, (o_x, o_y), sprite) def print_number(position, number, colour): """Prints a number using the sprite sheet.""" for digit in str(number): print_digit(position, int(digit), colour) position = (position[0] + 8, position[1]) # Paint out a black rectangle onto which we'll draw our canvas inkyphat.rectangle((cal_x, cal_y, cal_x + cal_w - 1, cal_y + cal_h - 1), fill=inkyphat.BLACK, outline=inkyphat.WHITE) # The starting position of the months in our spritesheet months_x = 2 months_y = 20 # Number of months per row months_cols = 3 # The width/height of each month in our spritesheet month_w = 23 month_h = 9 # Figure out where the month is in the spritesheet month_col = (now.month - 1) % months_cols
# INSIDE readings insideT = str(d["inside"]["temp"]) insideH = str(d["inside"]["humi"]) inkyphat.text((6, 30), "IN: ", inkyphat.RED, font10) inkyphat.text((35, 25), insideT + degSign, inkyphat.RED, font28) inkyphat.text((35, 50), insideH + '%', inkyphat.BLACK, font22) # OUTSUDE readings outsideT = str(d["outside"]["temp"]) outsideP = str(d["outside"]["press"]) outsideD = str(d["outside"]["timestamp"]) OUTpressw, OUTpressh = font22.getsize(outsideP) inkyphat.text((6, 80), "OUT: ", inkyphat.RED, font10) inkyphat.text((35, 75), outsideT + degSign, inkyphat.BLACK, font22) inkyphat.text((90, 75), outsideD, inkyphat.BLACK, font10) #inkyphat.text((100+OUTpressw,82), 'mbar', inkyphat.BLACK, font10) # HEATER status Pmode = str(d["program"]["mode"]) if Pmode == 'MANUAL': Pmode = 'MAN' Ptemp = str(d["program"]["temp"]) inkyphat.rectangle((120, 26, inkyphat.WIDTH - 3, inkyphat.HEIGHT - 3), fill=inkyphat.BLACK, outline=inkyphat.BLACK) inkyphat.text((130, 30), "MODE ", inkyphat.WHITE, font10b) inkyphat.text((130, 45), Pmode, inkyphat.RED, font22) inkyphat.text((130, 80), Ptemp + ' ', inkyphat.WHITE, font10b) inkyphat.show()
print("""Inky pHAT: ICS Calendar Events List Lists upcoming events from an ICS Calendar file. """) CALENDAR_FILE = "resources/test.ics" #today = datetime.date.today() today = datetime.date(2017, 06, 01) inkyphat.set_border(inkyphat.BLACK) #inkyphat.set_rotation(180) inkyphat.rectangle((0, 0, inkyphat.WIDTH, inkyphat.HEIGHT), fill=inkyphat.BLACK) ics = icalendar.Calendar.from_ical(open(CALENDAR_FILE).read()) font = inkyphat.ImageFont.truetype(inkyphat.fonts.FredokaOne, 12) offset_x, offset_y = 10, 0 for item in ics.walk(): if isinstance(item, icalendar.Event): dtstart = item['DTSTART'].dt dtend = item['DTEND'].dt summary = item['SUMMARY'] if dtstart < today: continue
RAIN_TEXT = "\uF0E9" RAIN_TEXT_W, RAIN_TEXT_H = WEATHER_FONT.getsize(RAIN_TEXT) SNOW_TEXT = "\uF2DC" SNOW_TEXT_W, SNOW_TEXT_H = WEATHER_FONT.getsize(SNOW_TEXT) #Corresponds to all WeatherUnderground icon names SUN_LIST = ['clear', 'mostlysunny', 'partlycloudy', 'partlysunny', 'sunny'] CLOUDY_LIST = ['mostlycloudy', 'cloudy', 'fog', 'hazy'] THUNDER_LIST = ['chancetstorms', 'tstorms', 'unknown'] RAIN_LIST = ['chancerain', 'rain'] SNOW_LIST = [ 'chanceflurries', 'chancesleet', 'chancesnow', 'flurries', 'sleet', 'snow' ] try: inkyphat.rectangle([(0, 0), (211, 103)], inkyphat.WHITE) inkyphat.set_border(inkyphat.RED) inData = requests.get('http://thecore:8080/json.htm?type=devices&rid=' + INDOOR_THERMO_ID).json()['result'][0] outData = requests.get('http://thecore:8080/json.htm?type=devices&rid=' + OUTDOOR_THERMO_ID).json()['result'][0] weatherData = requests.get(WUNDERGROUND_URL) inkyphat.text((3, 3), IN_TEXT, inkyphat.BLACK, SMALL_FONT) inkyphat.text((3 + OUT_TEXT_W + 3, 3), str(inData['Temp']) + '°C', inkyphat.BLACK, LARGE_FONT) inkyphat.text((3, 3 + LARGE_FONT.getsize(str(inData['Temp']))[1] + 3), OUT_TEXT, inkyphat.BLACK, SMALL_FONT) inkyphat.text((3 + OUT_TEXT_W + 3, 3 + LARGE_FONT.getsize(str(inData['Temp']))[1] + 3),
sprite = text_mask.crop((s_x, s_y, s_x + num_width, s_y + num_height)) inkyphat.paste(colour, (o_x, o_y), sprite) def print_number(position, number, colour): """Prints a number using the sprite sheet.""" for digit in str(number): print_digit(position, int(digit), colour) position = (position[0] + 8, position[1]) # Paint out a black rectangle onto which we'll draw our canvas inkyphat.rectangle((cal_x, cal_y, cal_x + cal_w - 1, cal_y + cal_h - 1), fill=inkyphat.BLACK, outline=inkyphat.WHITE) # The starting position of the months in our spritesheet months_x = 2 months_y = 20 # Number of months per row months_cols = 3 # The width/height of each month in our spritesheet month_w = 23 month_h = 9 # Figure out where the month is in the spritesheet month_col = (now.month - 1) % months_cols
item['viewers'] = data['stream']['viewers'] STATE.append(item) sys.stdout.write('Done\n') img = Image.new('RGBA', IMG_SIZE) fnt = ImageFont.truetype(FONT_PATH, FONT_SIZE) title_text_w, title_text_h = fnt.getsize(TITLE) date_text_w, date_text_h = fnt.getsize(NOW) DATE_POSITION = ((IMG_WIDTH - date_text_w - MARGIN * 2), MARGIN) TITLE_POSITION = (MARGIN * 2, MARGIN) inkyphat.set_rotation(180) inkyphat.set_border(config['FOREGROUND_COLOR']) inkyphat.rectangle((0, 0, IMG_WIDTH, IMG_HEIGHT), fill=config['BACKGROUND_COLOR']) inkyphat.rectangle((0, 0, IMG_WIDTH, MARGIN_TOP - MARGIN), fill=config['FOREGROUND_COLOR']) inkyphat.text(DATE_POSITION, NOW, font=fnt, fill=config['BACKGROUND_COLOR']) inkyphat.text(TITLE_POSITION, TITLE, font=fnt, fill=config['BACKGROUND_COLOR']) index = 0 for stream in STATE: magic = (MARGIN * 2) right_offset = 40 text_x = MARGIN * 3 + FONT_SIZE + right_offset text_y = MARGIN_TOP + (FONT_SIZE + MARGIN) * index + magic circle_x1 = MARGIN + right_offset circle_y1 = text_y + 2 - magic
# so the name strip is carefully aligned to an 8 pixel grid # # Generally you should refresh only whole horizontal rows. # Colours either side of the update area will be washed out! # # Your refreshed area may have a white border # which could cut into surrounding colours. # # Remember: # Art smartly to update partly! inkyphat.set_partial_mode(0, 64, 0, inkyphat.WIDTH) inkyphat.show() if line_1_status_code != 10: inkyphat.rectangle((0, 0, 212, 104), inkyphat.RED) inkyphat.text((4, 60), line_1_name, inkyphat.WHITE, BOOKBOLD_MEDIUM) inkyphat.text((inkyphat.WIDTH - line_1_status_w, 60), line_1_status_text, inkyphat.WHITE, BOOK_MEDIUM) else: inkyphat.rectangle((0, 0, 212, 104), inkyphat.WHITE) inkyphat.text((4, 56), line_1_name, inkyphat.BLACK, BOOKBOLD_MEDIUM) inkyphat.text((inkyphat.WIDTH - line_1_status_w, 56), line_1_status_text, inkyphat.BLACK, BOOK_MEDIUM) inkyphat.set_partial_mode(56, 80, 0, inkyphat.WIDTH) inkyphat.show() if line_2_status_code != 10: inkyphat.rectangle((0, 0, 212, 104), inkyphat.RED) inkyphat.text((4, 80), line_2_name, inkyphat.WHITE, BOOKBOLD_MEDIUM)