Timeseries Documentation#
For general users Stream and StreamSet should be the major classes of interest.
Avoid using the timeseries client and instead use pingthings.Client as the main interaction point with the system.
Stream#
- class pingthings.timeseries.Stream#
Bases:
object- aligned_windows_iter(start, end, point_width, version=None, schema=None)#
Return statistical summary timeseries data aligned with the internal tree structure of the database.
Query BTrDB for aggregates (or roll ups or windows) of the time series with
versionbetween timestart(inclusive) andend(exclusive) in nanoseconds[start, end). Each point returned is a statistical aggregate of all the raw data within a window of width2**pointwidthnanoseconds. These statistical aggregates currently include themean,minimum,maximum,count, andstandard deviationof the data composing the window.Note
Understanding
aligned_windowsqueriesstartis inclusive, butendis exclusive.Results will be returned for all windows that start in the interval \([start, end)\).
If \(end < start + 2^{pointwidth}\), you will not get any results.
If
startandendare not powers of two, the bottompointwidthbits will be cleared, aligning them to the nearest multiple of \(2^{pointwidth}\). For example, if you query data between[31, 121)withpointwidth = 4, the actual query will be performed on[16, 112].Each window will contain statistical summaries of the window.
Statistical points with
count == 0will be omitted.
Tip
Memory efficient queries
For long time ranges with small window widths (many statistical summaries), using the
_itermethods is significantly more memory efficient. These methods return data in batches, which are guaranteed to be returned in sorted order, allowing you to query much larger time ranges.- Parameters:
start – Start time to get data (inclusive)
end – End time for the data query (exclusive)
point_width – What size statistical windows to return, aligned to a size of the internal tree. Value will be interpreted as \(2^{point\_width}\).
width – The size of statistical windows to return, will contain summaries of the data between
starttoendof sizewidth, this is mutually exclusive withpoint_width.version – What version of the stream to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,statistical summary timeseries be returned as, default will be the server default.
- Yields:
Statistical summary timeseries of the stream between \([start, end)\)
- annotations(copy=True, refresh=None)#
Return the metadata that is not present in the tag-metadata of the stream.
- Parameters:
copy – Should the returned dict be copied or passed by reference, by default True
refresh – Do we need to get the latest metadata from the platform first, by default False
- Returns:
A mapping of annotation metadata key,value pairs.
- changes(from_version, to_version, resolution)#
Return a list of intervals of time that have changed between two versions.
Unlike the
_iterversion, this method buffers and returns the changed intervals in a single list.Warning
Advanced user feature
This method can have unexpected return values if you are not familiar with the underlying timeseries database that is part of the PredictiveGrid platform.
Note
Time ranges can overlap with previously inserted data
The returned timeranges will not be exact start and end times for the data inserted. Instead, they will be aligned as closely as they can be, but also in aligment with the underlying database’s tree structure.
- Parameters:
from_version – The stream version to compare from (exclusive).
to_version – The stream version to compare to (inclusive).
resolution – The “coarseness” of change detection in tree width. A resolution of
0typically returns the finest granularity of changed intervals (which is still aligned with our internal tree structure), a resolution of30, would be aligned exactly as a pointwidth of2^30nanoseconds. This resolution is the same as apointwidth, please refer to the explanation page here on stat point widths of our tree.
- Returns:
A list of dictionaries representing changed intervals. Typically each dictionary looks like:
{"start": <nanosecond_timestamp>, "end": <nanosecond_timestamp>}.- Return type:
list[dict[str, int] | None]
Examples
>>> # Suppose we want to iterate over all changes between version 9 and 42 >>> for changed_range in stream.changes(from_version=9, to_version=42, resolution=0): ... print("Changed interval:", changed_range)
>>> # Suppose we want to iterate over all changes between version 9 and 42 and get the lastest data that has not been inserted yet >>> for changed_range in stream.changes(from_version=9, to_version=0, resolution=0): ... print("Changed interval:", changed_range)
- changes_iter(from_version, to_version, resolution)#
Return the intervals of time that have changed between two versions as a generator.
Tip
Memory efficient queries
This method yields each changed interval one at a time. If you need to process many intervals without storing them all in memory at once, this
_itermethod is more memory efficient than its non-iter counterpart.Warning
Advanced user feature
This method can have unexpected return values if you are not familiar with the underlying timeseries database that is part of the PredictiveGrid platform.
Note
Time ranges can overlap with previously inserted data
The returned timeranges will not be exact start and end times for the data inserted. Instead, they will be aligned as closely as they can be, but also in aligment with the underlying database.
- Parameters:
from_version – The stream version to compare from.
to_version – The stream version to compare to.
resolution – The “coarseness” of change detection in tree width. A resolution of
0typically returns the finest granularity of changed intervals (which is still aligned with our internal tree structure), a resolution of30, would be aligned exactly as a pointwidth of2^30nanoseconds. This resolution is the same as apointwidth, please refer to the explanation page here on stat point widths of our tree.
- Yields:
dict[str, int] – A dictionary representing a changed interval, with a structure like:
{"start": <nanosecond_timestamp>, "end": <nanosecond_timestamp>}.
Examples
>>> # Suppose we want to iterate over all changes between version 9 and 42 >>> for changed_range in stream.changes_iter(from_version=9, to_version=42, resolution=0): ... print("Changed interval:", changed_range)
>>> # Suppose we want to iterate over all changes between version 9 and 42 and get the lastest data that has not been inserted yet >>> for changed_range in stream.changes_iter(from_version=9, to_version=0, resolution=0): ... print("Changed interval:", changed_range)
- collection#
- count(start=None, end=None, version=None, precise=None)#
Get the total count of raw measurements that are present in the stream.
- Parameters:
start – Bound the lower end of this query by a start time, by default MINIMUM_TIME.
end – Bound the upper end of this query by an end time, by default MAXIMUM_TIME
version – Version of the stream to query against, by default None, which means a version of 0 is used.
precise – Do we need an exact count or is an estimate reasonable, by default False
- Returns:
Count of points in the stream.
- delete(start, end)#
“Delete” all points between
[start, end)“Delete” all points between
start(inclusive) andend(exclusive), both in nanoseconds.Note
This is a soft delete
The PingThings timeseries data structure has persistent multiversioning. This means that the deleted points will still exist as part of an older version of the stream.
- Parameters:
start – Time to begin deleting points in the stream (inclusive).
end – Time to stop deleting points in the stream (exclusive).
- Returns:
The updated version number of the stream.
- earliest(version=None)#
Find the earliest point (in time) that is present in the stream at
version.- Parameters:
version – The version of the stream to query against, by default None, which means a version of 0 will be used.
- Returns:
The earliest point in the stream at
version.
- flush()#
Force a flush of the buffered data to persistent storage.
If data was present, the version number will be positively incremented.
- Returns:
The major version of the stream after the flush.
- get_latest_version()#
Get the current version of the stream.
- Returns:
The version number of the stream.
- get_retention(copy=True, refresh=None)#
Get the retention policy of the stream.
- Parameters:
copy – Should the returned dict be copied or passed by reference, by default True
refresh – Do we need to get the latest metadata from the platform first, by default True
- Returns:
Retention policy.
Examples
>>> stream_a.get_retention() {} >>> stream_b.get_retention() {'remove_older_than': datetime.timedelta(hours=2)}
- get_version_at_time(pytime)#
Return the version of the stream at the time provided.
- Parameters:
realtime – The time to check the version of the stream at, in nanoseconds.
- Returns:
The version of the stream at time
realtime.
- insert(data, merge_policy=None, round_spec=None)#
Add new timeseries data to the stream.
Tip
Default merge policy has changed!
Starting with the new
pingthingsapi, the default merge policy is nowreplace. Please refer tothe merge policy docsTip
Data must follow a specific schema for insertion
Your
datapyarrowtable or record batch must have a schema that matches theTIME_VALUE_F64_SCHEMA, defined. Order of the columns matter.- Parameters:
data – A pyarrow table or record batch of time series data.
merge_policy – How should the database handle data with the same timestamp, by default “replace”
round_spec – Set how many bits of precision to keep inserted data. Default behavior is the full 64 bits.
- Returns:
The version of the stream after data insertion, this number can increment multiple times depending on how many points are inserted.
- latest(version=None)#
Find the latest point (in time) that is present in the stream at
version.- Parameters:
version – The version of the stream to query against, by default None, which means a
versionof 0 will be used.- Returns:
The latest point in the stream, if present.
- name#
- nearest(time, backward=None, version=None)#
Get the nearest datapoint at
timewithversion.- Parameters:
time – The time to query for the nearest point.
backward – Can the query find the closest time that is before
time, by default Falseversion – Version of the stream to query against, by default None, which means version 0 will be used.
- Returns:
The time,value Point that is closest to the time in question, if available.
- obliterate()#
Completely remove the stream from the platform.
Danger
Will delete data!
Obliterating the stream will remove the stream, as well as all of its data! This stream will no longer be accessible, make sure you are completely sure you want to do this. If you have
Adminprivileges, you can obliterate streams!
- pin_version(version)#
Set the version of the stream to a specific version number, useful when wanting reproducible data queries.
Default behavior is to pin the stream to the latest version number when this method is executed.
Tip
Useful version number
If you do not want to pin the stream to a version and want to instead always use the latest version of the stream, which includes data that is being streamed into the platform, use a version number of
0. This is a “magic” value which tells the platform to always use the latest data it can find.- Parameters:
version – Version number to pin the stream to, by default None, which will pin the stream to its latest version, as returned by
Stream.get_latest_version.- Returns:
The version pinned.
- pinned_version#
- precise_windows_iter(start, end, width, depth=0, version=None, schema=None)#
Return custom-sized statistical summaries of the data.
Note
Understanding
windowsquerieswindowsreturns arbitrary precision statistical summary windows from the platform.It is slower than
aligned_windows, but can be significantly faster than raw value queries (raw_values).
Each returned window will be
widthnanoseconds long.startis inclusive, butendis exclusive (e.g., ifend < start + widthyou will get no results).Results will be returned for all windows that start at a time less than the
endtimestamp.If (
end - start) is not a multiple ofwidth, thenendwill be decreased to the greatest value less thanendsuch that (end - start) is a multiple ofwidth(i.e., we setend = start + width * floordiv(end - start, width)).Windows that have no data points
count==0will be omitted from the returned table
Tip
Memory efficient queries
For long time ranges with small window widths (many statistical summaries), using the
_itermethods is significantly more memory efficient. These methods return data in batches, which are guaranteed to be returned in sorted order, allowing you to query much larger time ranges.- Parameters:
start – Start time to get data (inclusive)
end – End time for the data query (exclusive)
width – The size of statistical windows to return, will contain summaries of the data between
starttoendof sizewidth.depth – What is the maximum tradeoff in computation of the statistical summaries by how far we need to walk down the tree, by default 0 is the most accurate, and a range of 0->63 can be used based on the time range of data.
version – What version of the stream to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,statistical summary timeseries be returned as, default will be the server default.
- Yields:
The statistical summary information of the stream as a timeseries.
- raw_values(start, end, version=None, schema=None)#
Return the raw time,value pairs of data from the stream between
startandend.- Parameters:
start – Start time to get data (inclusive)
end – End time for the data query (exclusive)
version – What version of the stream to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,value pairs be returned as, default will be the server default.
- Returns:
A table of timeseries data in the interval of [start, end)
- raw_values_iter(start, end, version=None, schema=None)#
Return the raw timeseries data from the stream between
startandend, but as an iterator instead of buffering all at once.Tip
Memory efficient queries
If you are working with a lot of raw data and can afford to do processing in batches (which are guaranteed to return in sorted order), the
_iterbased methods are much more memory efficient and allow you to query much larger ranges of time.- Parameters:
start – Start time to get data (inclusive)
end – End time for the data query (exclusive)
version – What version of the stream to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,value pairs be returned as, default will be the server default.
- Yields:
Tables of timeseries data from the stream in the interval of [start, end)
Examples
Query for a large range of data and process in batches.
>>> value_generator = stream.raw_values_iter(start, end) >>> value_counter = 0 >>> for batch in value_generator: >>> value_counter += batch.num_rows >>> print(f"Processed {value_counter} rows")
- refresh_metadata()#
Retrieve and update all metadata for this stream.
This will update the
tagsandannotationsfor the stream as well as any other metadata that might not be set during manual instantiation of theStreamobject
- set_retention(remove_older_than=None)#
Set retention policy on a stream.
- Parameters:
remove_older_than – Trim time period after which the data can be removed. Specifying
Noneor not passing the parameter disables trimming.
Examples
Keep the data for only two hours.
>>> stream.set_retention(datetime.timedelta(hours=2))
- tags(copy=True, refresh=None)#
Return the tag-based metadata of the stream.
- Parameters:
copy – Should the tag dictionary be copied or passed by reference, by default True
refresh – Do we need to query the platform to get the metadata first, by default False
- Returns:
A mapping of tag metadata key,value pairs.
- update(collection=None, tags=None, annotations=None, replace_tags=None, replace_annotations=None)#
Update the stream metadata.
tagsmust be from one of the below fields.- Parameters:
collection – Change the collection the stream is located under, by default
Nonetags – Update any tag metadata of the stream, by default
Noneannotations – Update any non-tag metadata of the stream, by default
Nonereplace_tags – If you want to fully replace the current stream
tagswith the ones provided here, set toTrue, by default Falsereplace_annotations – If you want to fully replace the current stream
annotationsmetadata with the ones provided here set toTrueby defaultFalse.
Note
Update Behavior
This function updates a field if it has been set, otherwise it inserts a new value. Not passing a value for an existing field will not clear the value from that field. For that you must choose
replace=True. Ifreplace=Truenamecan not beNoneor an empty string.Tip
Available tags in the
streamtablecolumn_name
Description
name
name of the stream
source
Where did the stream come from
device_id
What device is the stream attached to
samples_per_second
What is the nominal report rate of the data, in Hz?
time_precision
How accurate is each timestep (+- nanoseconds)
value_precision
Bit precision
dynamic
Can the timeseries stream send us data at varying report rates?
continuous
Should we expect a continuous stream of data?
description
Additional information about the timeseries stream
alt_name
Additional name that the stream may be referenced by
alt_id
Alternative ID (most likely SignalID from STTP)
norm_factor
A factor to scale the measurement by to normalize. Like “baseKV” for voltage, etc.
scaling_factor
The “m” in y=mx + b factor, line-line scaling factor, etc
bias_factor
The “b” in y=mx+b
hidden
Whether the stream should be presented to non-admin users
unit
Unit of measurement of the stream data
unit_id
unit_id for the corresponding unit in the unit table
- uuid#
- windowed_values(start, end, width, precise=None, version=None, schema=None, depth=0)#
Return statistical summaries of the data.
- Parameters:
start – The approximate start time to get data (inclusive). See notes.
end – The approximate end time for the data query (exclusive). See notes.
width – The approximate size of statistical windows to return, will contain summaries of the data between
starttoendof sizewidth.precise – Pass in
precise=Trueto use the exactstart,endandwidthvalues specified. See notes.version – What version of the stream to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,statistical summary timeseries be returned as, default will be the server default.
- Returns:
The statistical summary information of the stream as a timeseries.
Notes
By default (
precise=False), the values provided tostart,endandwidthmay not fully align with the values actually used by the query. Instead, the window width used will be the largest power of 2 ns that is smaller than the providedwindow. Doing so aligns the query with BTrDB’s internal tree structure and thus increases query performance by several orders of magnitude.Consequently, the actual time-range of the data pulled will be the aligned values that fall within the range
[start, end).
StreamSet#
- class pingthings.timeseries.StreamSet(streams)#
Bases:
object- annotations(copy=True, refresh=None)#
Return the metadata that is not present in the tag-metadata of the StreamSet.
- Parameters:
copy – Should the returned dict be copied or passed by reference, by default True
refresh – Do we need to get the latest metadata from the platform first, by default False
- Returns:
A mapping of annotation metadata key,value pairs.
- changes(from_version_map, to_version_map, resolution)#
Return a mapping of intervals of time that have changed between two versions for each stream.
Warning
Advanced user feature
This method can have unexpected return values if you are not familiar with the underlying timeseries database that is part of the PredictiveGrid platform.
Note
Time ranges can overlap with previously inserted data
The returned timeranges will not be exact start and end times for the data inserted. Instead, they will be aligned as closely as they can be, but also in aligment with the underlying database’s tree structure.
- Parameters:
from_version_map – The stream versions to compare from (exclusive).
to_version_map – The stream versions to compare to (inclusive).
resolution – The “coarseness” of change detection in tree width. A resolution of
0typically returns the finest granularity of changed intervals (which is still aligned with our internal tree structure), a resolution of30, would be aligned exactly as a pointwidth of2^30nanoseconds. This resolution is the same as apointwidth, please refer to the explanation page here on stat point widths of our tree.
- Returns:
A dictionary keyed on stream UUID’s where the value is a list of dictionaries representing changed intervals. Typically the return looks like:
{UUID: [{"start": <nanosecond_timestamp>, "end": <nanosecond_timestamp>}, ...].- Return type:
changes
Examples
>>> # Suppose we want to iterate over all changes between version 9 and 42 >>> # and we have a two stream streamset >>> from_version_map = {s.uuid: 9 for s in streamset} >>> to_version_map = {s.uuid: 42 for s in streamset} >>> changed_range = streamset.changes(from_version_map=from_version_map, ... to_version_map=to_version_map, resolution=0): >>> for stream_uuid, changed_range in changed_range.items(): ... print(f"Stream UUID: {stream_uuid} Changed intervals: {changed_range}")
>>> # Suppose we want to iterate over all changes between version 42 and the latest data that has not been inserted yet >>> from_version_map = {s.uuid: 42 for s in streamset} >>> to_version_map = {s.uuid: 0 for s in streamset} >>> changed_range = streamset.changes(from_version_map=from_version_map, ... to_version_map=to_version_map, resolution=0): >>> for stream_uuid, changed_range in changed_range.items(): ... print(f"Stream UUID: {stream_uuid} Changed intervals: {changed_range}")
- count(start=None, end=None, versions=None, precise=None)#
Get the total count of raw measurements that are present in each stream.
- Parameters:
start – Bound the lower end of this query by a start time, by default MINIMUM_TIME.
end – Bound the upper end of this query by an end time, by default MAXIMUM_TIME
versions – Versions of the streams to query against, by default None, which means a version of 0 is used.
precise – Do we need an exact count or is an estimate reasonable, by default False
- Returns:
Mapping of individual
stream.uuid’s tocountvalues.
- earliest()#
Find the earliest point (in time) that is present in the streams.
- Returns:
The earliest points in the streams.
- filter(collection=None, tags=None, annotations=None, refresh_metadata=None)#
Create a new
StreamSetthat is a subset of the streams based on metadata filtering.- Parameters:
collection – The collection string to filter by, by default None
tags – Tag metadata to filter on, by default None
annotations – Annotation metadata to filter on, by default None
refresh_metadata – Should we use the latest metadata of the streams to filter on, by default True
- Returns:
A subset of the streams that match the provided filters, if any.
- flush()#
Force a flush of the buffered data to persistent storage for all streams.
If data was present, the version number will be positively incremented.
- Returns:
version dictionary mapping.
- Return type:
The version number of each stream after the flush as a uuid
- get_latest_version()#
Get the latest version of each stream.
- Returns:
A
stream.uuid, latestversionmapping.
- get_version_at_time(time)#
Get the version of each stream at time
realtime.- Parameters:
realtime – The time to check the stream version against
- Returns:
A
stream.uuid,versionmapping.
- insert(data_map, merge_policy=None, round_spec=None)#
Insert new timeseries data into the streams.
Tip
Default merge policy has changed!
Starting with the new
pingthingsapi, the default merge policy is nowreplace. Please refer tothe merge policy docsTip
Data must follow a specific schema for insertion
Your
datapyarrowtable or record batch must have a schema that matches theTIME_VALUE_F64_SCHEMA, defined. Order of the columns matter.- Parameters:
data_map – A mapping of
stream.uuidtopyarrow.Tabletimeseries data.merge_policy – How to handle when duplicate timestamp points are inserted into the stream
round_spec – Set how many bits of precision to keep inserted data. Default behavior is the full 64 bits.
- Returns:
A mapping of
stream.uuid,versionof the stream after insertion.
- latest()#
Find the latest point (in time) that is present in the streams.
- Returns:
The latest point in the streams, if present.
- nearest(time, backward=None)#
- raw_values(start, end, snap_period=None, versions=None, schema=None)#
Return the raw time,value pairs of data from the streams.
Tip
StreamSetraw value queries de-duplicate timestampsCurrent behavior for the accelerated “multistream” streamset queries de-duplicates timestamps internally.
- Parameters:
start – Start time to get data (inclusive)
end – End time for the data query (exclusive)
snap_period – What period of time (if any) should the data be aligned to?
versions – What versions of the streams to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,values be returned as, default will be the server default.
- Returns:
A table of timeseries data in the interval of [start, end)
- raw_values_iter(start, end, snap_period_ns=None, versions=None, schema=None)#
- refresh_metadata()#
Update all metadata for each stream in the
StreamSet
- tags(copy=True, refresh=None)#
Return the tag-based metadata of the StreamSet.
- Parameters:
copy – Should the tag dictionary be copied or passed by reference, by default True
refresh – Do we need to query the platform to get the metadata first, by default False
- Returns:
A mapping of tag metadata key,value pairs.
- update(collection=Ellipsis, tags=None, custom_tags=None, annotations=None, custom_annotations=None, names=None, replace_tags=None, replace_annotations=None)#
- windowed_values(start, end, width, precise=None, versions=None, schema=None, depth=0)#
Return statistical summaries of the data.
- Parameters:
start – The approximate start time to get data (inclusive). See notes.
end – The approximate end time for the data query (exclusive). See notes.
width – The approximate size of statistical windows to return, will contain summaries of the data between
starttoendof sizewidth.precise – Pass in
precise=Trueto use the exactstart,endandwidthvalues specified. See notes.versions – What versions of the stream to query against, using the default of
Nonewill use version 0.schema – What
pyarrow.Schemashould the time,statistical summary timeseries be returned as, default will be the server default.
- Returns:
The statistical summary information of the stream as a timeseries.
Notes
By default (
precise=False), the values provided tostart,endandwidthmay not fully align with the values actually used by the query. Instead, the window width used will be the largest power of 2 ns that is smaller than the providedwindow. Doing so aligns the query with BTrDB’s internal tree structure and thus increases query performance by several orders of magnitude.Consequently, the actual time-range of the data pulled will be the aligned values that fall within the range
[start, end).
Utility Functions#
- pingthings.timeseries.utils.currently_as_ns()#
Returns the current UTC time as nanoseconds since epoch
- pingthings.timeseries.utils.to_nanoseconds(val)#
Converts datetime, datetime64, float, str (RFC 2822) to nanoseconds. If a datetime-like object is received then nanoseconds since epoch is returned.
Note
The following string formats are supported for conversion.
Format String
Description
%Y-%m-%d %H:%M:%S.%f%zmost common RFC3339 nanoseconds
%Y-%m-%d %H:%M:%S.%fexpects UTC default timezone
%Y-%m-%dT%H:%M:%S.%fZJSON encoding, UTC timezone
%Y-%m-%dT%H:%M:%SZJSON encoding, UTC timezone
%Y-%m-%dT%H:%M:%S.%f%zless common JSON-ish encoding
%Y-%m-%dT%H:%M:%S.%ffor completeness, UTC+0 default timezone
%Y-%m-%d %H:%M:%S%zhuman readable date time with TZ
%Y-%m-%d %H:%M:%Shuman readable date time UTC+0 default
%Y-%m-%dhuman readable date time at midnight UTC default
- Parameters:
val – An object to convert to nanoseconds
- Returns:
Object converted to nanoseconds
- pingthings.timeseries.utils.datetime_to_ns(dt)#
Converts a datetime object to nanoseconds since epoch. If a timezone-aware object is received then it will be converted to UTC. If a timezone-naive object is received then it will be assumed to be in UTC.
- Parameters:
dt – The datetime object to convert.
- Returns:
The number of nanoseconds since the Unix epoch.
- pingthings.timeseries.utils.ns_delta(days=0.0, hours=0.0, minutes=0.0, seconds=0.0, milliseconds=0.0, microseconds=0.0, nanoseconds=0)#
Similar to
timedelta,ns_deltarepresents a span of time but as the total number of nanoseconds.- Parameters:
days – Days (as 24 hours) to convert to nanoseconds
hours – Hours to convert to nanoseconds
minutes – Minutes to convert to nanoseconds
seconds – Seconds to convert to nanoseconds
milliseconds – Milliseconds to convert to nanoseconds
microseconds – Microseconds to convert to nanoseconds
nanoseconds – Nanoseconds to add to the time span
- Returns:
Amount of time in nanoseconds
- pingthings.timeseries.utils.ns_to_datetime(val)#
Convert nanoseconds relative to the Unix epoch to a UTC datetime.
Tip
Due to the limitation of Python’s
datetimemodule, the datetime representation is only accurate to the nearest microsecond.- Parameters:
ns – Nanoseconds since epoch (can be negative)
- Returns:
A timezone-aware datetime in UTC.
- pingthings.timeseries.utils.nearest_pointwidth(days=0.0, hours=0.0, minutes=0.0, seconds=0.0, milliseconds=0.0, microseconds=0.0, nanoseconds=0, hertz=0.0)#
Convert time delta of days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds or hertz to the nearest point-width.
- Parameters:
days – Days (as 24 hours) to convert to nanoseconds
hours – Hours to convert to nanoseconds
minutes – Minutes to convert to nanoseconds
seconds – Seconds to convert to nanoseconds
milliseconds – Milliseconds to convert to nanoseconds
microseconds – Microseconds to convert to nanoseconds
nanoseconds – Nanoseconds to add to the time span
hertz – Alternatively, provide the frequency in Hz
- Returns:
The nearest point-width-aligned value.
Useful Constants#
- pingthings.timeseries.constants.PW#
Durations that naturally align with the platform timeseries data structure. Utilizing windowed value queries where the start, end and averaging windows align with these point-widths ensures optimal query performance.
- These point-width durations are as follows:
point-width
number of nanoseconds
duration
PW[0]
1
1 ns
PW[1]
2
2 ns
PW[2]
4
4 ns
PW[3]
8
8 ns
PW[4]
16
16 ns
PW[5]
32
32 ns
PW[6]
64
64 ns
PW[7]
128
128 ns
PW[8]
256
256 ns
PW[9]
512
512 ns
PW[10]
1024
1 μs 24 ns
PW[11]
2048
2 μs 48 ns
PW[12]
4096
4 μs 96 ns
PW[13]
8192
8 μs 192 ns
PW[14]
16384
16 μs 384 ns
PW[15]
32768
32 μs 768 ns
PW[16]
65536
65 μs 536 ns
PW[17]
131072
131 μs 72 ns
PW[18]
262144
262 μs 144 ns
PW[19]
524288
524 μs 288 ns
PW[20]
1.04858e+06
1 ms 48 μs 576 ns
PW[21]
2.09715e+06
2 ms 97 μs 152 ns
PW[22]
4.1943e+06
4 ms 194 μs 304 ns
PW[23]
8.38861e+06
8 ms 388 μs 608 ns
PW[24]
1.67772e+07
16 ms 777 μs 216 ns
PW[25]
3.35544e+07
33 ms 554 μs 432 ns
PW[26]
6.71089e+07
67 ms 108 μs 864 ns
PW[27]
1.34218e+08
134 ms 217 μs 728 ns
PW[28]
2.68435e+08
268 ms 435 μs 456 ns
PW[29]
5.36871e+08
536 ms 870 μs 912 ns
PW[30]
1.07374e+09
1 sec 73 ms 741 μs
PW[31]
2.14748e+09
2 sec 147 ms 483 μs
PW[32]
4.29497e+09
4 sec 294 ms 967 μs
PW[33]
8.58993e+09
8 sec 589 ms 934 μs
PW[34]
1.71799e+10
17 sec 179 ms 869 μs
PW[35]
3.43597e+10
34 sec 359 ms 738 μs
PW[36]
6.87195e+10
1 min 8 sec 719 ms
PW[37]
1.37439e+11
2 mins 17 sec 438 ms
PW[38]
2.74878e+11
4 mins 34 sec 877 ms
PW[39]
5.49756e+11
9 mins 9 sec 755 ms
PW[40]
1.09951e+12
18 mins 19 sec 511 ms
PW[41]
2.19902e+12
36 mins 39 sec 23 ms
PW[42]
4.39805e+12
1 hour 13 mins 18 sec
PW[43]
8.79609e+12
2 hours 26 mins 36 sec
PW[44]
1.75922e+13
4 hours 53 mins 12 sec
PW[45]
3.51844e+13
9 hours 46 mins 24 sec
PW[46]
7.03687e+13
19 hours 32 mins 48 sec
PW[47]
1.40737e+14
1 day 15 hours 5 mins
PW[48]
2.81475e+14
3 days 6 hours 11 mins
PW[49]
5.6295e+14
6 days 12 hours 22 mins
PW[50]
1.1259e+15
13 days 44 mins 59 sec
PW[51]
2.2518e+15
26 days 1 hour 29 mins
PW[52]
4.5036e+15
52 days 2 hours 59 mins
PW[53]
9.0072e+15
104 days 5 hours 59 mins
PW[54]
1.80144e+16
208 days 11 hours 59 mins
PW[55]
3.60288e+16
1 year 51 days 23 hours
PW[56]
7.20576e+16
2 years 103 days 23 hours
PW[57]
1.44115e+17
4 years 207 days 23 hours
PW[58]
2.8823e+17
9 years 50 days 23 hours
PW[59]
5.76461e+17
18 years 101 days 23 hours
PW[60]
1.15292e+18
36 years 203 days 23 hours
alias of [<constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>, <constants._PW object>]
- pingthings.timeseries.constants.MAXIMUM_TIME#
alias of 3458764513820540927
- pingthings.timeseries.constants.MINIMUM_TIME#
alias of -1152921504606846976
- pingthings.timeseries.constants.TIME_VALUE_F64_SCHEMA#
alias of time: timestamp[ns, tz=UTC] not null value: double not null
- pingthings.timeseries.constants.TIME_VALUE_F32_SCHEMA#
alias of time: timestamp[ns, tz=UTC] not null value: float not null
- pingthings.timeseries.constants.STAT_F64_SCHEMA#
alias of time: timestamp[ns, tz=UTC] not null min: double not null mean: double not null max: double not null count: uint64 not null stddev: double not null
- pingthings.timeseries.constants.STAT_F32_SCHEMA#
alias of time: timestamp[ns, tz=UTC] not null min: float not null mean: float not null max: float not null count: uint64 not null stddev: float not null
Client#
- class pingthings.timeseries.Client#
Bases:
object- create(uuid, collection, tags=None, annotations=None)#
Create a new stream with the given uuid and collection name.
- Parameters:
uuid – The UUID for the new stream.
collection – The collection to which the stream belongs.
tags – Tags associated with the stream.
annotations – Annotations for the stream.
- Returns:
The newly created stream.
Note
Required and Allowable Tags/Annotations
The
namefield intagsmust be set and currently alltags/annotationsmust be encoded as strings and two streams can not share both the samecollectionandname.Tip
Available tags in the
streamtablecolumn_name
Description
name
name of the stream
source
Where did the stream come from
device_id
What device is the stream attached to
samples_per_second
What is the nominal report rate of the data, in Hz?
time_precision
How accurate is each timestep (+- nanoseconds)
value_precision
Bit precision
dynamic
Can the timeseries stream send us data at varying report rates?
continuous
Should we expect a continuous stream of data?
description
Additional information about the timeseries stream
alt_name
Additional name that the stream may be referenced by
alt_id
Alternative ID (most likely SignalID from STTP)
norm_factor
A factor to scale the measurement by to normalize. Like “baseKV” for voltage, etc.
scaling_factor
The “m” in y=mx + b factor, line-line scaling factor, etc
bias_factor
The “b” in y=mx+b
hidden
Whether the stream should be presented to non-admin users
- create_device(device)#
Creates a device with fields matching the passed dictionary.
namecan not beNoneor an empty string, two devices can not share the samenameandgeo, andenabled=Trueby default.- Parameters:
device – dictionary with the possible keys and description of expected values below.
- Returns:
A dictionary with the same fields passed with create plus the
device["id"]set
Tip
Available columns in the
devicetablecolumn_name
Description
name
Name of device
device_type
Type of device (DFR/Relay/etc)
description
User readable description
geo
Coordinates, a dict {“latitude”:float,”logitude”:float}
elevation
Elevation of the device, float
alt_id
Alternative id, int
alt_name
Alternative name
enabled
Whether the device is expected to be sending data, bool default: True
owner
Who owns the device
protocol
What protocol the device is using to send data
model_name
The model name of the device
vendor
The company that creates/sells the device
- create_streams(uuids, collection, tags=None, custom_tags=None, annotations=None, custom_annotations=None, names=None)#
- create_unit(name, symbol, base, canonical, source_name)#
Create a new representation of a unit definition in the platform.
Unitsare a main way to assign further meaning to the timeseries stored in the platform. There are usually a handful of defaultunitsprovided with each cluster, however, based on user needs, additional units will need to be included to support the wide range of timeseries added to the platform.- Parameters:
name – Name of the new unit.
symbol – Symbol of the new unit.
base – Multiplicative factor to convert the unit to the canonical representation.
canonical – The “main” unit that this unit can be ultimately converted to.
source_name – List of other potential
namesthat thisunitcan be considered in the platform. For example, if theunitname isdegreesthe source_name could include the following:["deg", "VPHA", "IPHA", "VpHA", "Deg", "DEG"]
- Returns:
Dictionary with fields corresponding to the values in the database.
Examples
>>> unit_def = {"name":"volts", "symbol":"V", "base":1.0, "canonical":"volts", source_name:["VPHM", "voltage", "VOLTS", "VLTGE"]} >>> unit = client.create_unit(**unit_def) >>> print(unit) {'id': 6, 'name': 'volts', 'symbol': 'V', 'canonical': 'volts', 'base': 1.0, 'source_name': ['VPHM', 'voltage', 'VOLTS', 'VLTGE']}
- delete_device(device_id)#
Deletes the device with the specified id
- Parameters:
device_id – Corresponding id of the device to be deleted
- Returns:
None
- delete_unit(unit_id)#
Remove a unit from the platform.
- Parameters:
unit_id – Integer corresponding to the id of the unit in the database.
- Returns:
None
Examples
>>> client.delete_unit(6)
- get_collection_properties(collection)#
Get properties of a collection.
- Parameters:
collection – The name of the collection.
Examples
Get the retention policy of a collection.
>>> conn.get_collection_properties("bar") {'retention': {'remove_older_than': datetime.timedelta(days=7)}}
- get_device(device_id)#
Returns a device with a matching id in the device table.
- Parameters:
device_id – Integer corresponding to the id of the device in the database.
- Returns:
Dictionary with fields corresponding to the values in the database.
- get_devices(device_ids)#
Returns devices with matching ids in the device table.
- Parameters:
device_ids – List of integers corresponding to the ids of the devices in the database.
- Returns:
Dictionary with fields corresponding to the values in the database.
- get_unit(unit_id)#
Returns a unit with a matching id in the unit table.
- Parameters:
unit_id – Integer corresponding to the id of the unit in the database.
- Returns:
Dictionary with fields corresponding to the values in the unit table.
- info()#
Retrieve information about the server and proxy server the client is connected to.
- Returns:
A dictionary containing server and proxy server information.
- list_collections(prefix=None)#
Returns a list of collection paths using the
prefixargument for filtering.- Parameters:
prefix – Filter collections that start with the string provided, if none passed, will list all collections.
- Returns:
All collections that match the provided prefix.
Examples
Assuming we have the following collections in the platform:
foo,bar,foo/baz,bar/baz>>> conn = pt.connect() >>> conn.list_collections().sort() ["bar", "bar/baz", "foo", "foo/bar"]
>>> conn.list_collections(prefix="foo") ["foo", "foo/bar"]
- list_devices()#
Returns a list of devices the user has permission to see.
- Returns:
Dictionary with keys matching the columns in the device table.
- list_units()#
Returns a list of units generated in the database.
- Returns:
Dictionary with keys matching the columns in the units table.
- set_collection_retention(collection, override_per_stream, remove_older_than=None)#
Set retention policy on a collection of streams.
- Parameters:
collection – The name of the collection.
override_per_stream – Whether stream-specific retention policy should be overridden.
remove_older_than – Trim time period - after which the data will get removed. Not specifying this parameter disables the trimming.
Examples
Keep the data for only one week.
>>> conn.set_collection_retention("bar", false, datetime.timedelta(days=7))
- set_retention(uuids, remove_older_than=None)#
Set retention policy on a list of streams.
- Parameters:
uuids – The UUIDs of the streams to apply the retention policy to.
remove_older_than – Trim time period after which the data can be removed. Specifying
Noneor not passing the parameter disables trimming.
- stream_from_uuid(py_uuid)#
Retrieve a stream based on its UUID.
- Parameters:
uuid – The UUID of the stream.
- Returns:
The stream associated with the provided UUID.
- Raises:
TypeError – If the provided
uuidis not a valid UUID
- streams_in_collection(collection=None, is_collection_prefix=None, tags=None, annotations=None)#
Search for streams matching given parameters
- Parameters:
collection – collections to use when searching for streams, case sensitive.
is_collection_prefix – Whether the collection is a prefix of the whole collection name.
tags – The tags to identify the stream.
annotations – The annotations to identify the stream.
- Returns:
The grouping of streams matching given parameters.
- streamset_from_uuids(uuids, fetch_metadata=None)#
Return a
StreamSetfrom an iterable of UUIDs.- Parameters:
uuids – List of stream identifiers
fetch_metadata – Whether to fetch metadata for the streams in the set. Default is True.
Warning
Advanced user feature
Be cautious about using
fetch_metadata=False. Many stream metadata values like collection, name, unit, tags, annotations will not be available, meaning filtering and other operations that require metadata will not work.- Returns:
The
StreamSetassociated with the provided iterable of UUIDs.
- update_device(device, replace=False)#
Updates a
devicewith matchingdevice["id"]using fields matching the passed dictionary.namecan not beNoneor an empty string.- Parameters:
device – dictionary with the possible keys and description of expected values below.
replace – whether to change all unspecified values to
None(device["enabled"]=Trueby default).
- Returns:
Dictionary with the updated fields and original unmodified fields of the device
Note
Update Behavior
This function updates a field if it has been set, otherwise it inserts a new value. Not passing a value for an existing field will not clear the value from that field. For that you must choose
replace=True. Ifreplace=Truenamecan not beNoneor an empty string. Even withreplace=Truegeowill not be set toNone.Tip
Available columns in the
devicetablecolumn_name
Description
id
Internal id of device
name
Name of device
device_type
Type of device (DFR/Relay/etc)
description
User readable description
geo
Coordinates, a dict {“latitude”:float,”logitude”:float}
elevation
Elevation of the device, float
alt_id
Alternative id, int
alt_name
Alternative name
enabled
Whether the device is expected to be sending data, bool default: True
owner
Who owns the device
protocol
What protocol the device is using to send data
model_name
The model name of the device
vendor
The company that creates/sells the device
- update_unit(unit)#
Updates a
unit_dictwith matchingidusing fields from the passed dictionary.Modify the
unitwhere theunit_dict['id']is theidnumber of theunityou want to update.Note
Update Behavior
You are not requried to include fields that you want to keep the same. Although including them will not cause issues.
- Parameters:
unit_dict – Dictionary with fields corresponding to the values in the database you want to update
- Returns:
Dictionary with the updated fields and original unmodified fields of the unit
Examples
>>> original_unit = client.get_unit(6) >>> print(original_unit) {'id': 6, 'name': 'volts', 'symbol': 'V', 'canonical': 'volts', 'base': 1.0, 'source_name': ['VPHM', 'voltage', 'VOLTS', 'VLTGE']} >>> updated_unit = {"id":6, "name":"volt"} >>> client.update_unit(updated_unit) {'id': 6, 'name': 'volt', 'symbol': 'V', 'canonical': 'volts', 'base': 1.0, 'source_name': ['VPHM', 'voltage', 'VOLTS', 'VLTGE']}