Operators allow you to check the value of trait attributes against specific
values, compare them to one another, and to combine expressions used in
`condition` nodes.

Operators are made available through the following `import` statements:

```kotlin
import com.google.home.automation.and
import com.google.home.automation.between
import com.google.home.automation.contains
import com.google.home.automation.equals
import com.google.home.automation.greaterThan
import com.google.home.automation.greaterThanOrEquals
import com.google.home.automation.lessThan
import com.google.home.automation.not
import com.google.home.automation.notEquals
import com.google.home.automation.or
```

## Comparison operators

### between

Evaluates to `true` when the value of Expression 1 is between that of Expression
2 and Expression 3 (inclusive). Expressions are ranked differently depending on
their data type. Simple data types such as numbers and strings are ranked the
same way they are in Kotlin.

<br />

| Expression 1 | Expression 2 | Expression 3 | Result |
|:---:|:---:|:---:|:---:|
| `6` | `1` | `3` | `false` |
| `2` | `1` | `3` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
val time = stateReader<_>(structure, Time)
condition() {
  expression = time.currentTime
     .between(
      time.sunsetTime,
      time.sunriseTime)
}
```

#### Use dates with between()

When using the `between()` operator, you can specify a range of dates:

```kotlin
val exp2 =
  time.currentDate.between(
    LocalDate.of(2025, Month.OCTOBER, 1),
    LocalDate.of(2025, Month.DECEMBER, 15),
  )
```

However, you're not limited to full dates. The Automation DSL also lets you
express a range of dates in a variety of ways:

- Using only year and month:

```kotlin
val exp2 =
  time.currentDate.yearMonth.between(
    YearMonth.of(2024, Month.OCTOBER),
    YearMonth.of(2026, Month.JANUARY),
  )
```

- Using only month and day:

```kotlin
val exp2 =
  time.currentDate.monthDay.between(
    MonthDay.of(Month.OCTOBER, 1),
    MonthDay.of(Month.DECEMBER, 15),
  )
```

- Using only the day of the month:

```kotlin
val exp2 = time.currentDate.day.between(1, 15)
```

### equals

Evaluates to `true` when the Expression 1 equals Expression 2.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `6` | `1` | `false` |
| `2` | `2` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
washer.operationalState equals STOPPED
```

### greaterThan

Evaluates to `true` when the Expression 1 is greater than Expression 2.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `6` | `1` | `true` |
| `1` | `6` | `false` |
[*Example*]

<br />

#### DSL example

```kotlin
( blindsPosition.currentPositionLift greaterThan 0u )
```

### greaterThanOrEquals

Evaluates to `true` when the Expression 1 is greater than or equal to Expression
2.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `8` | `6` | `true` |
| `6` | `6` | `true` |
| `1` | `6` | `false` |
[*Example*]

<br />

#### DSL example

```kotlin
( starterNode.measuredValue greaterThanOrEquals 50 )
```

### lessThan

evaluates to `true` when the Expression 1 is less than Expression 2.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `6` | `1` | `false` |
| `1` | `6` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
time.currentTime lessThan LocalTime.of(22,0,0,0)
```

### lessThanOrEquals

Evaluates to `true` when the Expression 1 is less than or equal to Expression 2.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `8` | `6` | `false` |
| `6` | `6` | `true` |
| `1` | `6` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
( starterNode.measuredValue lessThanOrEquals 25 )
```

### notEquals

Evaluates to `true` when the Expression 1 is not equal to Expression 2.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `6` | `1` | `true` |
| `1` | `6` | `true` |
| `2` | `2` | `false` |
[*Example*]

<br />

#### DSL example

```kotlin
occupancyStateChange.occupied notEquals 0
```

## Arithmetic operators

### Add

The addition operator ( `+` ).

#### DSL example

```kotlin
var totalCount = 0
...
totalCount = totalCount + 1
```

### Subtract

The subtraction operator ( `-` ).

#### DSL example

```kotlin
var countdown = 10
...
countdown = countdown - 1
```

### Multiply

The multiplication operator ( `*` ).

#### DSL example

```kotlin
val millis = seconds * 1000
```

### Divide

The division operator ( `/` ).

#### DSL example

```kotlin
val rpm = revolutions / minutes
```

## Logical operators

### and

Combines two expressions in a logical AND expression, evaluating to `true` when
both expressions are `true`.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `false` | `false` | `false` |
| `true` | `false` | `false` |
| `false` | `true` | `false` |
| `true` | `true` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
((device.occupied notEquals 0) and
   time.currentTime.between(time.sunriseTime, time.sunsetTime))
```

### not

Negates the logical value of an expression.

<br />

| Expression | Result |
|:---:|:---:|
| `true` | `false` |
| `false` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
time.currentTime not (between(time.sunriseTime, time.sunsetTime))
```

### or

Combines two expressions into a logical OR expression.

<br />

| Expression 1 | Expression 2 | Result |
|:---:|:---:|:---:|
| `false` | `false` | `false` |
| `true` | `false` | `true` |
| `false` | `true` | `true` |
[*Example*]

<br />

#### DSL example

```kotlin
(time.currentTime equals LocalTime.of(10,0,0,0)) or
  (time.currentTime equals LocalTime.of(22,0,0,0))
```