# Tags

[Kaithemautomation Index](./README.md#kaithemautomation-index) / Tags

> Auto-generated documentation for [tags](../../../api/tags.py) module.

- [Tags](#tags)
  - [BinaryTag](#binarytag)
  - [NumericTag](#numerictag)
  - [ObjectTag](#objecttag)
  - [StringTag](#stringtag)
  - [all_tags_raw](#all_tags_raw)
  - [existing_tag](#existing_tag)
  - [normalize_tag_name](#normalize_tag_name)
  - [tags_docstring](#tags_docstring)
  - [Tag Points](#tag-points)
    - [The TagPoint object](#the-tagpoint-object)
    - [Locking](#locking)
    - [Expression Tags](#expression-tags)
    - [Error Handling Errors in getters are logged, and the most recent value](#error-handling-errors-in-getters-are-logged,-and-the-most-recent-value)
    - [tagPoint.pull()](#tagpointpull())
    - [StringTags](#stringtags)
    - [ObjectTags](#objecttags)
    - [BinaryTag](#binarytag-1)
    - [Get arbitrary existing tag ignoring type](#get-arbitrary-existing-tag-ignoring-type)
    - [The Tag Point Classes](#the-tag-point-classes)
  - [The raw data API endpoint](#the-raw-data-api-endpoint)

## BinaryTag

[Show source in tags.py:377](../../../api/tags.py#L377)

#### Signature

```python
def BinaryTag(k: str) -> tagpoints.BinaryTagPointClass: ...
```



## NumericTag

[Show source in tags.py:362](../../../api/tags.py#L362)

#### Signature

```python
def NumericTag(k: str) -> tagpoints.NumericTagPointClass: ...
```



## ObjectTag

[Show source in tags.py:372](../../../api/tags.py#L372)

#### Signature

```python
def ObjectTag(k: str) -> tagpoints.ObjectTagPointClass: ...
```



## StringTag

[Show source in tags.py:367](../../../api/tags.py#L367)

#### Signature

```python
def StringTag(k: str) -> tagpoints.StringTagPointClass: ...
```



## all_tags_raw

[Show source in tags.py:343](../../../api/tags.py#L343)

#### Signature

```python
def all_tags_raw(): ...
```



## existing_tag

[Show source in tags.py:347](../../../api/tags.py#L347)

Return tag by that name, of any type, if it exists

#### Signature

```python
def existing_tag(s) -> tagpoints.GenericTagPointClass | None: ...
```



## normalize_tag_name

[Show source in tags.py:356](../../../api/tags.py#L356)

Add the leading / if needed

#### Signature

```python
def normalize_tag_name(s: str): ...
```



## tags_docstring

[Show source in tags.py:5](../../../api/tags.py#L5)

## Tag Points

### The TagPoint object

TagPoints are threadsafe containers for variables that provide easy
debugging and subscription to changes.

TagPoints are created on demand. To create a tagpoint
  holding a number, use kaithem.api.tags.NumericTag(name).

Once a tag exists, it shows up in the tags listing page.

If a TagPoint already exists when you request it, you get that one instead.
Tags exist until there are no more references or claims on them, and all
properties may be reconfigured on the fly. this allows them to be used for
loose coupling between different parts of a program.

Tag point values have an associated timestamp and annotation(Which have
defaults, and you can ignore), that follow the values, allowing advanced
patterns and loop avoidance with remote systems.

When a tag is first created, it's value is the default for that type, and
it's timestamp will be 0.

The annotation is an arbitrary python object, and the timestamp is always in
the time.time() scale.

It is suggested that you not do anything with annotations besides equality
testing, or that you always typecheck the value as it defaults to None.

### Locking

When you write to a tag, it will call all subscribers under a reentrant
lock. This of course, means that it is possible to create deadlocks if you
do something really crazy.

To prevent this, tags have a timeout, of around ten seconds, after which
they will give up on most actions and raise a RuntimeError.

As kaithem is all about auto-retry in case of error, this should save you
from most mistakes, but you should still be aware.

Reading from tags may or may not involve the lock, due to caching.

You can always break possible lock cycles by doing something in a background
thread, if the application can handle it.

### Expression Tags

Any tag having a name that begins with an equals sign
will be created with a getter that evaluates the name as an expression. The
priority of the expression source will be 98.

You have access to time, math, random, re, plus the tag itself as 'tag', and
anything else you put in tag.context in code.

#### the tv(n) function

The tv function is used from within a tag expression. It returns the value
of a numeric tag with the given name, and adds the tag to the list of source
tags.

The tag will re-eval the expression whenever a source tag has new data.

Updating the config data via the interface will reset the list of source
tags.

### Error Handling Errors in getters are logged, and the most recent value
is used. Errors in setters are logged.

#### TagPoint.value

Property that can get the tag's value, or set the value of the default
claim.

Errors in getters will never cause an error to be raised getting or setting
this.

#### TagPoint.min, TagPoint.max Set the range of the tag point. Out of range
values are clipped. Default is None. Setting does bothing if overridden by
configuration.

#### TagPoint.interval Set the sample rate of the tags data in seconds.
Affects polling and cacheing. Setting does nothing if overridden by
configuration.

#### TagPoint.subscribe(f) f will be called whe the value changes, as long
as the function f still exists.

It will also be called the first time you set a tag's value, even if the
value has not changed.

It should very very rarely be called on repeated values otherwise, but this
behavior is not absolutelu guaranteed and should not be relied on.

All subscribers are called synchronously in the same thread that set the
value, however any errors are logged and ignored.

They will all be called under the tagpoint's lock. To avoid various problems
like endless loops, one should be careful when accessing the tagpoint itself
from within this function.

The signature of f must be: f(value, timestamp, annotation)

#### TagPoint.unit A string that determines the unit of a tag. Units are
expressed in strings like "m" or "degF". Currently only a small number of
unit conversions are supported natively and others use pint, which is not as
fast.

SI prefixes should not be used in units, as it interferes with
auto-prefixing for display that meter widgets can do, and generally
complicates coding. This includes kilograms.

Grams should be used for internal calculations instead despite Kg being the
base unit according to SI.

Note that operations involving units raise an error if the unit is not set.
To prevent this, both the "sending" and "recieving" code should set the unit
before using the tag.

To prevent the very obvious classes of errors where different code thinks a
unit is a different thing, this property will not allow changes once it has
been set. You can freely write the same string to it, and you can set it to
None and then to a new value if you must, but you cannot change between two
strings without raising an exception.

This property can't currently be configured through the UI.

For some units, meters will become "unit aware" on the display page.

#### TagPoint.subtype

A string that determines a more specific type.  Use a com.site.x name, or
something like that, to avoid collisions.

"Official" ones include bool, which can be 1 or 0, or tristate, which can be
-1 for unset/no effect, 0, or 1.

#### TagPoint.display_units

This can be None, or a pipe-separated string listing one or more units that
the tag's value should be displayed in. Base SI units imply that the correct
prefix should be used for readability, but units that contain a prefix imply
fixed display only in that unit.

#### TagPoint.convert_to(unit) Return the value in the given unit

#### TagPoint.convert_value(value,unit) Value must be a number in the tag's
native unit. Returns the value after converting.

#### TagPoint.claim(value, name, priority, timestamp=None, annotation=None)
Adds a claim to the tag and returns the Claim object. The claim will
dissapear if the returned Claim object ever does. Value may be a function
that can be polled to return a float, or a number.

If a function is provided, it may return None to indicate no new data has
arrived. This will not update the tags age.

Should a claim already exist by that name, the exact same claim object as
the previous claim is returned.

Rather than using multiple claims, consider whether it's really needed, lots
of builtin functionality in the UI is mean to just work with the default
claim, for ease of use.

### tagPoint.pull()

Return the value from a tag, forcing a new update from the getter without
any caching. May also trigger the subscribers if the value changes.

##### TagPoint.eval_context

Dict used as globals and locals for evaluating
alarm conditions and expression tags.

#### tagPoint.expose(readPerm, writePerm, priority, configured=False)

Expose the tag to web APIs, with the permissions specified. Permissions must be
strings, but can use commas for multiple.

Priority must be an integer, and determines the priority at which the web
API may set the tag's value.  The web API cannot control the priority, but
can release the claim entirely by sending a null, or reclaim by sending real
data again.

The way this works is that tag.data_source_widget is created, a
Widgets.DataSource instance having id "tag:TAGNAME", with the given
permissions.

TO the server will set a claim at the permitted priority, or release any
claim if the data is None. FROM the server indicates the actual current
value of the tag.

A second widget, tag.control:TAGNAME is also created.  This widget is
write-only, it is not affected by changes to the tagpoint itself, but it
will sync between different users.

This means that you can write a Null to it, and everyone will be able to see
that null, while also reading back the real currect tag value set from other
claims.

You must always have at least one read permission, and write_perms defaults
to `__admin__`.   Note that if the user sets or configures any permissions
via the web API, they will override those set in code.

If read_perms or write_perms is empty, disable exposure.

You cannot have different priority levels for different users this way, that
would be highly confusing. Use multiple tags or code your own API for that.

If configured is True, will actually set the persistant config rather than
the runtime config. This will not be made permanent till the user clicks
"save server state to disk".

#### tagPoint.get_effective_permissions()

Returns the read, write, and max priority permissions currently in effect.

#### tagPoint.expose() Cancels any API exposure

##### TagPoint(v,t,a)

Equivalent to calling set() on the default handler. If
no args are provided, just returns the tag's value.

##### Claim.set(value,timestamp=None,annotation=None)

Set the value of a
claim. You can optionally also set the timestamp of the message.

##### Claim()

Equivalent to claim.set(). This allows claims themselves to be
subscribers for another tagpoint

##### Claim.set_as(value,unit,timestamp=None,annotation=None)

Set the value
of a claim with a value of the given unit, if neccesary, converts to the
tag's native unit before setting. You can optionally also set the timestamp
of the message.

#### TagPoint.current_source

Return the Claim object that is currently
controlling the tag

##### Claim.release() Release a claim.

### StringTags

StringTags are created or fetched on demand by kaithem.tags.StringTag(name).
They function exactly like regular tagpoints, minus all features relating to
unit conversion.

### ObjectTags

ObjectTags are created or fetched on demand by kaithem.tags.StringTag(name).
They are just like any other tag, but the value must be a JSON serializable
object.

### BinaryTag

BinaryTags are created or fetched on demand by kaithem.tags.BinaryTag(name).
The value of a binary tag is always a bytes object, defaulting to empty.

You can set the default value from the management page for any particular
tag, but for BinaryTags it will be interpreted as a hex string.

### Get arbitrary existing tag ignoring type

kaithem.tags.all_tags_raw is a dict containing a weak reference to every
tag.  It allows raw access to the internal tags list.

kaithem.tags.all_tags_raw['foo']() gets you the foo tag.

#### BinaryTag.unreliable

Set to true, makes tag act more like a UDP connection. Setting the value
just pushed to subscribers. Polling not guaranteed to work. Type checking
disabled.

#### BinaryTag.fast_push(self, value,timestamp=None, annotation=None)

Just notify sbscribers. Use with unreliable mode.  Does not set the value
and ignores all claims and priorities. Allows tag points to be used for
realtime media streaming.  Preferably, use MPEG 2 TS. Subtype should be
"mpegts" and data packets must start at 188 byte boundaries for that.

### The Tag Point Classes

TagPointClass, StringTagPointClass,ObjectTagPointClass, and
BinaryTagPointClass  exist under kaithem.tags.

Subclassing is a bad plan but you may want them for type hinting.

## The raw data API endpoint

Create a websocket connection to the URL of this form:

`globalThis.kaithemapi.wsPrefix()+"/widgets/wsraw?widgetid={obj.tagPoints[i].data_source_widget.uuid}",`

And if you have read permissions, you will get tag data updates as raw data.
Added to support video playback with mpegts.js

#### Signature

```python
def tags_docstring(): ...
```