Advertisement
muetzenfrosch

bakebit_nanohat_oled

Feb 29th, 2020
755
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.60 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #
  3. # BakeBit example for the basic functions of BakeBit 128x64 OLED (http://wiki.friendlyarm.com/wiki/index.php/BakeBit_-_OLED_128x64)
  4. #
  5. # The BakeBit connects the NanoPi NEO and BakeBit sensors.
  6. # You can learn more about BakeBit here:  http://wiki.friendlyarm.com/BakeBit
  7. #
  8. # Have a question about this example?  Ask on the forums here:  http://www.friendlyarm.com/Forum/
  9. #
  10. '''
  11. ## License
  12.  
  13. The MIT License (MIT)
  14.  
  15. BakeBit: an open source platform for connecting BakeBit Sensors to the NanoPi NEO.
  16. Copyright (C) 2016 FriendlyARM
  17.  
  18. Permission is hereby granted, free of charge, to any person obtaining a copy
  19. of this software and associated documentation files (the "Software"), to deal
  20. in the Software without restriction, including without limitation the rights
  21. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  22. copies of the Software, and to permit persons to whom the Software is
  23. furnished to do so, subject to the following conditions:
  24.  
  25. The above copyright notice and this permission notice shall be included in
  26. all copies or substantial portions of the Software.
  27.  
  28. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  29. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  30. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  31. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  32. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  33. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  34. THE SOFTWARE.
  35. '''
  36.  
  37. import bakebit_128_64_oled as oled
  38. from PIL import Image
  39. from PIL import ImageFont
  40. from PIL import ImageDraw
  41. import time
  42. import sys
  43. import subprocess
  44. import threading
  45. import signal
  46. import os
  47. import socket
  48. import fcntl
  49. import struct
  50. import datetime
  51.  
  52. global width
  53. width=128
  54. global height
  55. height=64
  56.  
  57. global pageCount
  58. pageCount=2
  59. global pageIndex
  60. pageIndex=0
  61. global showPageIndicator
  62. showPageIndicator=False
  63.  
  64. global pageSleep
  65. pageSleep=120
  66. global pageSleepCountdown
  67. pageSleepCountdown=pageSleep
  68.  
  69. global disableTimeSeconds
  70. disableTimeSeconds=900
  71. global disableCounter
  72. disableCounter=0
  73.  
  74. global status
  75. status = "\"enabled\""
  76.  
  77. global enabledMarkerShownSeconds
  78. enabledMarkerShownSeconds=5
  79. global enabledCounter
  80. enabledCounter=0
  81.  
  82. oled.init()  #initialze SEEED OLED display
  83. oled.setNormalDisplay()      #Set display to normal mode (i.e non-inverse mode)
  84. oled.setHorizontalMode()
  85.  
  86. global drawing
  87. drawing = False
  88.  
  89. global image
  90. image = Image.new('1', (width, height))
  91. global draw
  92. draw = ImageDraw.Draw(image)
  93. global fontb24
  94. fontb24 = ImageFont.truetype('DejaVuSansMono-Bold.ttf', 24);
  95. global font14
  96. font14 = ImageFont.truetype('DejaVuSansMono.ttf', 14);
  97. global smartFont
  98. smartFont = ImageFont.truetype('DejaVuSansMono-Bold.ttf', 10);
  99. global fontb14
  100. fontb14 = ImageFont.truetype('DejaVuSansMono-Bold.ttf', 14);
  101. global font11
  102. font11 = ImageFont.truetype('DejaVuSansMono.ttf', 11);
  103.  
  104. global lock
  105. lock = threading.Lock()
  106.  
  107. def get_ip_address(ifname):
  108.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  109.     return socket.inet_ntoa(fcntl.ioctl(
  110.         s.fileno(),
  111.         0x8915,  # SIOCGIFADDR
  112.         struct.pack('256s', ifname[:15])
  113.     )[20:24])
  114.  
  115. def get_ip():
  116.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  117.     try:
  118.         # doesn't even have to be reachable
  119.         s.connect(('10.255.255.255', 1))
  120.         IP = s.getsockname()[0]
  121.     except:
  122.         IP = '127.0.0.1'
  123.     finally:
  124.         s.close()
  125.     return IP
  126.  
  127. def draw_page():
  128.     global drawing
  129.     global image
  130.     global draw
  131.     global oled
  132.     global font
  133.     global font14
  134.     global smartFont
  135.     global width
  136.     global height
  137.     global pageCount
  138.     global pageIndex
  139.     global showPageIndicator
  140.     global width
  141.     global height
  142.     global lock
  143.     global pageSleepCountdown
  144.     global disableTimeSeconds
  145.     global disableCounter
  146.     global status
  147.     global enabledMarkerShownSeconds
  148.     global enabledCounter
  149.  
  150.     lock.acquire()
  151.     is_drawing = drawing
  152.     page_index = pageIndex
  153.     lock.release()
  154.  
  155.     if is_drawing:
  156.         return
  157.  
  158.     if disableCounter > 0:
  159.         disableCounter = disableCounter -1
  160.  
  161.     #if the countdown is zero we should be sleeping (blank the display to reduce screenburn)
  162.     if pageSleepCountdown == 1:
  163.         oled.clearDisplay()
  164.         pageSleepCountdown = pageSleepCountdown - 1
  165.         return
  166.  
  167.     if pageSleepCountdown == 0:
  168.         return
  169.  
  170.     pageSleepCountdown = pageSleepCountdown - 1
  171.  
  172.     lock.acquire()
  173.     drawing = True
  174.     lock.release()
  175.  
  176.     # Draw a black filled box to clear the image.            
  177.     draw.rectangle((0,0,width,height), outline=0, fill=0)
  178.     # Draw current page indicator
  179.     if showPageIndicator:
  180.         dotWidth=4
  181.         dotPadding=2
  182.         dotX=width-dotWidth-1
  183.         dotTop=(height-pageCount*dotWidth-(pageCount-1)*dotPadding)/2
  184.         for i in range(pageCount):
  185.             if i==page_index:
  186.                 draw.rectangle((dotX, dotTop, dotX+dotWidth, dotTop+dotWidth), outline=255, fill=255)
  187.             else:
  188.                 draw.rectangle((dotX, dotTop, dotX+dotWidth, dotTop+dotWidth), outline=255, fill=0)
  189.             dotTop=dotTop+dotWidth+dotPadding
  190.  
  191.     if page_index==0:
  192.         text = time.strftime("%A")
  193.         draw.text((2,2),text,font=font14,fill=255)
  194.         text = time.strftime("%e %b %Y")
  195.         draw.text((2,18),text,font=font14,fill=255)
  196.         text = time.strftime("%X")
  197.         draw.text((2,40),text,font=fontb24,fill=255)
  198.     elif page_index==1:
  199.         # Draw some shapes.
  200.         # First define some constants to allow easy resizing of shapes.
  201.         padding = 2
  202.         top = padding
  203.         bottom = height-padding
  204.         # Move left to right keeping track of the current x position for drawing shapes.
  205.         x = 0
  206.         try:
  207.             IPAddress = get_ip_address('eth0')
  208.         except:
  209.             IPAddress = get_ip()
  210.         cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'"
  211.         CPU = subprocess.check_output(cmd, shell = True )
  212.         cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%sMB %.2f%%\", $3,$2,$3*100/$2 }'"
  213.         MemUsage = subprocess.check_output(cmd, shell = True )
  214.         cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%dGB %s\", $3,$2,$5}'"
  215.         Disk = subprocess.check_output(cmd, shell = True )
  216.         tempI = int(open('/sys/class/thermal/thermal_zone0/temp').read());
  217.         if tempI>1000:
  218.             tempI = tempI/1000
  219.         tempStr = "CPU TEMP: %sC" % str(tempI)
  220.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .dns_queries_today"
  221.         Queries = subprocess.check_output(cmd, shell = True ).strip()
  222.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .ads_blocked_today"
  223.         AdsToday = subprocess.check_output(cmd, shell = True ).strip()
  224.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .ads_percentage_today"
  225.         AdsPercentage = subprocess.check_output(cmd, shell = True ).strip()
  226.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .clients_ever_seen"
  227.         ClientsEver = subprocess.check_output(cmd, shell = True ).strip()
  228.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .unique_clients"
  229.         ClientsUnique = subprocess.check_output(cmd, shell = True ).strip()
  230.  
  231.         draw.text((x, top+2),       "IP: " + str(IPAddress),  font=smartFont, fill=255)
  232.         draw.text((x, top+2+12),    "Queries: " + str(Queries), font=smartFont, fill=255)
  233.         draw.text((x, top+2+24),    "Blocked: " + str(AdsToday),  font=smartFont, fill=255)
  234.         draw.text((x, top+2+36),    "Percent: " + str(AdsPercentage),  font=smartFont, fill=255)
  235.         draw.text((x, top+2+48),    "Clients: " + str(ClientsUnique),  font=smartFont, fill=255)
  236.     elif page_index==3: #Disable Pi-Hole for some senconds? -- no
  237.         draw.text((2, 2),  'Disable ' + str( int(float(disableTimeSeconds)/60) ) + 'min?',  font=fontb14, fill=255)
  238.  
  239.         draw.rectangle((2,20,width-4,20+16), outline=0, fill=0)
  240.         draw.text((4, 22),  'Yes',  font=font11, fill=255)
  241.  
  242.         draw.rectangle((2,38,width-4,38+16), outline=0, fill=255)
  243.         draw.text((4, 40),  'No',  font=font11, fill=0)
  244.  
  245.     elif page_index==4: #Disable Pi-Hole for some senconds? -- yes
  246.         draw.text((2, 2),  'Disable ' + str( int(float(disableTimeSeconds)/60) ) + 'min?',  font=fontb14, fill=255)
  247.  
  248.         draw.rectangle((2,20,width-4,20+16), outline=0, fill=255)
  249.         draw.text((4, 22),  'Yes',  font=font11, fill=0)
  250.  
  251.         draw.rectangle((2,38,width-4,38+16), outline=0, fill=0)
  252.         draw.text((4, 40),  'No',  font=font11, fill=255)
  253.  
  254.     elif page_index==5:
  255.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .status"
  256.         status = subprocess.check_output(cmd, shell = True ).strip()
  257.         if str(status) == "\"disabled\"":
  258.             enabledCounter = 0
  259.             draw.text((2, 2),  'Disabled',  font=fontb14, fill=255)
  260.             if disableCounter > 0:
  261.                 draw.text((2, 20),  str(datetime.timedelta(seconds=disableCounter)),  font=fontb24, fill=255)
  262.                 draw.rectangle((2,47,int(float(width-4)*(float(disableCounter)/float(disableTimeSeconds))),47+15), outline=0, fill=255)
  263.         elif str(status) == "\"enabled\"":
  264.             disableCounter = 0
  265.             draw.text((2, 2),  'Enabled',  font=fontb14, fill=255)
  266.             if enabledCounter < enabledMarkerShownSeconds:
  267.                 enabledCounter = enabledCounter + 1
  268.             else:
  269.                 enabledCounter = 0
  270.                 update_page_index(1)
  271.         else:
  272.             draw.text((2, 2),  'Disabled',  font=fontb14, fill=255)
  273.  
  274.     oled.drawImage(image)
  275.  
  276.     lock.acquire()
  277.     drawing = False
  278.     lock.release()
  279.  
  280.  
  281. def is_showing_disable_msgbox():
  282.     global pageIndex
  283.     lock.acquire()
  284.     page_index = pageIndex
  285.     lock.release()
  286.     if page_index==3 or page_index==4:
  287.         return True
  288.     return False
  289.  
  290. def update_page_index(pi):
  291.     global pageIndex
  292.     lock.acquire()
  293.     pageIndex = pi
  294.     lock.release()
  295.  
  296. def receive_signal(signum, stack):
  297.     global pageIndex
  298.     global pageSleepCountdown
  299.     global pageSleep
  300.     global disableTimeSeconds
  301.     global disableCounter
  302.     global status
  303.  
  304.     if pageSleepCountdown == 0:
  305.         image1 = Image.open('pihole.png').convert('1')
  306.         oled.drawImage(image1)
  307.         time.sleep(0.5)
  308.  
  309.     pageSleepCountdown = pageSleep #user pressed a button, reset the sleep counter
  310.  
  311.     lock.acquire()
  312.     page_index = pageIndex
  313.     lock.release()
  314.  
  315.     #if page_index==5:
  316.     #    return
  317.  
  318.     if signum == signal.SIGUSR1:
  319.         print 'K1 pressed'
  320.         if is_showing_disable_msgbox():
  321.             if page_index==3:
  322.                 update_page_index(4)
  323.             else:
  324.                 update_page_index(3)
  325.             draw_page()
  326.         else:
  327.             pageIndex=0
  328.             draw_page()
  329.  
  330.     if signum == signal.SIGUSR2:
  331.         print 'K2 pressed'
  332.         if is_showing_disable_msgbox():
  333.             if page_index==4:
  334.                 cmd = "curl -f -s \"http://127.0.0.1/admin/api.php?disable=" + str(disableTimeSeconds) + "&auth=$(docker exec -i pihole grep -oPi \"(?<=WEBPASSWORD\=).+\" /etc/pihole/setupVars.conf)\" | jq .status"
  335.                 status = subprocess.check_output(cmd, shell = True )
  336.                 lock.acquire()
  337.                 disableCounter=disableTimeSeconds
  338.                 lock.release()
  339.                 update_page_index(5)
  340.                 draw_page()
  341.             else:
  342.                 update_page_index(0)
  343.                 draw_page()
  344.         else:
  345.             update_page_index(1)
  346.             draw_page()
  347.  
  348.     if signum == signal.SIGALRM:
  349.         print 'K3 pressed'
  350.         cmd = "curl -f -s http://127.0.0.1/admin/api.php | jq .status"
  351.         status = subprocess.check_output(cmd, shell = True ).strip()
  352.         if str(status) == "\"disabled\"":
  353.             enabledCounter = 0
  354.             update_page_index(5)
  355.             draw_page()
  356.         elif is_showing_disable_msgbox():
  357.             update_page_index(0)
  358.             draw_page()
  359.         else:
  360.             update_page_index(3)
  361.             draw_page()
  362.  
  363.  
  364. image0 = Image.open('pihole.png').convert('1')
  365. oled.drawImage(image0)
  366. time.sleep(2)
  367.  
  368. signal.signal(signal.SIGUSR1, receive_signal)
  369. signal.signal(signal.SIGUSR2, receive_signal)
  370. signal.signal(signal.SIGALRM, receive_signal)
  371.  
  372. while True:
  373.     try:
  374.         draw_page()
  375.  
  376.         lock.acquire()
  377.         page_index = pageIndex
  378.         lock.release()
  379.  
  380.         time.sleep(1)
  381.     except KeyboardInterrupt:
  382.         break
  383.     except IOError:
  384.         print ("Error")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement