> For the complete documentation index, see [llms.txt](https://renewables.docs.helinplatform.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://renewables.docs.helinplatform.com/sgm-product-docs/concepts/cyclic-writer.md).

# Cyclic Writer

Background process that periodically re-writes the active setpoint to each device, defending against firmware-level state loss.

The cyclic writer is the simplest and lowest-priority control mechanism in SGM. It runs in the background on every gateway and does one thing: **re-write the currently active setpoint to each device on a fixed interval**.

If your inverter loses power and reboots without the latest curtailment value, or if the controller's last command quietly doesn't stick due to a Modbus glitch, the cyclic writer is the safety net that ensures the device returns to the intended state without a human in the loop.

## Why this exists

Field hardware doesn't always behave the way the spec says it should. Common patterns the writer defends against:

* **Memory loss after power cycles.** Some inverters revert to factory defaults after a brown-out. Without a writer, the operator only finds out when they read telemetry hours later.
* **Silent command drops.** A Modbus write that returns "OK" but doesn't actually update the register. Rare, but observed in the wild.
* **Unrecorded local overrides.** A technician on site uses the device's HMI to change a setting; the writer overwrites that change on the next cycle, which is the right behaviour for an operator-controlled fleet.

## Configuration

| Setting                | Where it lives                      | Default behaviour                                                                                    |
| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `cyclic_write_timeout` | Site-level (`PUT /sites/{site_id}`) | The platform writes the active value at this interval. Typical values: a few minutes to a few hours. |

Set the interval based on how aggressive you want the defence to be. A 15-minute interval catches most failure modes within an acceptable window without flooding the device's Modbus stack. A 1-minute interval is rarely necessary and can interfere with other reads.

{% hint style="info" %}
The cyclic writer **never changes** the active setpoint. It only **reinforces** it. If a higher-priority source, a [direct setpoint](/sgm-product-docs/reference-docs/scheduling-setpoints.md#direct-setpoints), a [scheduled setpoint](/sgm-product-docs/reference-docs/scheduling-setpoints.md#scheduled-setpoints), or [closed loop control](/sgm-product-docs/concepts/closed-loop-control.md), has set a value, the writer keeps writing that same value. If nothing higher-priority is active, it writes the device's `default_value`.
{% endhint %}

## How the writer picks a value

```mermaid
flowchart TD
    A[Cyclic writer fires] --> B{Direct setpoint<br/>active?}
    B -->|Yes| C[Re-write the<br/>direct value]
    B -->|No| D{Schedule slot<br/>active?}
    D -->|Yes| E[Re-write the<br/>scheduled value]
    D -->|No| F[Re-write the device's<br/>default_value]

    style C fill:#dcfce7,stroke:#22c55e,color:#000
    style E fill:#dbeafe,stroke:#3b82f6,color:#000
    style F fill:#fef9c3,stroke:#eab308,color:#000
```

The decision tree is intentionally simple, there's no negotiation, no merging. Whatever the gateway thinks the device should be doing right now is what gets written.

## Where the writer runs

On the **edge node**, not in the cloud. This is intentional.

* The writer keeps reinforcing the right value even when the cloud connection is down.
* The cloud doesn't have to keep track of every device's state.
* Lost cloud connectivity affects only your *new* commands, not the maintenance of state for *existing* commands.

The writer logs only minimally, there's no per-cycle entry, just deviations and failures, so it doesn't flood the operation log.

## When NOT to rely on the writer

The cyclic writer is a defence, not a control mechanism. Don't use it to "set a value once and forget about it", that's what a scheduled setpoint is for.

The writer also doesn't deliver real-time control. If you need a value applied within seconds of a market signal, send a [direct setpoint](/sgm-product-docs/reference-docs/scheduling-setpoints.md#direct-setpoints). The writer's interval (minutes to hours) is too slow for trading-grade control.

## Relevant pages

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><p><i class="fa-clock">:clock:</i></p><p><a href="/sgm-product-docs/reference-docs/scheduling-setpoints.md"><strong>Scheduling setpoints</strong></a></p></td><td>The setpoint hierarchy the writer defers to.</td></tr><tr><td><p><i class="fa-rotate">:rotate:</i></p><p><a href="/sgm-product-docs/concepts/closed-loop-control.md"><strong>Closed Loop Control</strong></a></p></td><td>When you need active feedback, not just write reinforcement.</td></tr><tr><td><p><i class="fa-server">:server:</i></p><p><a href="/api-reference/sites.md"><strong>API: site update</strong></a></p></td><td>Set <code>cyclic_write_timeout</code> via <code>PUT /sites/{site_id}</code>.</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://renewables.docs.helinplatform.com/sgm-product-docs/concepts/cyclic-writer.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
