Skip to content

Commit

Permalink
Add better vacuum error handling;
Browse files Browse the repository at this point in the history
Fix subprocess.Popen stdout/stderr to devnull
  • Loading branch information
mrin committed Nov 6, 2017
1 parent 65331bf commit 690e0bb
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 35 deletions.
27 changes: 13 additions & 14 deletions plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Author: mrin, 2017
#
"""
<plugin key="xiaomi-mi-robot-vacuum" name="Xiaomi Mi Robot Vacuum" author="mrin" version="0.1.0" wikilink="https://github.com/mrin/domoticz-mirobot-plugin" externallink="">
<plugin key="xiaomi-mi-robot-vacuum" name="Xiaomi Mi Robot Vacuum" author="mrin" version="0.1.1" wikilink="https://github.com/mrin/domoticz-mirobot-plugin" externallink="">
<params>
<param field="Address" label="Robot IP" width="200px" required="true" default="192.168.1.12"/>
<param field="Mode1" label="Token" width="200px" required="true" default="476e6b70343055483230644c53707a12"/>
Expand Down Expand Up @@ -36,7 +36,6 @@

import Domoticz
import subprocess
import signal
import datetime
import time

Expand Down Expand Up @@ -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':
Expand All @@ -116,19 +116,19 @@ 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',
Parameters['Address'],
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
Expand Down Expand Up @@ -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))
Expand All @@ -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':

Expand Down
20 changes: 8 additions & 12 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

Expand All @@ -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)



Expand All @@ -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))


Expand All @@ -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,
Expand Down
22 changes: 13 additions & 9 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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')
Expand All @@ -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()


0 comments on commit 690e0bb

Please sign in to comment.