Exemplo n.º 1
0
def main():
    config = configparser.ConfigParser()
    # does not throw an error, just returns the empty set if the file doesn't exist
    config.read(CONFIG.BASEPATH + '/config/iGrill_config.ini')
    loglevel = config.get("Logging", "LogLevel", fallback="Error")
    logfile = config.get("Logging", "LogFile", fallback="")

    parser = argparse.ArgumentParser(
        description='Runs a thread to control the buzzer')
    parser.add_argument('-l',
                        '--log-level',
                        action='store',
                        dest='log_level',
                        default=loglevel,
                        help='Set log level, default: \'' + loglevel + '\'')
    parser.add_argument('-d',
                        '--log-destination',
                        action='store',
                        dest='log_destination',
                        default=logfile,
                        help='Set log destination (file), default: \'' +
                        logfile + '\'')
    options = parser.parse_args()

    SetupLog(options.log_level, options.log_destination)
    daemon = Daemon(host=BUZZ.DAEMON.PYRO_HOST, port=BUZZ.DAEMON.PYRO_PORT)
    buzzObj = Buzzer(daemon)
    uri = daemon.register(buzzObj, objectId=BUZZ.DAEMON.PYRO_OBJECT_ID)
    logging.debug(uri)
    daemon.requestLoop()
    logging.debug('exited requestLoop')
    daemon.shutdown()
    daemon.close()
    logging.debug('daemon closed')
    sys.exit(buzzObj.ExitCode())
Exemplo n.º 2
0
class Test_BuzzerDaemon(unittest.TestCase):
    def setUp(self):
        self.m_daemon = Daemon(host=BUZZ.DAEMON.PYRO_HOST,
                               port=BUZZ.DAEMON.PYRO_PORT)
        with mock.patch('pygrill.board.buzzer_daemon.pigpio.pi') as mockitem:
            self.m_mock_inst = mockitem.return_value
            self.m_buzzDaemon = buzzer_daemon.Buzzer(self.m_daemon,
                                                     boardIn=SSRC.BOARD.REV_sD)
            self.m_daemon.register(self.m_buzzDaemon,
                                   objectId=BUZZ.DAEMON.PYRO_OBJECT_ID)

    def tearDown(self):
        self.m_buzzDaemon.Exit()
        self.m_daemon.close()
        self.assertEqual(self.m_buzzDaemon.ExitCode(), 0)

    def test_buzzer(self):
        buzzDaemon = self.m_buzzDaemon
        mock_inst = self.m_mock_inst
        pin = SSRC.BOARD.ITEMS["Buzzer"][SSRC.BOARD.REV_sD][SSRC.BOARD.ITEM_IO]
        mock_inst.hardware_PWM.assert_called_with(pin, 2000, 0)
        buzzDaemon.Done()
        mock_inst.reset_mock()
        time.sleep(0.6)
        mock_inst.hardware_PWM.assert_any_call(pin, 2500, 500000)
        mock_inst.hardware_PWM.assert_any_call(pin, 2500, 0)
        buzzDaemon.LowBattery()
        mock_inst.reset_mock()
        time.sleep(0.6)
        mock_inst.hardware_PWM.assert_any_call(pin, 3000, 500000)
        mock_inst.hardware_PWM.assert_any_call(pin, 2000, 500000)
        buzzDaemon.Stop()
        mock_inst.reset_mock()
        time.sleep(0.1)
        mock_inst.hardware_PWM.assert_called_with(pin, 2000, 0)
Exemplo n.º 3
0
def run_maestral_daemon(config_name="maestral", run=True, log_to_stdout=False):
    """
    Wraps :class:`maestral.main.Maestral` as Pyro daemon object, creates a new instance
    and start Pyro's event loop to listen for requests on a unix domain socket. This call
    will block until the event loop shuts down.

    This command will return silently if the daemon is already running.

    :param str config_name: The name of the Maestral configuration to use.
    :param bool run: If ``True``, start syncing automatically. Defaults to ``True``.
    :param bool log_to_stdout: If ``True``, write logs to stdout. Defaults to ``False``.
    """

    from maestral.main import Maestral

    sock_name = sockpath_for_config(config_name)
    pid_name = pidpath_for_config(config_name)

    lockfile = PIDLockFile(pid_name)

    # acquire PID lock file

    try:
        lockfile.acquire(timeout=1)
    except AlreadyLocked:
        if is_pidfile_stale(lockfile):
            lockfile.break_lock()
        else:
            logger.debug(f"Maestral already running")
            return

    logger.debug(f"Starting Maestral daemon on socket '{sock_name}'")

    try:
        # clean up old socket, create new one
        try:
            os.remove(sock_name)
        except FileNotFoundError:
            pass

        daemon = Daemon(unixsocket=sock_name)

        # start Maestral as Pyro server
        ExposedMaestral = expose(Maestral)
        # mark stop_sync and shutdown_daemon as oneway methods
        # so that they don't block on call
        ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync)
        ExposedMaestral.shutdown_pyro_daemon = oneway(
            ExposedMaestral.shutdown_pyro_daemon)
        m = ExposedMaestral(config_name, run=run, log_to_stdout=log_to_stdout)

        daemon.register(m, f"maestral.{config_name}")
        daemon.requestLoop(loopCondition=m._loop_condition)
        daemon.close()
    except Exception:
        traceback.print_exc()
    finally:
        # remove PID lock
        lockfile.release()
Exemplo n.º 4
0
def run_maestral_daemon(config_name='maestral', run=True, log_to_stdout=False):
    """
    Wraps :class:`maestral.main.Maestral` as Pyro daemon object, creates a new instance
    and start Pyro's event loop to listen for requests on a unix domain socket. This call
    will block until the event loop shuts down.

    This command will return silently if the daemon is already running.

    :param str config_name: The name of the Maestral configuration to use.
    :param bool run: If ``True``, start syncing automatically. Defaults to ``True``.
    :param bool log_to_stdout: If ``True``, write logs to stdout. Defaults to ``False``.
    """
    import threading
    from maestral.main import Maestral

    sock_name = sockpath_for_config(config_name)
    pid_name = pidpath_for_config(config_name)

    lockfile = PIDLockFile(pid_name)

    if threading.current_thread() is threading.main_thread():
        signal.signal(signal.SIGTERM, _sigterm_handler)

    # acquire PID lock file

    try:
        lockfile.acquire(timeout=1)
    except (AlreadyLocked, LockTimeout):
        if is_pidfile_stale(lockfile):
            lockfile.break_lock()
        else:
            logger.debug(f'Maestral already running')
            return

    # Nice ourselves give other processes priority. We will likely only
    # have significant CPU usage in case of many concurrent downloads.
    os.nice(10)

    logger.debug(f'Starting Maestral daemon on socket "{sock_name}"')

    try:
        # clean up old socket
        try:
            os.remove(sock_name)
        except FileNotFoundError:
            pass

        daemon = Daemon(unixsocket=sock_name)

        # start Maestral as Pyro server
        ExposedMaestral = expose(Maestral)
        # mark stop_sync and shutdown_daemon as one way
        # methods so that they don't block on call
        ExposedMaestral.stop_sync = oneway(ExposedMaestral.stop_sync)
        ExposedMaestral.pause_sync = oneway(ExposedMaestral.pause_sync)
        ExposedMaestral.shutdown_pyro_daemon = oneway(
            ExposedMaestral.shutdown_pyro_daemon)
        m = ExposedMaestral(config_name, run=run, log_to_stdout=log_to_stdout)

        daemon.register(m, f'maestral.{config_name}')
        daemon.requestLoop(loopCondition=m._loop_condition)
        daemon.close()
    except Exception:
        traceback.print_exc()
    except (KeyboardInterrupt, SystemExit):
        logger.info('Received system exit')
        sys.exit(0)
    finally:
        lockfile.release()
Exemplo n.º 5
0
class Test_KasaDaemon(unittest.TestCase):

    def setUp(self):
        self.m_daemon = Daemon(host=KASA.DAEMON.PYRO_HOST,
                               port=KASA.DAEMON.PYRO_PORT)
        
        # This must be scoped oddly.  Daemon uses sockets so we don't want to mock the socket
        # object untill the daemon is setup.
        with mock.patch('pygrill.kasa.kasa_daemon.socket.socket') as mockitem:
            self.m_mock_inst = mockitem.return_value
            self.m_mock_inst.recvfrom.return_value = [kasa_daemon.Encrypt(
                TEST.KASA.DAEMON.DISCOVER_RSP), ['192.168.0.0', 9999]]
            self.m_mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader(
                TEST.KASA.DAEMON.DISCOVER_RSP)
            self.m_kasaDaemon = kasa_daemon.Kasa(self.m_daemon)
            self.m_daemon.register(
                self.m_kasaDaemon, objectId=KASA.DAEMON.PYRO_OBJECT_ID)

    def tearDown(self):
        self.m_kasaDaemon.Exit()
        self.m_daemon.close()
        self.assertEqual(self.m_kasaDaemon.ExitCode(), 0)

    def test_Power(self):
        # Since the above mock is out of scope, we must create a new mock here
        with mock.patch('pygrill.kasa.kasa_daemon.socket.socket') as mockitem:
            mock_inst = mockitem.return_value
            mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader(
                TEST.KASA.DAEMON.OFF_ON_NO_ERROR_RSP)
            self.m_kasaDaemon.TurnPlugOn()
            self.assertListEqual(self.m_kasaDaemon.GetErrors(), list())
            mock_inst.send.assert_called_with(
                kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_PLUG_ON))
            mock_inst.reset_mock()
            mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader(
                TEST.KASA.DAEMON.ON_ON_NO_ERROR_RSP)
            self.m_kasaDaemon.TurnPlugOn()
            self.assertListEqual(self.m_kasaDaemon.GetErrors(), list())
            mock_inst.send.assert_called_with(
                kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_COUNTDOWN_DELETE_AND_RUN))
            mock_inst.reset_mock()
            mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader(
                TEST.KASA.DAEMON.ON_OFF_NO_ERROR_RSP)
            self.m_kasaDaemon.TurnPlugOff()
            self.assertListEqual(self.m_kasaDaemon.GetErrors(), list())
            mock_inst.send.assert_called_with(
                kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_PLUG_OFF))
            mock_inst.reset_mock()
            mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader(
                TEST.KASA.DAEMON.OFF_OFF_NO_ERROR_RSP)
            self.m_kasaDaemon.TurnPlugOff()
            self.assertListEqual(self.m_kasaDaemon.GetErrors(), list())
            mock_inst.send.assert_called_with(
                kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_COUNTDOWN_DELETE))
            mock_inst.reset_mock()
            mock_inst.recv.return_value = kasa_daemon.EncryptWithHeader(
                TEST.KASA.DAEMON.OFF_ERROR_RSP)
            self.m_kasaDaemon.TurnPlugOff()
            mock_inst.send.assert_called_with(
                kasa_daemon.EncryptWithHeader(KASA.DAEMON.JSON_COUNTDOWN_DELETE))
            resp = list()
            resp.append(kasa_daemon.Decrypt(
                kasa_daemon.Encrypt(TEST.KASA.DAEMON.OFF_ERROR_RSP)))
            resp.append(kasa_daemon.Decrypt(
                kasa_daemon.Encrypt(TEST.KASA.DAEMON.OFF_ERROR_RSP)))
            print(self.m_kasaDaemon.GetErrors())
            self.assertListEqual(self.m_kasaDaemon.GetErrors(), resp)
            mock_inst.send.assert_called()
            mock_inst.reset_mock()

            self.assertEqual(self.m_kasaDaemon.GetActive(), False)

    def test_IP(self):
        self.assertEqual(self.m_kasaDaemon.GetIP(), "192.168.0.0")