Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 33 additions & 12 deletions docs/data_states.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,33 @@ The `<domain>` part of an entity identifier is equal to the Home Assistant compo

All states are stored in the database in a table named `states`.

The difference between `last_changed` and `last_updated` is that `last_changed` only updates when the `state` value was changed while `last_updated` is updated on every state change. Example: if a light turns on, the state changes from `off` to `on`, so both `last_updated` and `last_changed` will update. If a light changes color from red to blue, only the state attributes change. In this case only `last_updated` will change. By distinguishing between these two values, we can easily identify how long a light has been on and how long it has been on the current color/brightness.
The difference between `last_changed` and `last_updated` is that `last_changed` only updates when the `state` value was changed while `last_updated` is updated on any change to the state, even if that included just attributes. Example: if a light turns on, the state changes from `off` to `on`, so both `last_updated` and `last_changed` will update. If a light changes color from red to blue, only the state attributes change. In this case only `last_updated` will change. By distinguishing between these two values, we can easily identify how long a light has been on and how long it has been on the current color/brightness.

| Field | Type |
| ----------------- | ------------------------------------------------------------------------- |
| state_id | Column(Integer, primary_key=True) |
| domain | Column(String(64)) |
| entity_id | Column(String(255)) |
| state | Column(String(255)) |
| event_id | Column(Integer, ForeignKey('events.event_id'), index=True) |
| last_changed | Column(DateTime(timezone=True), default=datetime.utcnow) |
| last_updated | Column(DateTime(timezone=True), default=datetime.utcnow, index=True) |
| old_state_id | Column(Integer, ForeignKey("states.state_id"), index=True) |
| attributes_id | Column(Integer, ForeignKey("state_attributes.attributes_id"), index=True) |

The `created` field is no longer stored in the `states` table to avoid duplicating data in the database as it was always the same as `last_updated` and the matching `state_change` event's `time_fired`.

As many `attributes` are the same, attributes are stored in the `state_attributes` table with many to one relationship:

| Field | Type |
| ----------------- | -------------------------------------------------------------------- |
| state_id | Column(Integer, primary_key=True) |
| domain | Column(String(64)) |
| entity_id | Column(String(255)) |
| state | Column(String(255)) |
| attributes | Column(Text) |
| event_id | Column(Integer, ForeignKey('events.event_id'), index=True) |
| last_changed | Column(DateTime(timezone=True), default=datetime.utcnow) |
| last_updated | Column(DateTime(timezone=True), default=datetime.utcnow, index=True) |
| old_state_id | Column(Integer, index=True) |
| attributes_id | Column(Integer, primary_key=True) |
| hash | Column(BigInteger, index=True) |
| shared_attrs | Column(Text().with_variant(mysql.LONGTEXT, "mysql")) |

The `created` field is no longer stored in the `states` table to avoid duplicating data in the database as it was always the same as `last_updated` and the matching `state_change` event's `time_fired`.
Below is an example query to find `attributes` that were recordered after the change over.

### Indices
### `states` Indices

| Name | Fields |
| -------------------------------- | ----------------------- |
Expand All @@ -51,3 +61,14 @@ After startup, once a state is changed, the id of the old state is stored as `ol
```sql
SELECT * FROM states LEFT JOIN states as old_states ON states.old_state_id = old_states.state_id
```

### Fetching attributes

Attributes are stored in the `state_attributes` table.

```sql
SELECT * FROM states LEFT JOIN state_attributes ON states.attributes_id = state_attributes.attributes_id
```

Attributes can be found in the following order `state_attributes.shared_attrs` or `states.attributes`.
As new states are recorded `states.attributes` will be phased out.