Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 21, 2017 20:12:21

East
Зарегистрирован: 2017-06-21
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

Пробую сделать включение/выключение реле на 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("Выключить выход")

Офлайн

#2 Июнь 21, 2017 20:58:13

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

Офлайн

#3 Июнь 21, 2017 21:31:02

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

East
2) GUI для скрипта (попадалась информация, что цикл while будет “как-то” мешать работе GUI). Думаю попробовать PyQt или TkInter.
на PyQt можешь сделать QTimer и крути сколько угодно
http://pyqt.sourceforge.net/Docs/PyQt4/qtimer.html

Офлайн

#4 Июнь 28, 2017 13:41:16

East
Зарегистрирован: 2017-06-21
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

Спасибо всем за подсказки.
Использовал 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 нужен только для того, чтобы изменять значения в файле, содержащем настройки и вручную запускать планировщик после изменения данных в настройках.

Офлайн

#5 Июнь 29, 2017 09:27:19

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

Скрипт вешается на cron/at, скрипт читает конфиг. Гуй пишет в конфиг. KISS



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#6 Июнь 29, 2017 23:03:09

East
Зарегистрирован: 2017-06-21
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

Совсем не хочется работать с 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 можно было делать вызовы методов скрипта основной программы

Офлайн

#7 Июнь 30, 2017 00:42:57

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

East
Допустимо ли так делать? Посоветуйте пожалуйста.
Допустимо все что работает. Это наверное не рационально. Раз уж вы все равно запускаете цикл обработки сообщений Qt то вы прекрасно можете подписаться на события таймера в Qt и у вас будет на один поток меньше и меньше головной боли с синхронизацией.



Отредактировано doza_and (Июнь 30, 2017 00:46:10)

Офлайн

#8 Июнь 30, 2017 09:24:53

Seyran
Зарегистрирован: 2017-06-19
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Постоянное выполнение скрипта

Я вероятно что то недопонимаю, но если топикстартер собирается прикрутить GUI к своему скрипту, то запущенная программа не завершиться пока пользователь не закроет окно программы. А код программы выполняется согласно своему алгоритму. Либо по какому то шедулеру (таймеру) запускается функция, либо по событию (кнопка, внешнее прерывание и тд. и т.п)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version