# Designing Rules

A well-designed rule is the foundation of a good user experience. The core of the MOOST platform is the rule engine, which allows you to define the precise conditions that trigger a recommendation. If this underlying logic is irrelevant, poorly timed, or triggers too often, the notification will be perceived as spam, no matter how well-designed the app is.

This guide covers best practices for designing the logical conditions for your rules in the Rule Configurator.

***

## Best Practices for Rule Design

### Be Proactive, Not Just Reactive

Your most valuable rules will anticipate user needs. Leverage the Context Services(like `$WeatherForecast` or `$SolarProductionForecast`) to send recommendations *before* an event happens.

{% hint style="danger" %}
Bad Rule - Only act on current status without considering future changes.

`IF $GridPowerConsumption > 5000 THEN send "High grid usage"`
{% endhint %}

{% hint style="success" %}
Good Rule - Taking forecast information into consideration before sending a recommendation.

`IF $SolarProductionForecast_Next3Hours < 500 AND $CarChargingMode = "ON" THEN send "Cloudy weather is expected. We recommend pausing car charging to save costs."`
{% endhint %}

### Prevent "Notification Flapping"&#x20;

Avoid rules that trigger on and off rapidly from fluctuating data. Use **aggregation functions** ([AVG](/platform-manual/rules/rule-language/functions/avg.md), [MIN](/platform-manual/rules/rule-language/functions/min.md), [MAX](/platform-manual/rules/rule-language/functions/max.md), [SUM](/platform-manual/rules/rule-language/functions/sum.md)) to check for conditions over a stable time window or use properties [Match Threshold](/platform-manual/rules/rule-configurator/settings.md#match-threshold) or [Time Between Notifications](/platform-manual/rules/rule-configurator/settings.md#time-between-notifications) to prevent over notification.

{% hint style="danger" %}
Bad Rule - Always act on a single data point that can change heavily

`IF $GridPowerConsumption > 1000 THEN send "High Usage"`
{% endhint %}

{% hint style="success" %}
Good Rule - Acting on an average of timeseries dataset over a period of time

`IF AVG($GridPowerConsumption) > 1000 THEN send "Your average usage has been high for the last 15 minutes."`
{% endhint %}

### Create Highly Specific, Contextual Triggers

The best rules combine multiple data points using `AND` / `OR` logic to find a truly specific, actionable moment. A simple threshold is mostly not enough to send hyper personalised recommendations.

{% hint style="danger" %}
Bad Rule - Reyling on a single dataset to find a specific, actionable moment.

`IF $BatteryLevel < 20 THEN send "Battery is low"`
{% endhint %}

{% hint style="success" %}
Good Rule - Comining multiple datasets to find a specific, actinable moment.

`IF $BatteryLevel < 20 AND $IsLowTariffHours = 1 AND $SolarProductionForecast_NextHour = 0 THEN send "Your battery is low. We recommend charging from the grid now while tariffs are cheap."`
{% endhint %}

### Personalize with Profile Data

Use information from the Household Profile to make rules relevant to the specific user. A rule for a "cost-saving-motivated" user should be different from one for an "eco-motivated" user.

### Always Use the Rule Simulator&#x20;

This is the most critical step. Before activating any rule, use the Rule Simulator to test it against historical data from several different buildings and time ranges. The simulator allows you to:

* Verify the rule triggers only when you expect it to.
* See the exact notification text with dynamic data filled in.
* Ensure the rule does *not* trigger when it shouldn't.


---

# Agent Instructions: 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:

```
GET https://doc.moost.io/best-practices/user-experience/designing-rules.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
