Найти - Пользователи
Полная версия: Постоянное выполнение скрипта
Начало » Python для новичков » Постоянное выполнение скрипта
1
East
Пробую сделать включение/выключение реле на 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("Выключить выход")
doza_and
https://docs.python.org/3/library/sched.html
vic57
East
2) GUI для скрипта (попадалась информация, что цикл while будет “как-то” мешать работе GUI). Думаю попробовать PyQt или TkInter.
на PyQt можешь сделать QTimer и крути сколько угодно
http://pyqt.sourceforge.net/Docs/PyQt4/qtimer.html
East
Спасибо всем за подсказки.
Использовал 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())
Правилен ли такой подход? GUI нужен только для того, чтобы изменять значения в файле, содержащем настройки и вручную запускать планировщик после изменения данных в настройках.
PooH
Скрипт вешается на cron/at, скрипт читает конфиг. Гуй пишет в конфиг. KISS
East
Совсем не хочется работать с 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())
Так вроде бы всё работает и скрипт в фоне и gui стартует.
Допустимо ли так делать? Посоветуйте пожалуйста.

Понять бы как правильно выстроить общую архитектуру, чтобы и GUI и скрипт программы были отдельными скриптами, чтобы из GUI можно было делать вызовы методов скрипта основной программы
doza_and
East
Допустимо ли так делать? Посоветуйте пожалуйста.
Допустимо все что работает. Это наверное не рационально. Раз уж вы все равно запускаете цикл обработки сообщений Qt то вы прекрасно можете подписаться на события таймера в Qt и у вас будет на один поток меньше и меньше головной боли с синхронизацией.
Seyran
Я вероятно что то недопонимаю, но если топикстартер собирается прикрутить GUI к своему скрипту, то запущенная программа не завершиться пока пользователь не закроет окно программы. А код программы выполняется согласно своему алгоритму. Либо по какому то шедулеру (таймеру) запускается функция, либо по событию (кнопка, внешнее прерывание и тд. и т.п)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB