# Systemstate

The Systemstate protocol enables you to monitor state changes across all Connectware resources. For any object with a [Resource ID](https://docs.cybus.io/2-1-0/services/service-commissioning-files/resources#resource-id), you can either query the current state using `read` operations or subscribe to receive ongoing state change notifications using `subscribe` operations.

## Systemstate Configuration

Below is the format for configuring the Systemstate protocol in your service commissioning file. A complete working example is provided at the end of this topic.

{% hint style="info" %}
**Resource Deployment**: All Systemstate resources are deployed via Resource Status Tracking (RST). The `agentName` property is ignored for Systemstate resources.
{% endhint %}

### Configuring Connections

Systemstate establishes an internal connection to monitor the Connectware's state management system.

* Configure your connection object as follows:

{% code lineNumbers="true" %}

```yaml
eventsConnection:
  type: Cybus::Connection
  properties:
    protocol: Systemstate
    connection: {}
```

{% endcode %}

#### Systemstate Connection Properties

**`protocol` (required)**

Must be set to `Systemstate`.

#### Systemstate Endpoints Properties

See [Systemstate Endpoint Properties](https://docs.cybus.io/2-1-0/documentation/industry-protocol-details/systemstate/systemstateendpoint).

### Configuring Endpoints

Each Systemstate connection can support multiple endpoints that specify which operations are available.

Two operation types are available:

* **subscribe**: Sends a message with state information each time the specified resource changes state.
* **read**: Allows querying the current state by sending any message to the topic with suffix `req`, and receiving the response on a topic with suffix `res`.

### Tracking Individual Resources vs. Services

Systemstate supports two types of tracking:

#### Individual Resource Tracking

Track specific resources within a service (endpoints, connections, etc.) by specifying the full component identifier:

* [Service ID](https://docs.cybus.io/2-1-0/documentation/services/serviceid)
* [Resource ID](https://docs.cybus.io/2-1-0/services/service-commissioning-files/resources#resource-id)
* Format: `ServiceID-ResourceID` (separated by a `-` hyphen)

This is the recommended approach for detailed monitoring of specific components.

#### Service-Level Tracking

Track the entire service's enabled/disabled status by specifying only the Service ID:

* Format: `ServiceID` (without a resource suffix)
* Use `resourceId: !sub '${Cybus::ServiceId}'` in your endpoint configuration

**Service-Level Tracking Limitations**:

* Service tracking only begins reporting after the service has been enabled for the first time.
* Only reports whether the service is **enabled** or **disabled**.
* Service deviations (validation errors, resource-specific issues) are **not reported** by the Systemstate protocol when tracking at the service level.
* For detailed resource-level monitoring, use individual resource tracking instead.

### Setting Up a Systemstate Endpoint

To set up a Systemstate endpoint:

1. Create a resource with type `Cybus::Endpoint` and specify the `Systemstate` protocol.
2. Define the component identifier that you want to monitor (see tracking types above).

{% hint style="info" %}
Best practice: Rather than hardcoding the Service ID directly, use the parameter reference syntax `!sub '${Cybus::ServiceId}'` as shown in the example below. This improves flexibility and simplifies maintenance. For more details, see [Inter-Service Referencing](https://docs.cybus.io/2-1-0/documentation/services/inter-service-referencing).
{% endhint %}

{% code lineNumbers="true" %}

```yaml
# Track individual resource
resourceEndpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Systemstate
    connection: !ref someConnection
    subscribe:
      resourceId: !sub '${Cybus::ServiceId}-someConnection'

# Track entire service
serviceEndpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Systemstate
    connection: !ref someConnection
    subscribe:
      resourceId: !sub '${Cybus::ServiceId}'
```

{% endcode %}

## Message Format Examples

Based on the example service commissioning file below, here are sample output messages from the protocol.

Your specific MQTT topics may vary, but the message payload structure shown here must be maintained - except when you have applied JSONata transformation rules.

**When enabling an endpoint**

{% code lineNumbers="true" %}

```json
{ "state": "enabling", "resourceId": "samplesystemstateservice-someEndpoint", "timestamp": 1621256032226 }
```

{% endcode %}

**When an endpoint has been successfully enabled**

{% code lineNumbers="true" %}

```json
{ "state": "enabled", "resourceId": "samplesystemstateservice-someEndpoint", "timestamp": 1621256032233 }
```

{% endcode %}

**When a resource/service does not exist (read operation)**

If you send a message to a topic with suffix `req` for a resource or service that does not exist, Systemstate will return an error response:

{% code lineNumbers="true" %}

```json
{ "state": "", "resourceId": "samplesystemstateservice-someEndpoint", "timestamp": 1770036468132, "error": "resource not found" }
```

{% endcode %}

### Service Commissioning File Example

{% file src="<https://2398418777-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE3kF1al6qtDJ7pi353Uv%2Fuploads%2Fgit-blob-a3bd1de84ceeff3cef0aed8554360c243987dc08%2Fsystemstate-example.yml?alt=media>" %}

{% code title="systemstate-example.yml" lineNumbers="true" %}

```yaml
description: >
  Sample Systemstate service commissioning file

metadata:
  name: Sample Systemstate service
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

resources:
  someConnection:
    type: Cybus::Connection
    properties:
      protocol: Systemstate
      connection: {}

  someEndpoint:
    type: Cybus::Endpoint
    properties:
      protocol: Systemstate
      connection: !ref someConnection
      subscribe:
        resourceId: !sub '${Cybus::ServiceId}-someConnection'

  anotherEndpoint:
    type: Cybus::Endpoint
    properties:
      protocol: Systemstate
      connection: !ref someConnection
      subscribe:
        resourceId: !sub '${Cybus::ServiceId}-someEndpoint'
```

{% endcode %}
