|
| 1 | +#!/usr/bin/python |
| 2 | +import os |
| 3 | +import time |
| 4 | +import math |
| 5 | +import logging |
| 6 | +import pygame, sys |
| 7 | +from pygame.locals import * |
| 8 | +import RPi.GPIO as GPIO |
| 9 | +from twitter import * |
| 10 | +from flowmeter import * |
| 11 | +from adabot import * |
| 12 | +from seekrits import * |
| 13 | + |
| 14 | +t = Twitter( auth=OAuth(OAUTH_TOKEN, OAUTH_SECRET, CONSUMER_KEY, CONSUMER_SECRET) ) |
| 15 | +#boardRevision = GPIO.RPI_REVISION |
| 16 | +GPIO.setmode(GPIO.BCM) # use real GPIO numbering |
| 17 | +GPIO.setup(23,GPIO.IN, pull_up_down=GPIO.PUD_UP) |
| 18 | +GPIO.setup(24,GPIO.IN, pull_up_down=GPIO.PUD_UP) |
| 19 | + |
| 20 | +# set up pygame |
| 21 | +pygame.init() |
| 22 | + |
| 23 | +# set up the window |
| 24 | +VIEW_WIDTH = 1024 |
| 25 | +VIEW_HEIGHT = 576 |
| 26 | +pygame.display.set_caption('KEGBOT') |
| 27 | +lastTweet = 0 |
| 28 | +view_mode = 'normal' |
| 29 | + |
| 30 | +# hide the mouse |
| 31 | +pygame.mouse.set_visible(False) |
| 32 | + |
| 33 | +# set up the flow meters |
| 34 | +fm = FlowMeter('metric', ["beer"]) |
| 35 | +fm2 = FlowMeter('metric', ["root beer"]) |
| 36 | +tweet = '' |
| 37 | +# set up the colors |
| 38 | +BLACK = (0,0,0) |
| 39 | +WHITE = (255,255,255) |
| 40 | + |
| 41 | +# set up the window surface |
| 42 | +windowSurface = pygame.display.set_mode((VIEW_WIDTH,VIEW_HEIGHT), FULLSCREEN, 32) |
| 43 | +windowInfo = pygame.display.Info() |
| 44 | +FONTSIZE = 48 |
| 45 | +LINEHEIGHT = 28 |
| 46 | +basicFont = pygame.font.SysFont(None, FONTSIZE) |
| 47 | + |
| 48 | +# set up the backgrounds |
| 49 | +bg = pygame.image.load('beer-bg.png') |
| 50 | +tweet_bg = pygame.image.load('tweet-bg.png') |
| 51 | + |
| 52 | +# set up the adabots |
| 53 | +back_bot = adabot(361, 151, 361, 725) |
| 54 | +middle_bot = adabot(310, 339, 310, 825) |
| 55 | +front_bot = adabot(220, 527, 220, 888) |
| 56 | + |
| 57 | +# draw some text into an area of a surface |
| 58 | +# automatically wraps words |
| 59 | +# returns any text that didn't get blitted |
| 60 | +def drawText(surface, text, color, rect, font, aa=False, bkg=None): |
| 61 | + rect = Rect(rect) |
| 62 | + y = rect.top |
| 63 | + lineSpacing = -2 |
| 64 | + |
| 65 | + # get the height of the font |
| 66 | + fontHeight = font.size("Tg")[1] |
| 67 | + |
| 68 | + while text: |
| 69 | + i = 1 |
| 70 | + |
| 71 | + # determine if the row of text will be outside our area |
| 72 | + if y + fontHeight > rect.bottom: |
| 73 | + break |
| 74 | + |
| 75 | + # determine maximum width of line |
| 76 | + while font.size(text[:i])[0] < rect.width and i < len(text): |
| 77 | + i += 1 |
| 78 | + |
| 79 | + # if we've wrapped the text, then adjust the wrap to the last word |
| 80 | + if i < len(text): |
| 81 | + i = text.rfind(" ", 0, i) + 1 |
| 82 | + |
| 83 | + # render the line and blit it to the surface |
| 84 | + if bkg: |
| 85 | + image = font.render(text[:i], 1, color, bkg) |
| 86 | + image.set_colorkey(bkg) |
| 87 | + else: |
| 88 | + image = font.render(text[:i], aa, color) |
| 89 | + |
| 90 | + surface.blit(image, (rect.left, y)) |
| 91 | + y += fontHeight + lineSpacing |
| 92 | + |
| 93 | + # remove the text we just blitted |
| 94 | + text = text[i:] |
| 95 | + |
| 96 | + return text |
| 97 | + |
| 98 | +def renderThings(flowMeter, flowMeter2, tweet, windowSurface, basicFont): |
| 99 | + # Clear the screen |
| 100 | + windowSurface.blit(bg,(0,0)) |
| 101 | + |
| 102 | + # draw the adabots |
| 103 | + back_bot.update() |
| 104 | + windowSurface.blit(back_bot.image,(back_bot.x, back_bot.y)) |
| 105 | + middle_bot.update() |
| 106 | + windowSurface.blit(middle_bot.image,(middle_bot.x, middle_bot.y)) |
| 107 | + front_bot.update() |
| 108 | + windowSurface.blit(front_bot.image,(front_bot.x, front_bot.y)) |
| 109 | + |
| 110 | + # Draw Ammt Poured |
| 111 | + text = basicFont.render("CURRENT", True, WHITE, BLACK) |
| 112 | + textRect = text.get_rect() |
| 113 | + windowSurface.blit(text, (40,20)) |
| 114 | + if fm.enabled: |
| 115 | + text = basicFont.render(fm.getFormattedThisPour(), True, WHITE, BLACK) |
| 116 | + textRect = text.get_rect() |
| 117 | + windowSurface.blit(text, (40,30+LINEHEIGHT)) |
| 118 | + if fm2.enabled: |
| 119 | + text = basicFont.render(fm2.getFormattedThisPour(), True, WHITE, BLACK) |
| 120 | + textRect = text.get_rect() |
| 121 | + windowSurface.blit(text, (40, 30+(2*(LINEHEIGHT+5)))) |
| 122 | + |
| 123 | + # Draw Ammt Poured Total |
| 124 | + text = basicFont.render("TOTAL", True, WHITE, BLACK) |
| 125 | + textRect = text.get_rect() |
| 126 | + windowSurface.blit(text, (windowInfo.current_w - textRect.width - 40, 20)) |
| 127 | + if fm.enabled: |
| 128 | + text = basicFont.render(fm.getFormattedTotalPour(), True, WHITE, BLACK) |
| 129 | + textRect = text.get_rect() |
| 130 | + windowSurface.blit(text, (windowInfo.current_w - textRect.width - 40, 30 + LINEHEIGHT)) |
| 131 | + if fm2.enabled: |
| 132 | + text = basicFont.render(fm2.getFormattedTotalPour(), True, WHITE, BLACK) |
| 133 | + textRect = text.get_rect() |
| 134 | + windowSurface.blit(text, (windowInfo.current_w - textRect.width - 40, 30 + (2 * (LINEHEIGHT+5)))) |
| 135 | + |
| 136 | + if view_mode == 'tweet': |
| 137 | + windowSurface.blit(tweet_bg,(0,0)) |
| 138 | + textRect = Rect(545,265,500,225) |
| 139 | + drawText(windowSurface, tweet, BLACK, textRect, basicFont, True, None) |
| 140 | + |
| 141 | + # Display everything |
| 142 | + pygame.display.flip() |
| 143 | + |
| 144 | +# Beer, on Pin 23. |
| 145 | +def doAClick(channel): |
| 146 | + currentTime = int(time.time() * FlowMeter.MS_IN_A_SECOND) |
| 147 | + if fm.enabled == True: |
| 148 | + fm.update(currentTime) |
| 149 | + |
| 150 | +# Root Beer, on Pin 24. |
| 151 | +def doAClick2(channel): |
| 152 | + currentTime = int(time.time() * FlowMeter.MS_IN_A_SECOND) |
| 153 | + if fm2.enabled == True: |
| 154 | + fm2.update(currentTime) |
| 155 | + |
| 156 | +def tweetPour(theTweet): |
| 157 | + try: |
| 158 | + t.statuses.update(status=theTweet) |
| 159 | + except: |
| 160 | + logging.warning('Error tweeting: ' + theTweet + "\n") |
| 161 | + |
| 162 | +GPIO.add_event_detect(23, GPIO.RISING, callback=doAClick, bouncetime=20) # Beer, on Pin 23 |
| 163 | +GPIO.add_event_detect(24, GPIO.RISING, callback=doAClick2, bouncetime=20) # Root Beer, on Pin 24 |
| 164 | + |
| 165 | +# main loop |
| 166 | +while True: |
| 167 | + # Handle keyboard events |
| 168 | + for event in pygame.event.get(): |
| 169 | + if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE): |
| 170 | + GPIO.cleanup() |
| 171 | + pygame.quit() |
| 172 | + sys.exit() |
| 173 | + elif event.type == KEYUP and event.key == K_1: |
| 174 | + fm.enabled = not(fm.enabled) |
| 175 | + elif event.type == KEYUP and event.key == K_2: |
| 176 | + fm2.enabled = not(fm2.enabled) |
| 177 | + elif event.type == KEYUP and event.key == K_9: |
| 178 | + fm.clear() |
| 179 | + elif event.type == KEYUP and event.key == K_0: |
| 180 | + fm2.clear() |
| 181 | + |
| 182 | + currentTime = int(time.time() * FlowMeter.MS_IN_A_SECOND) |
| 183 | + |
| 184 | + if currentTime - lastTweet < 5000: # Pause for 5 seconds after tweeting to show the tweet |
| 185 | + view_mode = 'tweet' |
| 186 | + else: |
| 187 | + view_mode = 'normal' |
| 188 | + |
| 189 | + if (fm.thisPour > 0.23 and currentTime - fm.lastClick > 10000): # 10 seconds of inactivity causes a tweet |
| 190 | + tweet = "Someone just poured " + fm.getFormattedThisPour() + " of " + fm.getBeverage() + " from the Adafruit kegomatic!" |
| 191 | + lastTweet = int(time.time() * FlowMeter.MS_IN_A_SECOND) |
| 192 | + fm.thisPour = 0.0 |
| 193 | + tweetPour(tweet) |
| 194 | + |
| 195 | + if (fm2.thisPour > 0.23 and currentTime - fm2.lastClick > 10000): # 10 seconds of inactivity causes a tweet |
| 196 | + tweet = "Someone just poured " + fm2.getFormattedThisPour() + " of " + fm2.getBeverage() + " from the Adafruit kegomatic!" |
| 197 | + lastTweet = int(time.time() * FlowMeter.MS_IN_A_SECOND) |
| 198 | + fm2.thisPour = 0.0 |
| 199 | + tweetPour(tweet) |
| 200 | + |
| 201 | + # reset flow meter after each pour (2 secs of inactivity) |
| 202 | + if (fm.thisPour <= 0.23 and currentTime - fm.lastClick > 2000): |
| 203 | + fm.thisPour = 0.0 |
| 204 | + |
| 205 | + if (fm2.thisPour <= 0.23 and currentTime - fm2.lastClick > 2000): |
| 206 | + fm2.thisPour = 0.0 |
| 207 | + |
| 208 | + # Update the screen |
| 209 | + renderThings(fm, fm2, tweet, windowSurface, basicFont) |
0 commit comments