GitHub - moritz-john/homeassistant.koplugin: This KOReader plugin lets you control Home Assistant entities without leaving your current book!

GitHub

8 min read Original article β†—

In case you are coming from koreader/contrib, make sure that you check out the latest commit.

Jump to the [Installation], [Configuration] or [Examples] section

homeassistant.koplugin screenshots homeassistant.koplugin: a template query [left] & ButtonDialog gesture [right]

Features

  • Control any number of Home Assistant entities from KOReader
  • Action support with custom data attributes e.g.:
    • light.turn_on with brightness and color
    • media_player.play_media with media_content_id & type
  • Advanced targeting: single/multiple entities, areas or labels
  • Entity state queries with customizable attributes e.g.:
    • sensor.temperature_outside: state, last_updated
  • Evaluate Home Assistant templates
  • Simple text-based configuration

Installation

Step 1: Download the Plugin

Download the latest release and unpack homeassistant.koplugin.zip

Step 2: Copy the Plugin to Your Device

Copy the entire homeassistant.koplugin folder into koreader/plugins/.

Step 3: Restart KOReader

On first start, the plugin creates your configuration file in koreader/settings/homeassistant_config.lua.

πŸ“‚ koreader/settings/
β”œβ”€β”€ homeassistant_config.lua
└── ... (other files)

Step 4: Edit Your Config

Connect your device to your computer and edit koreader/settings/homeassistant_config.lua.

The example entries are placeholders and won't work until you add your host, port and token, and edit the entities to match your own setup. When you're done, set show_setup_hint = false.

See the Configuration section for details.

Step 5: Restart KOReader Again

Restart KOReader so the new config is loaded. The plugin is now available under Tools β†’ Page X β†’ Home Assistant or can be called from KOReader gestures.

Configuration

All configuration lives in koreader/settings/homeassistant_config.lua.
It consists of connection settings and a list of entries (Home Assistant entities).

Warning

Be careful with {} and , otherwise you will get syntax errors.

Connection Settings

First, add your Home Assistant connection details.
Change host, port, https and token according to your personal setup:

return {
    show_setup_hint = true,
    host = "192.168.1.10",
    port = 8123,
    https = false,
    token = 
    "PasteYourHomeAssistantLong-LivedAccessTokenHere",

    entities = {
        -- your entities go here (see below)
    },
}

Tip

How to create a Long-Lived Access Token:
Home Assistant: Profile β†’ Security (scroll down) β†’ Long-lived access tokens β†’ Create token
Copy the token now – you won’t be able to view it again.


Adding Home Assistant entities

Inside the entities table in homeassistant_config.lua, you can define three types of items:

Type Purpose Required Fields Optional
action Control an entity (e.g., turn on light) label, action, target data
state query Read a state (e.g., check temperature) label, target, attributes
template Evaluate a template label, template

Think of each entry as a single Home Assistant action or state query that becomes a button or gesture in KOReader.

Controlling Entities | 'action'

Let's start with a simple example: "turn on a light".
The entry in homeassistant_config.lua would look like this:

{   
    label = "Reading Lamp: turn_on",
    action = "light.turn_on",
    target = "light.reading_lamp",
},

You are not limited to light.turn_on - any Home Assistant action works, for example:
scene.turn_on, automation.trigger, input_button.press, fan.toggle, switch.turn_off etc...

Adding Data to Actions | 'data = {...}'

You can add additional data to your action. In this example we add the data attributes brightness and rgb_color to action light.turn_on through data:

{
    label = "Reading Lamp: turn blue",
    action = "light.turn_on",
    target = "light.reading_lamp",
    data = {
        brightness = 90,
        rgb_color = { 0, 0, 255 },
    },
},

The syntax in homeassistant_config.lua is loosely based on the YAML action syntax in Home Assistant.

Finding Available Action Attributes:

To discover what additional data you can send with an action:

  • Go to your Home Assistant instance β†’ Developer Tools β†’ Actions
    Play around with an action call, then click on "Go to YAML mode"

  • Check the official Home Assistant integration documentation, examples:
    Light, Fan, Media player or Climate

Tip

Take a look at the example section to see what's possible with homeassistant.koplugin.

Targeting Entities, Areas or Labels

You may target multiple entities, areas, or labels – but do not mix target types.

Target Scope Example homeassistant_config.lua Syntax
Single Entity target = "light.reading_lamp",
Multiple Entities target = {"light.lamp_1", "light.lamp_2"},
Area target = { area_id = "living_room" },
Label target = { label_id = {"nook", "desk"} },
Special Case target = "all",
Unsupported target = { entity_id = "lamp", area_id = "room" }

You can either use one single line or indentation:

{
    label = "Reading Lamp: turn_on",
    action = "light.turn_on",
    target = {
        area_id = {
            "living_room",
            "bed_room",
        },
    },
},

Get Entity States | 'state query'

To retrieve an entity's state and/or attributes, omit the action field.
attributes defines which state attributes will be displayed in the result pop-up.

{
    label = "\u{E350} Temperature Living Room",
    target = "sensor.living_room_temperature",
    attributes = { "state", "last_updated" },
},

Finding Available States & Attributes:

Go to Home Assistant instance β†’ Developer Tools β†’ States.
Select an entity and check the State and Attributes sections.

Note

State Query Limitations:

  • Queries require a single entity_id
  • Area and label targeting is not supported
  • Deeply nested JSON attributes may not display cleanly

Evaluating Templates | 'template'

You can evaluate Home Assistant templates with homeassistant.koplugin.
Templating can display complex & dynamic information.
Use templates to create conditional messages that go far beyond simple state queries.

{   
    label = "Time, Sun & Lights",
    template = [[
    {{ now().strftime('%Y-%m-%d %H:%M:%S') }}
    Sun: {{ "sun.sun" | state_translated }}
    Lights left on: {{ states.light | selectattr('state', 'eq', 'on') | list | count }}
    ]]
},

Be aware of the template = [[ ]] syntax.

How to create and test your templates:

Go to your Home Assistant instance β†’ Developer Tools β†’ Template
Use the template editor to test your code before pasting it into the template = [[...]] section of your config.

Examples

Actions

Turn off all switches:

{
    label = "All Switches: turn_off",
    target = "all",
    action = "switch.turn_off",
},

Play music through Spotify on your Sonos speaker:

{
    label = "Play Music",
    action = "media_player.play_media",
    target = "media_player.sonos",
    data = {
        media_content_id = "https://open.spotify.com/album/abcdefghij0123456789YZ",
        media_content_type = "music",
    },
},

Set standing desk height:

{
    label = "Set Desk Height to 80cm",
    target = "number.upsy_desky_target_desk_height",
    action = "number.set_value",    
    data = {
        value = 80.0
    },
},

Quit Kodi on a specific device:

{
    label = "Quit Kodi",
    target = "media_player.mac_mini",
    action = "kodi.call_method",
    data = {
        method = "Application.Quit"
    },
},

Example YAML to homeassistant_config.lua syntax with ALL the data:

Details

In theory you can take the whole data part (!) from a Home Assistant YAML action and "convert" it into the Lua syntax required in homeassistant_config.lua:

{
    label = "Play Nobody 2",
    action = "media_player.play_media",
    target = "media_player.firefox",
    data = {
        media = {
            media_content_id = "b594b3cf9c9a6778d0422b542ff654b8",
            media_content_type = "movie",
            metadata = {
                title = "Nobody 2",
                thumbnail = "http://192.168.10.12:8096//Items/b594b3cf9c9a6778d0422b542ff654b8/Images/Primary?MaxWidth=600&format=jpg&api_key=1f14dc0c0e5f4c9597156f186508316e",
                media_class = "movie",
                children_media_class = nil,
                navigateIds = {
                    {},
                    {
                        media_content_type = "collection",
                        media_content_id = "f137a2dd21bbc1b99aa5c0f6bf02a805",
                    },
                },
                browse_entity_id = "media_player.firefox",
            },
        },
    },
},

[!Note]

This example is intentionally verbose and included for completeness. Most users will never need this level of detail.

Templates

Get information about the currently playing song (as template):

{
    label = "Currently Playing",
    template = [[
    {% set player = 'media_player.firefox' %}
    {% set duration = state_attr(player, 'media_duration') | int(0) %}

    Song: {{ state_attr(player, 'media_title') or '-' }}
    Artist: {{ state_attr(player, 'media_artist') or '-' }}
    Album: {{ state_attr(player, 'media_album_name') or '-' }}
    Length: {{
    (duration // 60) ~ ':' ~ '%02d'|format(duration % 60)
    if duration > 0
    else '-'
    }}
    ]]
},

State Queries

Check if the light in the shed was left on:

{
    label = "\u{EA2B} Shed Light on?",
    target = "light.shed_ceiling_light",
    attributes = { "state", "brightness", "last_changed" },
},

KOReader Gestures

You can trigger your Home Assistant entities directly through KOReader gestures.
Each gesture can be assigned to any entity you have configured in homeassistant_config.lua.

For any chosen gesture, you will find your entities in:
Generalβ–Έ β†’ Page 1–X: [find your Home Assistant entity]

The actions are named after the label of each entity.

A complete gesture example:
Settings β†’ Taps and gestures β†’ Gesture managerβ–Έ
Long-press on cornerβ–Έ β†’ Bottom Left β†’ Generalβ–Έ β†’ Page 1–X: Reading Lamp β†’ turn_on

If you want several entities behind a single gesture, you can build a list manually with a Quick Menu.

ButtonDialog

The simplest way to access all your Home Assistant entities is the built-in gesture action ☰ Home Assistant: all entities.
It opens a ButtonDialog that lists every entity from your configuration file. Tap an entity to run it.

Unlike a manual Quick Menu, it updates itself: changes to homeassistant_config.lua appear after the next KOReader restart.

Result (triggered via Long-press on corner: Bottom Right):

Requirements

  • KOReader (tested with: 2026.07.1 on a Kindle Basic 2024)
  • Home Assistant & a Long-Lived Access Token

Screenshots

Resources

KOReader Website

Home Assistant: REST API
Home Assistant: Performing actions
Home Assistant: State and state object