Форум сайта python.su
Пробую сделать включение/выключение реле на Raspberry Pi по расписанию, написав скрипт на python. Задался вопросом как сделать так, чтобы скрипт не завершался после разового выполнения. Первая мысль - зациклить в while. Сделал - получается безумная нагрузка на проц в 30-40%. Думаю может нужно ставить что-то вроде sleep(1), но это кажется каким-то костылём. Подскажите как правильно делается на python
1) Скрипт, к-й не завершается после разового выполнения (и при этом не грузит проц)
2) GUI для скрипта (попадалась информация, что цикл while будет “как-то” мешать работе GUI). Думаю попробовать PyQt или TkInter.
Пример кода:
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys # import logging # Подключить папку с модулями sys.path.append(os.path.dirname(__file__)+'modules') # import GUI from Garden import * try: # Инициализации входов и запуск x = Garden() x.start() while True: x.watch() except Exception, e: raise e
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import RPi.GPIO as GPIO from pprint import pprint from time import gmtime, strftime class Garden: settings_file='settings.json' settings = [] def __init__(self): # Считать настройки из файла settings = self.readSettings(self.settings_file) self.setSettings(settings) def __del__(self): GPIO.cleanup() def start(self): print("Starting...") self.initGPIO() return def initGPIO(self): # Установить нумерацию GPIO GPIO.setmode(getattr(GPIO,self.settings['GPIO']['mode'])) # Установить режимы работы каналов for t,ch in self.settings['GPIO']['channels'].items(): GPIO.setup(ch, getattr(GPIO,t) ) # print("Initializing GPIO") return def readSettings(self,settings_file): """Считать настройки из файла или взять дефолтные значения""" with open(settings_file) as file: data = json.load(file) return data def setSettings(self,settings): """Установить настройки""" if not settings: return False self.settings = settings return True def setOut(self,ch,v): """Включить/выключить выхода""" GPIO.output(ch, v) def getTime(self): """Получить текущее время""" return strftime("%d.%m.%Y %H:%M", gmtime()) def watch(self): """Сверять время""" t = self.getTime() # Сверка времени. Хардкод if t == '20.06.2017 12:01': self.setOut(11,1) print("Включить выход") else: self.setOut(11,0) print("Выключить выход")
Офлайн
Офлайн
Eastна PyQt можешь сделать QTimer и крути сколько угодно
2) GUI для скрипта (попадалась информация, что цикл while будет “как-то” мешать работе GUI). Думаю попробовать PyQt или TkInter.
Офлайн
Спасибо всем за подсказки.
Использовал sched. Сделал планировщик, к-й каждый день планирует задания по настройкам из файла + на следующий день планирует запуск самого себя и так до бесконечности. Вроде всё работает нормально.
Теперь разбираюсь с GUI с использованием PyQt4.
Возник вопрос как правильно совмещать GUI и основную программу? GUI и основная программ разделены:
def main(): # Запуск основной программы g = Garden() g.start() # Запуск GUI app = QtGui.QApplication(sys.argv) form = mainform.MainForm() form.show() return app.exec_() if __name__ == "__main__": sys.exit(main())
Офлайн
Скрипт вешается на cron/at, скрипт читает конфиг. Гуй пишет в конфиг. KISS
Офлайн
Совсем не хочется работать с cron. Согласен с тем, что cron прекрасен, сам часто использую cron, но хочется обойтись без него.
sched в python как оказалось не даёт выполняться последующему коду и gui не стартует.
Появилась мысль запустить sched в отдельном потоке.
def main(): # Запуск основной программы g = Garden() t = threading.Thread(target=g.start) t.start() # Запуск GUI app = QtGui.QApplication(sys.argv) form = mainform.MainForm() form.show() return app.exec_() if __name__ == "__main__": sys.exit(main())
Офлайн
EastДопустимо все что работает. Это наверное не рационально. Раз уж вы все равно запускаете цикл обработки сообщений Qt то вы прекрасно можете подписаться на события таймера в Qt и у вас будет на один поток меньше и меньше головной боли с синхронизацией.
Допустимо ли так делать? Посоветуйте пожалуйста.
Отредактировано doza_and (Июнь 30, 2017 00:46:10)
Офлайн
Я вероятно что то недопонимаю, но если топикстартер собирается прикрутить GUI к своему скрипту, то запущенная программа не завершиться пока пользователь не закроет окно программы. А код программы выполняется согласно своему алгоритму. Либо по какому то шедулеру (таймеру) запускается функция, либо по событию (кнопка, внешнее прерывание и тд. и т.п)
Офлайн