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 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()
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()