From 690e0bb5128e2dfe65284271330c3571271a0c09 Mon Sep 17 00:00:00 2001 From: Igor Sankovich Date: Mon, 6 Nov 2017 22:54:31 +0300 Subject: [PATCH] Add better vacuum error handling; Fix subprocess.Popen stdout/stderr to devnull --- plugin.py | 27 +++++++++++++-------------- server.py | 20 ++++++++------------ test.py | 22 +++++++++++++--------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/plugin.py b/plugin.py index c1f3aa1..29d37d6 100755 --- a/plugin.py +++ b/plugin.py @@ -3,7 +3,7 @@ # Author: mrin, 2017 # """ - + @@ -36,7 +36,6 @@ import Domoticz import subprocess -import signal import datetime import time @@ -100,13 +99,14 @@ class BasePlugin: 100: 'Full' } - subProc = None - subHost = None - subPort = None - tcpConn = None - - heartBeatCnt = 0 + def __init__(self): + self.heartBeatCnt = 0 + self.subProc = None + self.subHost = None + self.subPort = None + self.tcpConn = None + self.devnull = open(os.devnull, 'w') def onStart(self): if Parameters['Mode4'] == 'Debug': @@ -116,7 +116,6 @@ def onStart(self): self.heartBeatCnt = 0 self.subHost, self.subPort = Parameters['Mode6'].split(':') - self.subProc = subprocess.Popen([ Parameters['Mode3'], os.path.join(os.path.dirname(__file__), '.') + '/server.py', @@ -124,11 +123,12 @@ def onStart(self): Parameters['Mode1'], '--host', self.subHost, '--port', self.subPort - ], shell=False, preexec_fn=os.setsid) + ], shell=False, stdout=self.devnull, stderr=self.devnull) Domoticz.Debug('Starting MIIOServer pid:%s %s:%s' % (self.subProc.pid, self.subHost, self.subPort)) - self.tcpConn = Domoticz.Connection(Name='MIIOServer', Transport='TCP/IP', Address=self.subHost, Port=self.subPort) + self.tcpConn = Domoticz.Connection(Name='MIIOServer', Transport='TCP/IP', Protocol='None', + Address=self.subHost, Port=self.subPort) if self.iconName not in Images: Domoticz.Image('icons.zip').Create() iconID = Images[self.iconName].ID @@ -177,8 +177,7 @@ def onStart(self): def onStop(self): Domoticz.Debug("Trying stop MIIOServer pid:%s" % self.subProc.pid) - - os.killpg(os.getpgid(self.subProc.pid), signal.SIGTERM) + self.subProc.kill() def onConnect(self, Connection, Status, Description): Domoticz.Debug("MIIOServer connection status is [%s] [%s]" % (Status, Description)) @@ -188,7 +187,7 @@ def onMessage(self, Connection, Data): Domoticz.Debug("Got: %s" % result) - if 'error' in result: return + if 'exception' in result: return if result['cmd'] == 'status': diff --git a/server.py b/server.py index d5710fd..a0636fc 100644 --- a/server.py +++ b/server.py @@ -37,7 +37,7 @@ s = logging.StreamHandler(sys.stdout) s.setLevel(logging.DEBUG) -s.setFormatter(logging.Formatter("%(message)s")) +s.setFormatter(logging.Formatter("server: %(message)s")) logger = logging.getLogger('server') logger.setLevel(logging.DEBUG) @@ -64,7 +64,7 @@ def socket_incoming_connection(socket, address): for msg in unpacker: receive.put(InMsg(msg, address)) - # logger.debug('got socket msg: %s', msg) + logger.debug('got socket msg: %s', msg) sockets.pop(address) @@ -73,7 +73,7 @@ def socket_msg_sender(sockets, q): msg = q.get() if isinstance(msg, OutMsg) and msg.to in sockets: sockets[msg.to].sendall(msgpack.packb(msg, use_bin_type=True)) - # logger.debug('send reply %s', msg.to) + logger.debug('send reply %s', msg.to) @@ -88,12 +88,12 @@ def vacuum_commands_handler(ip, token, q): if hasattr(VacuumCommand, cmd): result = getattr(VacuumCommand, cmd)(vac, *msg) else: - result = {'error': 'command [%s] not found' % cmd} + result = {'exception': 'command [%s] not found' % cmd} except (DeviceException, Exception) as e: - result = {'error': 'python-miio: %s' % e} + result = {'exception': 'python-miio: %s' % e} finally: result.update({'cmd': cmd}) - # logger.debug('vac result %s', result) + logger.debug('vac result %s', result) send.put(OutMsg(result, msg.to)) @@ -105,15 +105,11 @@ def status(cls, vac): res = vac.status() if not res: return { - 'error': 'no response' - } - - if res.error_code: - return { - 'error': res.error + 'exception': 'no response' } return { + 'error': res.error if res.error_code else None, 'state_code': res.state_code, 'battery': res.battery, 'fan_level': res.fanspeed, diff --git a/test.py b/test.py index 7fbe84a..3e88e1e 100644 --- a/test.py +++ b/test.py @@ -7,6 +7,7 @@ module_paths = [x[0] for x in os.walk( os.path.join(os.path.dirname(__file__), '.', '.env/lib/') ) if x[0].endswith('site-packages') ] for mp in module_paths: sys.path.append(mp) + print('test: python modules path: %s' % mp) from msgpack import Unpacker import socket @@ -19,22 +20,23 @@ parser.add_argument('--port', type=int, default=22222) args = parser.parse_args() -print('starting server.py') +print('test: starting server.py process') -FNULL = open(os.devnull, 'w') sProc = subprocess.Popen(['python3', os.path.join(os.path.dirname(__file__), '.') + '/server.py', args.ip, args.token, '--host', args.host, '--port', str(args.port)], - shell=False, stdout=FNULL, stderr=subprocess.PIPE) -sleep(1) + shell=False) -print('trying connect to %s:%s' % (args.host, args.port)) +print('test: wait server starting... 5 seconds ') +sleep(5) + +print('test: trying connect to %s:%s' % (args.host, args.port)) client = socket.create_connection((args.host, args.port)) client.sendall(msgpack.packb(['status'], use_bin_type=True)) -print("sent request to server [status]") -print("reading response...") +print("test: sent request to server [status]") +print("test: reading response...") def _reader(client): unpacker = Unpacker(encoding='utf-8') @@ -43,17 +45,19 @@ def _reader(client): data = client.recv(4096) if not data: - print('connection closed') + print('test: connection closed') break unpacker.feed(data) for msg in unpacker: - print('got server reply', msg) + print('test: got server reply', msg) return _reader(client) +print('test: kill servery.py pid: %s' % sProc.pid) + sProc.kill()