forked from kdudkov/x10_mqtt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
heyu.py
113 lines (94 loc) · 2.58 KB
/
heyu.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# coding: utf-8
import logging
import re
import time
import os
import subprocess
from tempfile import TemporaryFile
import settings
LOG = logging.getLogger(__name__)
def alive(prc):
if not prc:
return False
return prc.poll() is None
def died_in(prc, timeout):
start = time.time()
while time.time() - start < timeout:
if not alive(prc):
return True
time.sleep(0.01)
return False
def kill_prc(prc, timeout=2):
"""
kill subprocess prc
"""
if not alive(prc):
return
prc.terminate()
if died_in(prc, timeout):
return
LOG.error('can\'t terminate prc %s' % prc.pid)
prc.kill()
if died_in(prc, timeout):
return
LOG.error('can\'t kill prc %s' % prc.pid)
os.kill(prc.pid, -9)
def run_process(cmd, timeout=10):
"""
run process with timeout
"""
if type(cmd) == bytes:
cmd = cmd.decode('utf-8')
if type(cmd) == str:
cmd = cmd.split()
if not timeout:
subprocess.Popen(cmd)
return None, None, None
try:
out = TemporaryFile()
err = TemporaryFile()
prc = subprocess.Popen(cmd, stdout=out, stderr=err)
except:
LOG.exception('error in run_process %s' % cmd)
return -1, None, None
starttime = time.time()
while 1:
if time.time() - starttime > timeout:
LOG.error('run command %s timeout' % ' '.join(cmd))
try:
kill_prc(prc)
except:
pass
return -1, None, None
if not alive(prc):
out.flush()
err.flush()
out.seek(0)
err.seek(0)
return prc.poll(), out.read().decode('utf-8'), err.read().decode('utf-8')
time.sleep(0.1)
def run_command(cmd, timeout=30, lines=False):
_, out, _ = run_process(cmd, timeout=timeout)
if lines:
return out.split('\n')
else:
return out
def send_command(cmd, addr, timeout=10):
LOG.debug('%s %s %s' % (settings.heyu_binary, cmd, addr))
try:
return run_command('%s %s %s' % (settings.heyu_binary, cmd, addr), timeout)
except Exception as e:
LOG.exception('can\'t pass cmd "%s %s" to heyu: %s' % (cmd, addr, e))
return None
def get_status(addr):
s = send_command('status', addr, 5)
if s:
m = re.search('Status(\S+)', str(s))
if m:
return m.group(1).lower()
else:
LOG.error('no status in answer - %s' % s)
return ''
return ''
if __name__ == '__main__':
print(send_command('status', 'a1'))