The Core sMAP Library¶
- class smap.core.SmapInstance(root_uuid, **kwargs)[source]¶
A sMAP instance is a tree of Collections and Timeseries. A SmapInstance allows lookups based on either path or UUID, and also contains a reference to the sMAP reporting functionality.
- __init__(self, root_uuid, **reporting_args)[source]¶
Parameters: - root_uuid – a stringified UUID, or a uuid.UUID instance to be used as the identifier for the root of this sMAP tree.
- reporting_args – extra arguments passed to the smap.reporting.Reporting constructor.
- add_timeseries(path, key, units, **kwargs)[source]¶
Simple form: create a Timeseries and then add it to the SmapInstance:
ts = inst.add_timeseries('/sensor', 'my sensor key', 'V', data_type='double')
Parameters: - path – identifier indicating where to add the new resource.
- key (string) – (optional) local identifier for this timeseries. if not present uses path.
- units (string) – set the UnitofMeasure field for the Timeseries.
- kwargs – additional arguments for the Timeseries constructor.
Return type: Timeseries instance.
- add_timeseries(path, timeseries)[source]
Advanced form: add an already-existing Timeseries.
Parameters: - path – identifier indicating where the new timeseries will be mapped in. Either a string path starting with ‘/’, a string interoperable as a uuid.UUID, or a uuid.UUID instance. Must refer to a previously created Collection.
- timeseries (smap.core.Timeseries) – instance to add
Return type: Timeseries instance
- add_collection(path[, collection[, replace=False]])[source]¶
Add collection to the namespace. For instance:
inst.add_collection('/c1')
Parameters: - path (string) – path under which to add the collection
- args[0] – Collection class to add, if present
Return type: the Collection which was added
Raises: SmapException if the parent is not a collection, or the path exists.
- get_timeseries(path)[source]¶
Returns a Timeseries if an object is found matching path, or None otherwise.
- get_collection(path)[source]¶
Returns a Collection if an object with an identifier matching path is found, None otherwise
- add(path, *args, **kwargs)[source]¶
Utility to call the version of add() associated with path. The same as inst.get_timeseries(path).add(...)
- class smap.core.Timeseries(new_uuid, unit, data_type='long', timezone='America/Los_Angeles', description=None, buffersz=1, milliseconds=False, impl=None, read_limit=0, write_limit=0, autoadd=False)[source]¶
Represent a single Timeseries. A Timeseries is a single stream of scalars, with associated units.
The sMAP profile requires each time series to be associated with a data type (long or double), unit of measure, and timezone.
- __init__(new_uuid, unit, data_type='long', timezone='America/Los_Angeles', description=None, buffersz=1, milliseconds=False, impl=None, read_limit=0, write_limit=0, autoadd=False)[source]¶
Parameters: - new_uuid – a uuid.UUID
- unit (string) – the engineering units of this timeseries
- data_type (string) – the data type of the data. Options are long or double
- timezone (string) – a tzinfo-style timezone.
- description (string) – the value of sMAP Description field.
- buffersz (int) – how many readings to present when the timeseries is retrieved with a GET.
- milliseconds (bool) – if True, then the stream publishes time in units of Unix milliseconds. Otherwise, normal unix timestamps are assumed
- _add(*args)[source]¶
Add a new reading to this timeseries. This version must only be called from the twisted main loop; i.e. from a callback added with reactor.callFromThread()
Can be called with 1, 2, or 3 arguments. The forms are
- _add(value)
- _add(time, value)
- _add(time, value, seqno)
Raises SmapException: if the value’s type does not match the stream type, or was called with an invalid number of arguments.
- class smap.core.Collection(path, inst=None, description=None, *args)[source]¶
Represent a collection of sMAP resources
- __init__(path, inst=None, description=None, *args)[source]¶
Parameters: - path (string) – the path where the collection will be added
- inst (SmapInstance) – the containing SmapInstance object
- description (string) – the contents of the sMAP description field
Raises SmapSchemaException: if the resulting object does not validate
Accessing Other Properties¶
Both Collection and Timeseries overload __setattr__() to validate changes when you access fields covered by the sMAP schema. For a Collection, this means only Metadata; for a Timeseries, you have access to Metadata, Properties, and Actuator.
For instance, you can set the Metadata for either type of object like this:
ts['Metadata'] = {
'Instrument' : {
'Manufacturer' : 'Example Factory, Inc.'
}
}
This will cause the Metadata to be validated, so you may get a smap.core.SmapSchemaException from this operation.
Reporting¶
- class smap.reporting.Reporting(inst, autoflush=1.0, reportfile=None, max_size=100000)[source]¶
- __init__(inst, autoflush=1.0, reportfile=None, max_size=100000)[source]¶
Create a new report manager, responsible for delivering data to subscribers. Buffers data on disk until it can be delivered, storing up to max_size points per timeseries.
Parameters: - inst – the SmapInstance we’ll be delivering reports for.
- autoflush (float) – how often to call flush, which attempts to deliver all data.
- reportfile (string) – backing store for reporting instances and data which hasn’t been delivered yet.
- max_size (int) – the maximum number of points we will buffer for any stream.
- _flush(force=False)[source]¶
Send out json-packed report objects to registered listeners.
Parameters: force (boolean) – if True, ignore MinPeriod/MaxPeriod and force the reporting metadata to disk Return type: a twisted.internet.task.DeferredList instance which will fire when deliver to all subscribers has finished, or errBack when any fail
Utilities¶
- smap.loader.load(file, sections=, []**instargs)[source]¶
Create a sMAP instance based on the representation stored in a file.
The configuration file contains sections which refer to either reporting instances, or paths in the sMAP heirarchy. Any section whose name starts with / is treated as a resource name; sections starting with report are treated as reports.
The file must contain at least one section named /, which must contain a uuid key to set the root identifier for the source.
Parameters: - file (string) – filename of the configuration file
- instargs – arguments passed to the SmapInstance constructor.
Return smap.core.SmapInstance: the created instancev
Raises: - smap.loader.SmapLoadError – an error is encountered processing the file
- smap.core.SmapError – some other error is encountered validating the loaded object
- smap.loader.dump(inst, file)[source]¶
Dump an existing SmapInstance object to a conf file
Parameters: - inst (smap.Core.SmapInstance) – the object to dump
- file (string) – config filename
Raises IOError: if writing to the file fails
- smap.server.run(inst, port=None, logdir=None)[source]¶
Start the twisted event loop, with an HTTP server.
Parameters: - inst – a SmapInstance which you want to server.
- port (int) – port to run on
Return type: none; this function does not return
- smap.util.periodicCallInThread(fn, *args)[source]¶
Periodically enqueue a task to be run in the twisted threadpool (not in the main loop). You’ll need to call the start(interval) method on the return. Multiple copies may run concurrently, depending on the thread pool size if you do not finish fast enough.
Parameters: - fn – the function to be called
- args – arguments to be passed to fn
Return type: the twisted.internet.task.LoopingCall result
- smap.util.periodicSequentialCall(fn, *args)[source]¶
Periodically run fn(*args) in a threadpool. unlike periodicCallInThread(), will not run your task concurrently with itself – if the last invocation didn’t finish in time for your next execution, it will wait rather than running it in a different thread.
You also need to call start(interval) on the result.