Murano Device Client is the primary library for communicating with the Exosite Murano Platform.
Project description
A library for quickly testing, evaluating and writing client software for Murano devices.
Supported features:
HTTPS Device API
MQTT Device API
TOKEN Auth
TLS Client Cert Auth
Command Line Interface (gdc --help)
Requirements
Python 2.7.9+, 3.4, 3.5, 3.6
paho-mqtt (>=1.3.1)
requests (>=2.13.0)
docopt (>=0.6.2)
six
Installation
Run the following command.
> pip install murano-client
HTTP CLI Examples
Timestamp
> gdc -H https://t41hp23nod8s00000.m2.exosite.io/ http timestamp 1527272454
Activate
> gdc -H https://t41hp23nod8s00000.m2.exosite.io/ -u myDeviceName-1 http activate 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW
Write
> gdc -H https://t41hp23nod8s00000.m2.exosite.io/ -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http write data_in '{"some": "json data"}' [204] No content
Record
> gdc -H https://t41hp23nod8s00000.m2.exosite.io/ -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http record $(date +%s) data_in '{"historical": "data"}' [204] No content
Read
> gdc -H https://t41hp23nod8s00000.m2.exosite.io/ -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http read data_in data_in={"historical": "data"}
Poll
> gdc -H 'https://t41hp23nod8s00000.m2.exosite.io/' -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http poll config_io 3000 [304] Not modified
> gdc -H 'https://t41hp23nod8s00000.m2.exosite.io/' -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http poll config_io 30000 [200] config_io={"some": "config data"}
Content
List Content
> gdc -H 'https://t41hp23nod8s00000.m2.exosite.io/' -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http content list requests_check.v1.tar.gz ota_bundle_test.v2.tar.gz ota_bundle_test.v1.tar.gz gwe.v1.5.RC68.tar.gz gwe.v1.5.RC59.tar.gz gwe.v1.5.RC58.tar.gz gwe.v1.5.RC57.tar.gz
Get Content Info
> gdc -H 'https://t41hp23nod8s00000.m2.exosite.io/' -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http content info gwe.v1.5.RC68.tar.gz application/gzip,691529,1513931066,
Download Content
> gdc -H 'https://t41hp23nod8s00000.m2.exosite.io/' -k 97eWgtm9Et5VxwuJT8NiOK7w27Ly2GS092oSxgpW http content download gwe.v1.5.RC68.tar.gz WARNING:urllib3.response:Received response with both Content-Length and Transfer-Encoding set. This is expressly forbidden by RFC 7230 sec 3.3.2. Ignoring Content-Length and attempting to process response as Transfer-Encoding: chunked. > file gwe.v1.5.RC68.tar.gz gwe.v1.5.RC68.tar.gz: gzip compressed data, last modified: Fri Dec 22 08:24:23 2017, from Unix
MQTT CLI Examples
Activate
Activate a client with via MQTT.
> gdc -H mqtt://t41hp23nod8s00000.m2.exosite.io/ -u cleanup-stuff mqtt activate oihLldO3f53dqyJYDmiRCijVsf4eQJeUxFSBnEsk
Publish
Publish a single payload with MQTT.
> gdc -H mqtt://t41hp23nod8s00000.m2.exosite.io/ -k oihLldO3f53dqyJYDmiRCijVsf4eQJeUxFSBnEsk mqtt publish \$resource/data_in "{\"time\": $(date +%s)}" rc=0, mid=1: {"time": 1528214840}
Subscribe
Subscribe to a murano client.
NOTE: MQTT Subscribe works on all resources of a Murano client. Subscribing to a specific resource is not supported. Unsubscribe is also not supported.
> gdc -H mqtt://t41hp23nod8s00000.m2.exosite.io/ -k oihLldO3f53dqyJYDmiRCijVsf4eQJeUxFSBnEsk mqtt subscribe update_interval.1528215003884000=60
Pubsub
Use this command to publish newline-delineated date to a client resource while simultaneously subscribing to its resources.
> while true do echo "{\"time\": $(date +%s)}" sleep 0.5 done | gdc -H mqtt://t41hp23nod8s00000.m2.exosite.io/ \ -k oihLldO3f53dqyJYDmiRCijVsf4eQJeUxFSBnEsk \ mqtt pubsub \ \$resource/config_io update_interval.1528215003884000=60
Client Applications
For examples of how to import this library, see the commands in the murano_client/commands/ directory.
Simple HTTP Example Application
#!/usr/bin/env python # example.py import time import uuid import json from murano_client.http import MuranoHTTP, Http_ReadWriteCodes HTTP_TIMEOUT = 5*60*1000 # 5 minutes config_io = None client_params = { "murano_host": "https://t41hp23nod8s00000.m2.exosite.io/", "murano_id": str(uuid.uuid4()), "http_timeout": 5.0, "debug": "DEBUG", } print("Client parameters: {}".format(json.dumps(client_params))) hc = MuranoHTTP(**client_params) hc.set_http_timeout(HTTP_TIMEOUT) while not hc.is_activated(): hc.http_activate() print("TOKEN: {}".format(hc.murano_token())) if not hc.is_activated(): time.sleep(HTTP_TIMEOUT) print("Starting long poll...") while True: response_handler = hc.http_long_poll( 'config_io', HTTP_TIMEOUT, time.time() ) if response_handler.code == Http_ReadWriteCodes.NotModified: print("no config_io yet...") elif response_handler.code == Http_ReadWriteCodes.OK: print(response_handler.body) config_io = json.loads(response_handler.body.strip("config_io=")) print("got config_io: {}".format(config_io)) hc.http_write('config_io', "ACK") else: print(response_handler) if config_io: print(hc.http_write('data_in', str(uuid.uuid4())))
Simple MQTT Example Application
#!/usr/bin/env python # example.py from __future__ import print_function import time import uuid import json from murano_client.mqtt import MuranoMQTT client_params = { "murano_host": "mqtt://t41hp23nod8s00000.m2.exosite.io/", "murano_id": str(uuid.uuid4()), # "debug": "DEBUG", } print("Client parameters: {}".format(json.dumps(client_params))) mc = MuranoMQTT(**client_params) mc.start() mc.Config_IO = None print("Starting activation...") if not mc.is_activated(): mc.activate() print("TOKEN: {}".format(mc.murano_token())) def on_message(cls, userdata, msg): """ Override default on_message function. """ _, resource, timestamp = msg.topic.split('/')[0:3] print("{}.{}={}".format(resource, timestamp, msg.payload)) if 'config_io' == resource: try: cls.Config_IO = json.loads(msg.payload.decode()) print("New Config_IO: {}".format(cls.Config_IO)) except ValueError: print("Invalid JSON: {}".format(msg.payload.decode())) mc.on_message = on_message print("Starting program...") mc.start() while True: if mc.Config_IO: rand_data = str(uuid.uuid4()) rc, mid = mc.publish( '$resource/data_in', rand_data, qos=0 ) print("rc={}, mid={}, data={}" .format(rc, mid, rand_data)) else: print("waiting for config_io object...") mc.loop() time.sleep(1)
Simple MuranoClient Client Applications
The MuranoClient class takes the following constructor parameters:
murano_host - Required. The application will use the appropriate protocol to communicate with Murano according to the Product settings.
murano_id - This is the device identifier (e.g. serial number, etc.).
watchlist - Provide a list of resources from which to be notified of when new data is available. NOTE: Currently only one resource is supported.
http_timeout - Specify the length of time in between Long Poll connections when using HTTP.
debug - Turn the logging up or down. Valid values are the string values DEBUG, INFO, WARNING, ERROR and CRITICAL.
The application, below, uses the MuranoClient class’s MQTT option to “echo” payloads from the config_io resource to the data_in resource.
#!/usr/bin/env python import sys import signal import time from murano_client.client import MuranoClient c = MuranoClient( murano_host='mqtt://t41hp23nod8s00000.m2.exosite.io/', murano_id=sys.argv[1], watchlist=['config_io'], http_timeout=5*60, debug='DEBUG') def stop(signal, frame): print("stopping") c.stop_all() sys.exit(0) signal.signal(signal.SIGINT, stop) c.client_activate() c.start_client() while True: data_from_murano = c.watch() if data_from_murano: c.tell( resource='data_in', timestamp=time.time(), payload=data_from_murano.payload )
The example below uses the HTTP option to periodically write the current time into the data_in resource.
IMPORTANT:
#!/usr/bin/env python import sys import signal import time from murano_client.client import MuranoClient c = MuranoClient( murano_host='https://t41hp23nod8s00000.m2.exosite.io/', murano_id=sys.argv[1], watchlist=['config_io'], http_timeout=5, debug='DEBUG' ) def stop(signal, frame): c.stop_all() sys.exit(0) signal.signal(signal.SIGINT, stop) c.client_activate() c.start_client() while True: c.tell( resource='data_in', timestamp=time.time(), payload='chirp: {}'.format(time.time()) ) print(c.watch(timeout=1.0))
INI State File
Required:
murano_host
murano_id
watchlist - comma delineated list of Murano resources
Optional:
murano_port - (https default: 443, mqtt default: 8883)
debug
murano_token
Example INI files:
##NOTE:## If client hasn’t provisioned yet, exclude murano_token. The Device class will set/save it after it activates.
# device.ini [device] murano_host = mqtt://t41hp23nod8s00000.m2.exosite.io/ murano_id = 4321 murano_port = 443 watchlist = config_io debug = DEBUG murano_token = XaFfMaOvrGxJgWk2Iftgw1cplYuZeSsUoKlKn0lb
Example application code that used the INI example, above.
#!/usr/bin/env python from murano_client.ini import Device d = Device('device.ini') d.client_activate() d.start_client() print(d.watch()) # now set a value in the watchlist
Example CLI commands that use the INI file, above.
gdc -f device.ini http timestamp gdc -f device.ini http activate gdc -f device.ini http read config_io gdc -f device.ini http write data_in '{"a": "3.14"}' gdc -f device.ini http record $(date +%s) data_in '{"a": "3.14"}' gdc -f device.ini mqtt timestamp gdc -f device.ini mqtt activate gdc -f device.ini mqtt publish \$resource/data_in '{"a": "3.14"}' gdc -f device.ini mqtt subscribe
Logging
The murano_client library has a log file rotator built in. It is utilized via system environment variables only. It supports the following parameters:
MURANO_CLIENT_DEBUG - case-insensitive, default:warning (debug|info|warning|error|critical).
MURANO_CLIENT_LOGFILE - case-sensitive, default:stderr, can override to stdout or any file path.
MURANO_CLIENT_LOG_MAX_BYTES - integer(bytes), default:1024000
MURANO_CLIENT_MAX_BACKUPS - integer(number-of-backups), default:3
export MURANO_CLIENT_DEBUG=debug
export MURANO_CLIENT_LOGFILE=/var/log/murano_client.log
export MURANO_CLIENT_LOG_MAX_BYTES=$((1024*100))
export MURANO_CLIENT_MAX_BACKUPS=2
NOTE: Any application (e.g. edged) can override the MURANO_CLIENT_DEBUG parameter during runtime with the debug=<level> keyword argument to MuranoClient objects.
Test
To execute tests:
> pip install -U tox > tox
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Hashes for murano_client-19.1.2-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c0a59251453cde7d77581b350bbabdd6feb130609834a76c0b2434b6333da3ff |
|
MD5 | fb9ae12d18210adb398b41aa5071064a |
|
BLAKE2b-256 | a5b8c7a73d959ec6a473694ba4ae011c6bd2501c45f0dcd8e97b700380e82334 |