Sensors

Since :term:`sensor`s are an server-side construct, but predicates make use of them, here’s a section about sensors.

Note that you can’t define any sensors yourself and must rely on the server to do that.

There’s a way to access the value of a sensor. Where SMOK would represent the value of a sensor either by a JSONable value, or by a value and it’s units (via pint), smok-client does away with units, and returns sensor values only as JSONable values. The unit part is simply stripped from the value.

Let’s look at the sensor class:

class smok.sensor.Sensor(device: SMOKDevice, fqts: str, path: str, type_name: str)

A class representing a smok-client sensor defined on given device.

Class is eq-able and hashable by fqts.

Warning

Do not compare sensors across different devices!

Variables
  • fqts – this sensor’s FQTS (str)

  • path – composite pathpoint names, separated by a tilde (~) (str)

  • type_name – name of the sensor type (str)

  • type – object used for data conversion between pathpoints and sensor values (smok.sensor.types.BasicType)

get() Tuple[Union[int, float], Union[str, int, float, list, dict]]

Return the value of this sensor

Raises
Returns

a tuple of (timestamp in milliseconds, sensor value)

get_archive(starting_at: int, stopping_at: Optional[int] = None) Iterator[Tuple[int, Union[str, int, float, list, dict, smok.exceptions.OperationFailedError]]]

Get archive readings.

This will be readed entirely from the device’s data, the server will not be queried

Parameters
  • starting_at – timestamp of start, in milliseconds

  • stopping_at – timestamp of end, in milliseconds, or None for the end of the park

Returns

an iterator of tuple (timestamp in milliseconds, pathpoint value or exception instance)

log_write(who: str, reason: str, value: str, hr_value: Optional[str] = None, hr_sensor: Optional[str] = None, timestamp: Optional[int] = None) None

Log that a write has taken place in this sensor

Parameters
  • who – who has made this change

  • reason – reason for this write

  • value – a str-able form of value

  • hr_value – a human-readable value. Defaults to value

  • hr_sensor – a human-readable name for the sensor. Defaults to fqts

  • timestamp – in milliseconds! Leave at default for current timestamp

write(value, advise: smok.pathpoint.orders.AdviseLevel = AdviseLevel.ADVISE) smok.pathpoint.orders.Section

Write a particular value to the sensor.

Take care for the value to match the type of the sensor

Parameters
  • value – value to write

  • advise – advise level to use

Raises

TypeError – invalid type

And a type of it’s value:

smok.sensor.SensorValueType

The central part of internal API.

This represents a generic version of type ‘origin’ with type arguments ‘params’. There are two kind of these aliases: user defined and special. The special ones are wrappers around builtin collections and ABCs in collections.abc. These must have ‘name’ always set. If ‘inst’ is False, then the alias can’t be instantiated, this is used by e.g. typing.List and typing.Dict.

alias of Union[str, int, float, list, dict]

fqts is the basic of the sensor naming system. Each name is a set of words, separated by a whitespace. fqts is these words split by a space, sorted and then joined, ensuring that the names stay unique and not depend on order (since a set has no order).

The correct operation to standarize a sensor’s name is below:

smok.sensor.fqtsify(tag_name: Union[str, Set[str]]) str

Standarize the name, for use in dictionaries and other places that access sensors by name

Parameters

tag_nameTag name, either a space-separated set of names or a set of names proper

Returns

FQTS-ified name

Note

Why tags? Most SCADA system order their sensors in a hierarchical manner. SMOK does not use that, preferring for the far more elastic tag system, since it allows to organise the user in arbitrary-dimensional hierarchies.

You are more than welcome to make direct use of Sensors, especially when facing output to client. It makes more sense to use Sensor s for that, because Sensor s represent a concept, while pathpoint represents a single endpoint on the client.

Sensor types

Every sensor has a type. Type describes how to convert values from pathpoints to sensor and vice versa. Base class for types is:

class smok.sensor.types.BasicType

A base class for all SMOK sensor types

abstract pathpoint_to_sensor(*values: Union[int, float, str]) Union[str, int, float, list, dict]

Convert a value from pathpoint values to a sensor value

abstract sensor_to_pathpoint(value: Union[str, int, float, list, dict], *pathpoint_names: str) Tuple[Union[int, float, str], ...]

Convert a value from sensor values to pathpoint values, each value in tuple for a separate pathpoint. If your sensor consists of a single pathpoint, then you should return a 1-element tuple.

Other common types are:

class smok.sensor.types.NumericType(precision=2, multiplier=1, offset=0, **kwargs)

A type for values of numeric type

Variables

precision – number of places after the comma that should be diplayed (int)

pathpoint_to_sensor(*values: Union[int, float, str])

Convert a value from pathpoint values to a sensor value

sensor_to_pathpoint(value: Union[str, int, float, list, dict], *pathpoint_names: str) Tuple[Union[int, float, str], ...]

Convert a value from sensor values to pathpoint values, each value in tuple for a separate pathpoint. If your sensor consists of a single pathpoint, then you should return a 1-element tuple.

class smok.sensor.types.UnicodeType

A basic type for Unicode-containing sensors

pathpoint_to_sensor(*values: Union[int, float, str]) Union[str, int, float, list, dict]

Convert a value from pathpoint values to a sensor value

sensor_to_pathpoint(value: Union[str, int, float, list, dict], *pathpoint_names: str) Tuple[Union[int, float, str], ...]

Convert a value from sensor values to pathpoint values, each value in tuple for a separate pathpoint. If your sensor consists of a single pathpoint, then you should return a 1-element tuple.

Logging writes

In order to log a write, you must construct an instance of following:

class smok.sensor.SensorWriteEvent(timestamp: int, who: str, hr_sensor: str, hr_value: str, fqts: str, value: str, reason: str)

An event describing a situation wherein a sensor was written

Parameters

timestamp – in milliseconds

And pass it as an argument to log_sensor_write().