def __init__(self, config):
        self.mqtt_client = mosquitto.Mosquitto()

        self.config = config

        self.live_mode = False
        self.live_queue = Queue.Queue(maxsize=int(
            self.config.get('queue_size', self.DEFAULT_QUEUE_SIZE)))

        self._ensure_config_var(self.config, 'server_host')
        self._ensure_config_var(self.config, 'server_port')

        self._ensure_config_var(self.config, 'channels')

        self.scada_client_id = self.config['client_id']

        self.last_success_timestamp = 0
        self.last_success_uid = -1
        self.last_success_item_fname = self.config.get(
            'last_success_file', '/var/lib/sensor-tools/last_success_item.dat')
        self.load_last_success_item()

        self.channel_map = {}
        for channel_id, channel in self.config['channels'].iteritems():
            device_id, control_id = channel
            self.channel_map[(str(device_id),
                              str(control_id))] = int(channel_id)

        self.scada_conn = TServerConnection(
            self.config['server_host'],
            self.config['server_port'],
            self.config.get('tcp_timeout', self.DEFAULT_TCP_TIMEOUT),
            saving_interval=self.config.get('saving_interval_prop'))

        if self.config.get('mqtt_username'):
            self.mqtt_client.username_pw_set(
                self.config['mqtt_username'],
                self.config.get('mqtt_password', ''))

        self.rpc_client = TMQTTRPCClient(self.mqtt_client)

        self.rpc_timeout = float(
            self.config.get('rpc_timeout', self.DEFAULT_RPC_TIMEOUT))
        self.mqtt_client.on_message = self.on_mqtt_message
        self.mqtt_client.on_connect = self.on_mqtt_connect

        self.mqtt_client.connect(self.config.get('mqtt_host', 'localhost'),
                                 self.config.get('mqtt_port', 1883))
        self.mqtt_client.loop_start()
Esempio n. 2
0
def main():
    parser = argparse.ArgumentParser(description='Sample RPC client', add_help=False)

    parser.add_argument('-h', '--host', dest='host', type=str,
                     help='MQTT host', default='localhost')

    parser.add_argument('-u', '--username', dest='username', type=str,
                     help='MQTT username', default='')

    parser.add_argument('-P', '--password', dest='password', type=str,
                     help='MQTT password', default='')

    parser.add_argument('-p', '--port', dest='port', type=int,
                     help='MQTT port', default='1883')

    args = parser.parse_args()
    client = mosquitto.Mosquitto()

    if args.username:
        client.username_pw_set(args.username, args.password)

    client.connect(args.host, args.port)
    client.loop_start()

    rpc_client = TMQTTRPCClient(client)
    client.on_message = rpc_client.on_mqtt_message

    #~ resp =  rpc_client.call('Driver', 'main', 'foobar', {'foo':'foo', 'bar':'bar'})

    for i in xrange(10):
        resp =  rpc_client.call('db_logger', 'history', 'get_values', {
                    'channels': [
                        [ 'wb-w1', '00-1234566789' ],
                        [ 'wb-w1', '00' ],
                        [ 'wb-adc', 'Vin'],
                    ],

                    'timestamp' : {
                        'gt': 1434728034
                    },
                    'limit' : 60
                }, 10)

        print "got result!"
        pprint.pprint(resp)
        time.sleep(5)
    def __init__(self, config):
        self.mqtt_client = mosquitto.Mosquitto()


        self.config = config

        self.live_mode = False
        self.live_queue = Queue.Queue(maxsize=int(self.config.get('queue_size', self.DEFAULT_QUEUE_SIZE)))

        self._ensure_config_var(self.config, 'server_host')
        self._ensure_config_var(self.config, 'server_port')

        self._ensure_config_var(self.config, 'channels')

        self.scada_client_id = self.config['client_id']

        self.last_success_timestamp = 0
        self.last_success_uid  = -1
        self.last_success_item_fname = self.config.get('last_success_file', '/var/lib/sensor-tools/last_success_item.dat')
        self.load_last_success_item()


        self.channel_map = {}
        for channel_id, channel in self.config['channels'].iteritems():
            device_id, control_id = channel
            self.channel_map[(str(device_id), str(control_id))]  = int(channel_id)


        self.scada_conn = TServerConnection(self.config['server_host'], self.config['server_port'],
                                            self.config.get('tcp_timeout', self.DEFAULT_TCP_TIMEOUT),
                                            saving_interval = self.config.get('saving_interval_prop'))


        if self.config.get('mqtt_username'):
            self.mqtt_client.username_pw_set(self.config['mqtt_username'], self.config.get('mqtt_password', ''))


        self.rpc_client = TMQTTRPCClient(self.mqtt_client)

        self.rpc_timeout = float(self.config.get('rpc_timeout', self.DEFAULT_RPC_TIMEOUT))
        self.mqtt_client.on_message = self.on_mqtt_message
        self.mqtt_client.on_connect = self.on_mqtt_connect

        self.mqtt_client.connect(self.config.get('mqtt_host', 'localhost'), self.config.get('mqtt_port', 1883))
        self.mqtt_client.loop_start()
Esempio n. 4
0
def main():
    parser = argparse.ArgumentParser(description='wb-mqtt-db Console Client', add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('--help', action='help',
                help='show this help message and exit')

    parser.add_argument('-h', '--host', dest='host', type=str,
                     help='MQTT host', default='localhost')

    parser.add_argument('-u', '--username', dest='username', type=str,
                     help='MQTT username', default='')

    parser.add_argument('-P', '--password', dest='password', type=str,
                     help='MQTT password', default='')

    parser.add_argument('-p', '--port', dest='port', type=int,
                     help='MQTT port', default='1883')

    parser.add_argument('--from', dest='date_from', type=str,
                     help='start date', default=None)

    parser.add_argument('--to', dest='date_to', type=str,
                     help='end date', default=None)

    parser.add_argument('--time-format', dest='time_format', type=str,
                     help='''strftime-style format string for timestamp formating. Use "%%s.%%f" for UNIX timestamp''', default="%Y-%m-%d %H:%M:%S.%f")

    parser.add_argument('--limit', dest='limit', type=int, help='The maximum number of data points to request',
        default=10000)

    i_group = parser.add_mutually_exclusive_group()

    i_group.add_argument('--interval', dest='min_interval', type=int,
                     help='Min interval between data points (ms)', default=None)

    i_group.add_argument('-a', '--auto-interval', dest='auto_interval', action="store_true",
                     help='Automatically estimate the interval between data points based on "limit", "from" and "start"')

    parser.add_argument('--decimal-places', dest='decimal_places', type=int, help='Number of decimal places in value')

    parser.add_argument('-d', '--delimiter', dest='delimiter', type=str, help='CSV field separator', default='\t')

    parser.add_argument('-o', '--output-fname', dest='output_fname', type=str, help='Write result to file. "-" means stdout', default='-')
    parser.add_argument("--timeout", dest="timeout", type=int, help="Request timeout (in seconds)")

    parser.add_argument('channels', metavar='DEVICE/CONTROL', type=str, nargs='+',
                        help='List of channels to request')


    args = parser.parse_args()

    if args.date_from:
        date_from = dateutil.parser.parse(args.date_from)
    else:
        date_from = None

    if args.date_to:
        date_to = dateutil.parser.parse(args.date_to)
    else:
        date_to = datetime.datetime.now()

    if args.min_interval:
        min_interval = args.min_interval
    else:
        min_interval = None

    if args.auto_interval:
        if args.date_from is None:
            parser.error("--from argument should be present when using -a/--auto-interval")

        time_interval = date_to - date_from
        if time_interval < datetime.timedelta(0):
            parser.error("--from is greater than --to (or in future)")
        min_interval = (time_interval / args.limit).total_seconds() * 1000



    client = mosquitto.Mosquitto()

    if args.username:
        client.username_pw_set(args.username, args.password)

    client.connect(args.host, args.port)
    client.loop_start()

    rpc_client = TMQTTRPCClient(client)
    client.on_message = rpc_client.on_mqtt_message

    channels = [channel.split('/', 2) for channel in args.channels]

    fieldnames = ['channel', 'time', 'average', 'min', 'max']
    if args.output_fname == '-':
        csvfile = sys.stdout
    else:
        csvfile = open(args.output_fname, 'wb')

    try:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames,delimiter=args.delimiter)

        for i, channel in enumerate(channels):
            rpc_params =  {
                'channels': [channel,],

                'timestamp' : {
                },
                'limit' : args.limit,
                'ver' : 1,
            }

            if args.date_from:
                rpc_params['timestamp']['gt'] = int(time.mktime(date_from.timetuple()))
            if args.date_to:
                rpc_params['timestamp']['lt'] = time.mktime(date_to.timetuple())

            if min_interval:
                rpc_params['min_interval'] = min_interval

            if args.timeout:
                rpc_params["request_timeout"] = args.timeout
                mqtt_timeout = args.timeout + 5
            else:
                mqtt_timeout = 30

            try:
                resp =  rpc_client.call('db_logger', 'history', 'get_values', rpc_params, timeout=mqtt_timeout)
            except MQTTRPCError as err:
                if err.code == -32100:
                    print("ERROR: Backend wb-mqtt-db failed to process request in time. Consider increasing timeout (--timeout).", file=sys.stderr)
                    return
                raise err

            if i == 0:
                writer.writeheader()

            # pprint.pprint(resp)
            # print(len(resp['values']))
            for row in resp['values']:
                csvrow = dict(
                    channel = ("%s/%s" % tuple(channel)),
                    time    = datetime.datetime.fromtimestamp(row.get('t') or row.get('timestamp')).strftime(args.time_format),
                    average = format_value(row.get('v') or row.get('value'), args.decimal_places)
                )
                if 'min' in row:
                    csvrow['min'] = format_value(row['min'], args.decimal_places)
                if 'max' in row:
                    csvrow['max'] = format_value(row['max'], args.decimal_places)

                writer.writerow(csvrow)
    finally:
        csvfile.close()
class TSensorToolsClient(object):
    DEFAULT_TCP_TIMEOUT = 20
    DEFAULT_QUEUE_SIZE = 100
    DEFAULT_RPC_TIMEOUT = 10
    RPC_MAX_ROWS_PER_QUERY = 100

    SERVER_FAIL_RETRY_TIMEOUT = 10
    SERVER_FAIL_RETRY_ATTEMPTS = 5

    RPC_ERROR_RETRY_TIMEOUT = 10

    def _ensure_config_var(self, obj, var):
        if var not in obj:
            raise RuntimeError('Missing mandatory option %s in config' % var)

    def load_last_success_item(self):
        if os.path.exists(self.last_success_item_fname):
            try:
                parts = open(
                    self.last_success_item_fname).read().strip().split()
                self.last_success_timestamp = float(parts[0])
                self.last_success_uid = int(parts[1])
                return
            except:
                logging.warning(
                    "can't load last sucessfull item data from file")

    def set_last_success_item(self, timestamp, uid=None):
        self.last_success_timestamp = timestamp
        if uid is not None:
            self.last_success_uid = uid

        if not os.path.exists(os.path.dirname(self.last_success_item_fname)):
            os.makedirs(os.path.dirname(self.last_success_item_fname))

        open(self.last_success_item_fname, 'wt').write(
            "%f %d\n" % (self.last_success_timestamp, self.last_success_uid))

    def __init__(self, config):
        self.mqtt_client = mosquitto.Mosquitto()

        self.config = config

        self.live_mode = False
        self.live_queue = Queue.Queue(maxsize=int(
            self.config.get('queue_size', self.DEFAULT_QUEUE_SIZE)))

        self._ensure_config_var(self.config, 'server_host')
        self._ensure_config_var(self.config, 'server_port')

        self._ensure_config_var(self.config, 'channels')

        self.scada_client_id = self.config['client_id']

        self.last_success_timestamp = 0
        self.last_success_uid = -1
        self.last_success_item_fname = self.config.get(
            'last_success_file', '/var/lib/sensor-tools/last_success_item.dat')
        self.load_last_success_item()

        self.channel_map = {}
        for channel_id, channel in self.config['channels'].iteritems():
            device_id, control_id = channel
            self.channel_map[(str(device_id),
                              str(control_id))] = int(channel_id)

        self.scada_conn = TServerConnection(
            self.config['server_host'],
            self.config['server_port'],
            self.config.get('tcp_timeout', self.DEFAULT_TCP_TIMEOUT),
            saving_interval=self.config.get('saving_interval_prop'))

        if self.config.get('mqtt_username'):
            self.mqtt_client.username_pw_set(
                self.config['mqtt_username'],
                self.config.get('mqtt_password', ''))

        self.rpc_client = TMQTTRPCClient(self.mqtt_client)

        self.rpc_timeout = float(
            self.config.get('rpc_timeout', self.DEFAULT_RPC_TIMEOUT))
        self.mqtt_client.on_message = self.on_mqtt_message
        self.mqtt_client.on_connect = self.on_mqtt_connect

        self.mqtt_client.connect(self.config.get('mqtt_host', 'localhost'),
                                 self.config.get('mqtt_port', 1883))
        self.mqtt_client.loop_start()

    def on_mqtt_message(self, mosq, obj, msg):
        if self.rpc_client.on_mqtt_message(mosq, obj, msg):
            return

        if not self.live_mode:
            return

        if not mosquitto.topic_matches_sub('/devices/+/controls/+', msg.topic):
            return

        parts = msg.topic.split('/')
        device_id = parts[2]
        control_id = parts[4]

        channel_id = self.channel_map.get((device_id, control_id))
        if channel_id:
            try:
                self.live_queue.put_nowait(
                    (datetime.datetime.now(), channel_id, msg.payload))
            except Queue.Full, exc:
                logging.info("Setting live_mode to false")
                self.live_mode = False

                # do not call Queue methods inside 'with' block!
                # Queue.join() won't work after clearing in this way
                with self.live_queue.mutex:
                    self.live_queue.queue.clear()
class TSensorToolsClient(object):
    DEFAULT_TCP_TIMEOUT = 20
    DEFAULT_QUEUE_SIZE = 100
    DEFAULT_RPC_TIMEOUT = 10
    RPC_MAX_ROWS_PER_QUERY = 100

    SERVER_FAIL_RETRY_TIMEOUT = 10
    SERVER_FAIL_RETRY_ATTEMPTS = 5

    RPC_ERROR_RETRY_TIMEOUT = 10

    def _ensure_config_var(self, obj, var):
        if var not in obj:
            raise RuntimeError('Missing mandatory option %s in config' % var)





    def load_last_success_item(self):
        if os.path.exists(self.last_success_item_fname):
            try:
                parts = open(self.last_success_item_fname).read().strip().split()
                self.last_success_timestamp = float(parts[0])
                self.last_success_uid  = int(parts[1])
                return
            except:
                logging.warning("can't load last sucessfull item data from file")


    def set_last_success_item(self, timestamp, uid = None):
        self.last_success_timestamp = timestamp
        if uid is not None:
            self.last_success_uid = uid

        if not os.path.exists(os.path.dirname(self.last_success_item_fname)):
            os.makedirs(os.path.dirname(self.last_success_item_fname))

        open(self.last_success_item_fname, 'wt').write("%f %d\n" % (self.last_success_timestamp, self.last_success_uid))


    def __init__(self, config):
        self.mqtt_client = mosquitto.Mosquitto()


        self.config = config

        self.live_mode = False
        self.live_queue = Queue.Queue(maxsize=int(self.config.get('queue_size', self.DEFAULT_QUEUE_SIZE)))

        self._ensure_config_var(self.config, 'server_host')
        self._ensure_config_var(self.config, 'server_port')

        self._ensure_config_var(self.config, 'channels')

        self.scada_client_id = self.config['client_id']

        self.last_success_timestamp = 0
        self.last_success_uid  = -1
        self.last_success_item_fname = self.config.get('last_success_file', '/var/lib/sensor-tools/last_success_item.dat')
        self.load_last_success_item()


        self.channel_map = {}
        for channel_id, channel in self.config['channels'].iteritems():
            device_id, control_id = channel
            self.channel_map[(str(device_id), str(control_id))]  = int(channel_id)


        self.scada_conn = TServerConnection(self.config['server_host'], self.config['server_port'],
                                            self.config.get('tcp_timeout', self.DEFAULT_TCP_TIMEOUT),
                                            saving_interval = self.config.get('saving_interval_prop'))


        if self.config.get('mqtt_username'):
            self.mqtt_client.username_pw_set(self.config['mqtt_username'], self.config.get('mqtt_password', ''))


        self.rpc_client = TMQTTRPCClient(self.mqtt_client)

        self.rpc_timeout = float(self.config.get('rpc_timeout', self.DEFAULT_RPC_TIMEOUT))
        self.mqtt_client.on_message = self.on_mqtt_message
        self.mqtt_client.on_connect = self.on_mqtt_connect

        self.mqtt_client.connect(self.config.get('mqtt_host', 'localhost'), self.config.get('mqtt_port', 1883))
        self.mqtt_client.loop_start()

    def on_mqtt_message(self, mosq, obj, msg):
        if self.rpc_client.on_mqtt_message(mosq, obj, msg):
            return


        if not self.live_mode:
            return

        if not mosquitto.topic_matches_sub('/devices/+/controls/+', msg.topic):
            return

        parts = msg.topic.split('/')
        device_id = parts[2]
        control_id = parts[4]

        channel_id  = self.channel_map.get((device_id, control_id))
        if channel_id:
            try:
                self.live_queue.put_nowait((datetime.datetime.now(), channel_id, msg.payload))
            except Queue.Full, exc:
                logging.info("Setting live_mode to false")
                self.live_mode = False

                # do not call Queue methods inside 'with' block!
                # Queue.join() won't work after clearing in this way
                with self.live_queue.mutex:
                    self.live_queue.queue.clear()