1#!/usr/bin/python
2
3import os
4import logging
5from subprocess import call, check_output
6import psutil
7
8INDI_PORT = 7624
9INDI_FIFO = '/tmp/indiFIFO'
10try:
11    INDI_CONFIG_DIR = os.path.join(os.environ['HOME'], '.indi')
12except KeyError:
13    INDI_CONFIG_DIR = '/tmp/indi'
14
15
16class IndiServer(object):
17    def __init__(self, fifo=INDI_FIFO, conf_dir=INDI_CONFIG_DIR):
18        self.__fifo = fifo
19        self.__conf_dir = conf_dir
20
21        # stop running indiserver, if any
22        self.stop()
23
24    def __clear_fifo(self):
25        logging.info("Deleting fifo %s" % self.__fifo)
26        call(['rm', '-f', self.__fifo])
27        call(['mkfifo', self.__fifo])
28
29    def __run(self, port):
30        cmd = 'indiserver -p %d -m 100 -v -f %s > /tmp/indiserver.log 2>&1 &' % \
31            (port, self.__fifo)
32        logging.info(cmd)
33        call(cmd, shell=True)
34
35    def start_driver(self, driver):
36        # escape quotes if they exist
37        cmd = 'start %s' % driver.binary
38
39        if driver.skeleton:
40            cmd += ' -s "%s"' % driver.skeleton
41
42        cmd = cmd.replace('"', '\\"')
43        full_cmd = 'echo "%s" > %s' % (cmd, self.__fifo)
44        logging.info(full_cmd)
45        call(full_cmd, shell=True)
46        self.__running_drivers[driver.label] = driver
47
48    def stop_driver(self, driver):
49        # escape quotes if they exist
50        cmd = 'stop %s' % driver.binary
51
52        if "@" not in driver.binary:
53            cmd += ' -n "%s"' % driver.label
54
55        cmd = cmd.replace('"', '\\"')
56        full_cmd = 'echo "%s" > %s' % (cmd, self.__fifo)
57        logging.info(full_cmd)
58        call(full_cmd, shell=True)
59        del self.__running_drivers[driver.label]
60
61    def start(self, port=INDI_PORT, drivers=[]):
62        if self.is_running():
63            self.stop()
64
65        self.__clear_fifo()
66        self.__run(port)
67        self.__running_drivers = {}
68
69        for driver in drivers:
70            self.start_driver(driver)
71
72    def stop(self):
73        cmd = ['pkill', '-9', 'indiserver']
74        logging.info(' '.join(cmd))
75        ret = call(cmd)
76        if ret == 0:
77            logging.info('indiserver terminated successfully')
78        else:
79            logging.warn('terminating indiserver failed code ' + str(ret))
80
81    def is_running(self):
82        for proc in psutil.process_iter():
83            if proc.name() == 'indiserver':
84                return True
85        return False
86
87    def set_prop(self, dev, prop, element, value):
88        cmd = ['indi_setprop', '%s.%s.%s=%s' % (dev, prop, element, value)]
89        call(cmd)
90
91    def get_prop(self, dev, prop, element):
92        cmd = ['indi_getprop', '%s.%s.%s' % (dev, prop, element)]
93        output = check_output(cmd)
94        return output.split('=')[1].strip()
95
96    def get_state(self, dev, prop):
97        return self.get_prop(dev, prop, '_STATE')
98
99    def auto_connect(self):
100        cmd = ['indi_getprop', '*.CONNECTION.CONNECT']
101        output = ""
102        try:
103            output = check_output(cmd).decode('utf_8')
104        except Exception as e:
105            logging.error(e)
106
107        output = output.replace("Off", "On")
108
109        for dev in output.splitlines():
110            command = ['indi_setprop', dev]
111            logging.info(command)
112            call(command)
113
114    def get_running_drivers(self):
115        # drivers = [proc.name() for proc in psutil.process_iter() if
116        #            proc.name().startswith('indi_')]
117        drivers = self.__running_drivers
118        return drivers
119