Guest User

Untitled

a guest
Mar 2nd, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.98 KB | None | 0 0
  1. # -*- coding: UTF-8 -*-
  2.  
  3. """Reads input from GPIO with a reduced number of pins."""
  4.  
  5. import time
  6. import RPi.GPIO as GPIO
  7. from configparser import ConfigParser
  8.  
  9. class Matrix():
  10.  
  11. def __init__(self):
  12. """Sets up constants and pin numbers."""
  13. # BCM (Broadcom) numbers are used
  14. GPIO.setmode(GPIO.BCM)
  15. parser = ConfigParser()
  16. filename = 'config.ini'
  17. parser.read(filename)
  18. gpio = parser['gpio']
  19. selection = parser['selection']
  20. self.rows = list(map(int, gpio['button_rows'].split(',')))
  21. self.columns = list(map(int, gpio['button_columns'].split(',')))
  22. topics = selection['topics'].replace(" ","").split(',')
  23. actions = selection['actions'].replace(" ","").split(',')
  24. while len(actions) <= len(topics):
  25. actions.append('unassigned')
  26. self.options_array = [
  27. topics,
  28. actions
  29. ]
  30.  
  31. def get_button(self):
  32. """Findet gedrueckte Knoepfe und returnt Koordinaten falls gefunden."""
  33.  
  34. # To search for the row of a pressed button:
  35. # - set all rows to input
  36. # - set all columns to output low
  37. # - save index in row_position
  38.  
  39. row_position = -1
  40.  
  41. for i in range(len(self.columns)):
  42. GPIO.setup(self.columns[i], GPIO.OUT)
  43. GPIO.output(self.columns[i], GPIO.LOW)
  44.  
  45. for i in range(len(self.rows)):
  46. GPIO.setup(self.rows[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
  47.  
  48. for i in range(len(self.rows)):
  49. temp_read = GPIO.input(self.rows[i])
  50. if temp_read == 0:
  51. row_position = i
  52.  
  53. # cancel if no input was found
  54. if row_position < 0 or row_position >= len(self.rows):
  55. self.refresh()
  56. return
  57.  
  58. # To search for the column of a pressed button in the row:
  59. # - set all columns to input
  60. # - rows[row_position] to output
  61.  
  62. column_position = -1
  63.  
  64. for j in range(len(self.columns)):
  65. GPIO.setup(self.columns[j], GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
  66.  
  67. GPIO.setup(self.rows[row_position], GPIO.OUT)
  68. GPIO.output(self.rows[row_position], GPIO.HIGH)
  69.  
  70. for j in range(len(self.columns)):
  71. temp_read = GPIO.input(self.columns[j])
  72. if temp_read == 1:
  73. column_position = j
  74.  
  75. # cancel if no input was found
  76. if column_position < 0 or column_position >= len(self.columns):
  77. self.refresh()
  78. return
  79.  
  80. # returns coordinates of pressed button
  81. self.refresh()
  82. return self.options_array[row_position][column_position]
  83.  
  84. def refresh(self):
  85. """Resets all pin states."""
  86. for i in range(len(self.rows)):
  87. GPIO.setup(self.rows[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
  88. for j in range(len(self.columns)):
  89. GPIO.setup(self.columns[j], GPIO.IN, pull_up_down=GPIO.PUD_UP)
  90.  
  91. if __name__ == '__main__':
  92. # For testing matrix functionality
  93. while True:
  94. user_input = None
  95. while user_input is None:
  96. user_input = Matrix().get_button()
  97. print(user_input)
  98. time.sleep(.2)
  99.  
  100. #!/usr/bin/python3
  101.  
  102. """Waits for input from matrix.py and hands over selection to database_commit.py on confirmation."""
  103.  
  104. import time
  105. import signal
  106. import sys
  107. import threading
  108. import RPi.GPIO as GPIO
  109. from threading import Timer
  110. from configparser import ConfigParser
  111. from matrix import Matrix
  112. from database_commit import DatabaseCommit as database
  113.  
  114. class Controller():
  115. """Waits for input from matrix.py and hands over selection to database_commit.py on confirmation."""
  116. def __init__(self):
  117. """Sets up constants."""
  118. # Use Broadcom-Numbering
  119. GPIO.setmode(GPIO.BCM)
  120.  
  121. # Get constants from config.ini
  122. parser = ConfigParser()
  123. filename = 'config.ini'
  124. parser.read(filename)
  125.  
  126. # Pin adresses
  127. gpio = parser['gpio']
  128.  
  129. self.TOPICS_LED = list(map(int, gpio['topics_led'].split(',')))
  130. self.ACTIONS_LED = list(map(int, gpio['actions_led'].split(',')))
  131. self.CANCEL_LED = self.ACTIONS_LED[0]
  132. self.CONFIRM_LED = self.ACTIONS_LED[1]
  133. self.POST_LED = self.ACTIONS_LED[2]
  134. self.NAGIOS_LED = self.ACTIONS_LED[3]
  135.  
  136. # names, defaults, timers
  137. selection = parser['selection']
  138.  
  139. self.TOPICS = selection['topics'].replace(" ", "").split(',')
  140. self.ACTIONS = selection['actions'].replace(" ", "").split(',')
  141. self.CANCEL = self.ACTIONS[0]
  142. self.CONFIRM = self.ACTIONS[1]
  143. self.POST = self.ACTIONS[2]
  144. self.NAGIOS = self.ACTIONS[3]
  145. self.DEFAULT_SELECTION = selection['default_selection'].replace(" ", "").split(',')
  146. self.DEFAULT_LED_STATE = [False] * len(self.TOPICS_LED)
  147. self.SLEEP = float(selection['sleeptime'])
  148. self.BLINK = float(selection['blinktime'])
  149. self.SEND_DEFAULT_ON_EMPTY = bool(selection['send_default_on_empty'])
  150.  
  151. # reminder schedule
  152. schedule = parser['schedule']
  153.  
  154. self.POST_TIME = time.strptime(schedule['post'].replace(":", " "), '%H %M')
  155. self.NAGIOS_TIME = time.strptime(schedule['nagios'].replace(":", " "), '%H %M')
  156.  
  157. self.current_selection = self.DEFAULT_SELECTION[:]
  158. self.led_state = self.DEFAULT_LED_STATE[:]
  159.  
  160. # Setup the LED pins
  161. for i in range(len(self.TOPICS_LED)):
  162. GPIO.setup(self.TOPICS_LED[i], GPIO.OUT)
  163. GPIO.output(self.TOPICS_LED[i], GPIO.LOW)
  164. for i in range(len(self.ACTIONS_LED)):
  165. GPIO.setup(self.ACTIONS_LED[i], GPIO.OUT)
  166. GPIO.output(self.ACTIONS_LED[i], GPIO.LOW)
  167.  
  168. # Switch on default selection LEDs
  169. for i in range(len(self.DEFAULT_SELECTION)):
  170. for j in range(len(self.TOPICS)):
  171. if self.DEFAULT_SELECTION[i] == self.TOPICS[j]:
  172. GPIO.output(self.TOPICS_LED[j], GPIO.HIGH)
  173. self.led_state[j] = True
  174.  
  175. # Notification status
  176. self.post_notification = False
  177. self.nagios_notification = False
  178.  
  179.  
  180.  
  181. def led_reset_topics(self):
  182. """Disable all LEDs and enable default selection LEDs"""
  183. # All off
  184. for i in range(len(self.TOPICS_LED)):
  185. GPIO.output(self.TOPICS_LED[i], GPIO.LOW)
  186. # Default an
  187. for i in range(len(self.DEFAULT_SELECTION)):
  188. for j in range(len(self.TOPICS)):
  189. if self.DEFAULT_SELECTION[i] == self.TOPICS[j]:
  190. GPIO.output(self.TOPICS_LED[j], GPIO.HIGH)
  191. self.led_state[j] = True
  192. return
  193.  
  194. def continous_led_blink(blink_event, blink_thread, led):
  195. """Blink action LED continuously"""
  196. while not blink_event.isSet():
  197. GPIO.output(led, GPIO.HIGH)
  198. time.sleep(self.BLINK)
  199. event_is_set = blink_event.wait(blink_thread)
  200. if event_is_set:
  201. GPIO.output(led, GPIO.LOW)
  202. else:
  203. GPIO.output(led, GPIO.LOW)
  204. time.sleep(self.BLINK)
  205.  
  206. def led_blink(self, led_pin):
  207. """Blink action LED
  208. """
  209. t = Timer(self.BLINK, GPIO.output, [led_pin, GPIO.LOW])
  210. GPIO.output(led_pin, GPIO.HIGH)
  211. #time.sleep(.2)
  212. #GPIO.output(led_pin, GPIO.LOW)
  213. t.start()
  214. return
  215.  
  216. def dismiss_notification(self, led_pin):
  217. """Disables notification LED
  218. :param led_pin: GPIO pin number
  219. """
  220. GPIO.output(led_pin, GPIO.LOW)
  221.  
  222.  
  223. def led_toggle_topic(self, led_index):
  224. """Toggles LED state of led_index
  225. :param led_index: Index in TOPICS_LED; contains GPIO pin number"""
  226. self.led_state[led_index] = not self.led_state[led_index]
  227. if self.led_state[led_index]:
  228. GPIO.output(self.TOPICS_LED[led_index], GPIO.HIGH)
  229. else:
  230. GPIO.output(self.TOPICS_LED[led_index], GPIO.LOW)
  231. return
  232.  
  233. def handle_selection(self, user_input):
  234. """
  235. Handles de/selection of topics
  236. Returns False if selection is altered
  237. Returns True if CANCEL or COMMIT is chosen
  238. :param user_input: String, name of pressed button
  239. """
  240.  
  241. # If cancelled, reset to default selection
  242. if user_input == self.CANCEL:
  243. self.led_blink(self.CANCEL_LED)
  244. self.current_selection = self.DEFAULT_SELECTION[:]
  245. self.led_reset_topics()
  246. return True
  247.  
  248. # If selection is non-empty, commit selection
  249. # - selection array is always sorted
  250. # If selection is empty, reset to default selection
  251. # and send default selection if SEND_DEFAULT_ON_EMPTY is True
  252. elif user_input == self.CONFIRM:
  253. self.led_blink(self.CONFIRM_LED)
  254. if self.current_selection != []:
  255. #self.current_selection.sort()
  256. database().make_commit(self.current_selection)
  257. self.current_selection = self.DEFAULT_SELECTION[:]
  258. else:
  259. self.current_selection = self.DEFAULT_SELECTION[:]
  260. if self.SEND_DEFAULT_ON_EMPTY:
  261. if len(self.DEFAULT_SELECTION) > 0:
  262. database().make_commit(self.current_selection)
  263. return True
  264.  
  265. # TODO
  266. # Disable "Post" notification
  267. elif user_input == self.POST:
  268. """self.post_notification = False
  269. self.blink_thread.start()
  270. self.dismiss_notification(self.POST_LED)
  271. return False"""
  272.  
  273. # TODO
  274. # Disable "Nagios" notification
  275. elif user_input == self.NAGIOS:
  276. """self.nagios_notification = False
  277. self.dismiss_notification(self.NAGIOS_LED)
  278. return False"""
  279.  
  280. else:
  281. # Compare input with all TOPICS
  282. for i in range(len(self.TOPICS)):
  283. if user_input == self.TOPICS[i]:
  284. self.led_toggle_topic(i)
  285. already_exists = False
  286. # Delete if exists already
  287. for j in range(len(self.current_selection)):
  288. if user_input == self.current_selection[j]:
  289. already_exists = True
  290. self.current_selection.pop(j)
  291. print(user_input + " -")
  292. break
  293. # Add if does not exits yet
  294. if not already_exists:
  295. self.current_selection.append(user_input)
  296. print(user_input + " +")
  297. # Sort array
  298. # Same order as in TOPICS
  299. self.temp_selection = []
  300. for l in range(len(self.TOPICS)):
  301. self.temp_selection.append("")
  302. for i in range(len(self.TOPICS)):
  303. for j in range(len(self.current_selection)):
  304. if self.TOPICS[i] == self.current_selection[j]:
  305. self.temp_selection[i]=self.TOPICS[i]
  306. self.temp_selection = list(filter(None, self.temp_selection))
  307. self.current_selection = self.temp_selection[:]
  308. return False
  309.  
  310. def wait_for_input(self):
  311. """Wartet auf Input und gibt an handle_selection weiter."""
  312.  
  313. done_with_input = False
  314. while not done_with_input:
  315. user_input = None
  316. while user_input is None:
  317. user_input = Matrix().get_button()
  318. done_with_input = self.handle_selection(user_input)
  319. time.sleep(self.SLEEP)
  320. return
  321.  
  322. if __name__ == '__main__':
  323. GPIO.setwarnings(False)
  324. database().external_prepare_table()
  325. while True:
  326. Controller().wait_for_input()
  327. GPIO.cleanup()
  328. sys.exit(0)
  329.  
  330. #!/usr/bin/python
  331. # -*- coding: UTF-8 -*-
  332.  
  333. import datetime
  334. import time
  335. from configparser import ConfigParser
  336. from mysql.connector import MySQLConnection, Error
  337.  
  338. class DatabaseCommit():
  339.  
  340. def read_config(section, filename='config.ini'):
  341. """ Reads config.ini and returns dictionary with config from section
  342. :param filename: name of config file
  343. :param section: name of section in config file
  344. :return: dictionary with database settings
  345. """
  346.  
  347. parser = ConfigParser()
  348. parser.read(filename)
  349. config = {}
  350. if parser.has_section(section):
  351. items = parser.items(section)
  352. for item in items:
  353. config[item[0]] = item[1].replace(" ", "")
  354. else:
  355. raise Exception('{0} not found in {1} '.format(section, filename))
  356.  
  357. return config
  358.  
  359. def establish_connection(self):
  360. db_config = DatabaseCommit.read_config('mysql')
  361. conn = MySQLConnection(**db_config)
  362. if conn.is_connected():
  363. return conn
  364. else:
  365. print("Connection failed")
  366.  
  367. def prepare_table(self, cursor):
  368. # TODO check for existing tables, add any if neccessary, fill with 0
  369. database_name = DatabaseCommit.read_config('mysql')['database'].replace(" ", "")
  370. table_name = DatabaseCommit.read_config('table')['table_name'].replace(" ", "")
  371. counter_column = DatabaseCommit.read_config('table')['counter_column'].replace(" ", "")
  372. date_column = DatabaseCommit.read_config('table')['date_column'].replace(" ", "")
  373. sql = 'CREATE TABLE IF NOT EXISTS '+ table_name +' ('
  374. sql += counter_column +' INT PRIMARY KEY AUTO_INCREMENT, '
  375. sql += date_column +' DATETIME'
  376. for topic in DatabaseCommit.read_config('selection')['topics'].replace(" ", "").split(','):
  377. topic = topic.lower()
  378. sql += ', '+ topic +' BOOLEAN NOT NULL DEFAULT 0'
  379. sql += ');'
  380. print("n"+sql+"n")
  381. cursor.execute(sql)
  382. sql = ''
  383. return cursor
  384.  
  385. def external_prepare_table(self):
  386. conn = self.establish_connection()
  387. cursor = conn.cursor()
  388. self.prepare_table(cursor)
  389.  
  390. def insert_user_input(self, user_input, cursor, table_name):
  391. date_column = DatabaseCommit.read_config('table')['date_column']
  392. sql = 'INSERT INTO ' + table_name + '(' + date_column
  393. for topic in user_input:
  394. sql += ','+ topic
  395. sql += ')'
  396. sql += 'VALUES(NOW()'
  397. for topic in user_input:
  398. sql += ','+'TRUE'
  399. sql += ')'
  400. cursor.execute(sql)
  401.  
  402. def make_commit(self, user_input):
  403. conn = self.establish_connection()
  404. cursor = conn.cursor()
  405. #self.prepare_table(cursor)
  406. table_name = DatabaseCommit.read_config('table')['table_name']
  407. self.insert_user_input(user_input, cursor, table_name)
  408. cursor.execute('COMMIT;')
  409. print("made commit :")
  410. print(user_input)
  411. cursor.close()
  412. conn.close()
  413.  
  414. [gpio]
  415. button_rows = 4, 17
  416. button_columns = 18, 23, 24, 25, 12, 16
  417. topics_led = 2, 3, 27, 22, 10, 9
  418. actions_led = 11, 5, 6, 13, 19, 26
  419.  
  420. [selection]
  421. topics = topic_1, topic_2, topic_3, topic_4, topic_5, topic_6
  422. actions = Cancel, Commit, Post, Rundgang, unassigned_1, unassigned_2
  423. default_selection = topic_2
  424. sleeptime = .3
  425. blinktime = .2
  426. send_default_on_empty = True
  427.  
  428. [schedule]
  429. post = 11:30
  430. nagios = 09:30
  431.  
  432. [mysql]
  433. host = 127.0.0.1
  434. database = mydatabase
  435. user = rpi
  436. password = password
  437.  
  438. [table]
  439. table_name = test
  440. counter_column = number
  441. date_column = date
Add Comment
Please, Sign In to add comment