Skip to main content

Gazetteer Matcher

An English-language, constraint-driven intent recognizer for Home Assistant voice commands. It complements Home Assistant's built-in sentence grammars by handling home-specific names, fuzzy wording, compound requests, and explicit conversation references while rejecting interpretations that do not fit the upstream intent schema.

Features

  • Flexible and fuzzy target matching for entities, areas, floors, domains, and actions: turn on the bedrom lamp resolves to Bedroom Lamp.
  • Location-aware disambiguation from spoken qualifiers and voice-satellite context: bedroom TV selects the TV assigned to the bedroom.
  • Compound commands with multiple targets, intents, or properties: turn off the kitchen lights and open the bedroom blinds.
  • Multiple actions on one target: turn on the hallway light and set its brightness to 40%.
  • Explicit conversational follow-ups: turn on the kitchen lights followed by turn them off, or is the front door locked? followed by lock it.
  • Conservative, schema-backed validation with structured error categories and concise responses for ambiguous, unsupported, and out-of-range requests.

Install

pip install gazetteer-matcher

Runtime dependencies are home-assistant-intents, unicode-rbnf, and PyYAML. A source install also attempts to build a self-contained C++17 fuzzy scorer. Installation still succeeds without a compiler and uses the behaviorally equivalent Python implementation instead.

For development:

pip install 'gazetteer-matcher[dev]'
pytest

Quick start

from gazetteer_matcher import GazetteerMatcher

matcher = GazetteerMatcher(
    home={
        "areas": {
            "kitchen": {"name": "Kitchen", "floor": "ground"},
        },
        "floors": {
            "ground": {"name": "Ground Floor"},
        },
        "entities": {},
    }
)

result = matcher.interpret("flick on the kichen lights")
assert result.accepted

frame = result.frames[0]
assert frame.intent == "HassTurnOn"
assert frame.slots == {"area": "kitchen", "domain": "light"}
assert frame.response_key == "lights_area"

Pass the voice satellite's location when a command omits it:

result = matcher.interpret("turn off the lights", context_area="Kitchen")
assert result.frames[0].slots == {"domain": "light", "area": "kitchen"}

Interpretations can contain several ordered frames:

result = matcher.interpret(
    "turn off the kitchen lights and open the bedroom blinds"
)

assert [frame.intent for frame in result.frames] == [
    "HassTurnOff",
    "HassTurnOn",
]

Rejected requests carry an integration-facing category, a diagnostic reason, and an optional ready-to-use response:

result = matcher.interpret("set bedroom TV volume to 1000%")

assert not result.accepted
assert result.rejection_code == "invalid_percentage"
assert result.response == (
    "Sorry, the volume value must be a whole-number percentage "
    "between 0% and 100%."
)

Core API

GazetteerMatcher.interpret() accepts:

  • the utterance;
  • optional context_area and context_floor values;
  • optional previous_targets exported by a prior accepted interpretation.

An accepted Interpretation exposes ordered frames and reusable targets. Each frame contains the Home Assistant intent, slot combination, resolved slot values, response key, and selection diagnostics. Rejected interpretations expose rejection_code, reason, response, and refusal_target; their targets collection is always empty.

The matcher itself is stateless. The caller decides whether a prior target is recent enough to pass back:

previous = matcher.interpret("open the bedroom blinds")
result = matcher.interpret(
    "close them",
    previous_targets=previous.targets,
)

Call matcher.set_home(...) to replace the entity/area/floor gazetteer without rebuilding the language vocabulary, intent catalog, or shared number trie.

Documentation

  • Usage guide — context, compound commands, state questions, follow-ups, response keys, and rejection handling
  • Configuration — the home gazetteer, vocabulary, response wording, and runtime updates
  • Development — CLI diagnostics, fixture tests, rejection tests, and upstream coverage measurement
  • Internals — tagging, intent constraints, number words, fuzzy scoring, coordination, scope, and candidate selection

CLI

gazetteer-match match 'turn on the kitchen and hallway lights' \
  --home my-home.yaml
gazetteer-match match 'flick on the kichen lights' \
  --home my-home.yaml --debug
gazetteer-match match 'open the bedroom blinds' \
  --home my-home.yaml --debug --json
gazetteer-match spans 'flik the bedroom lights on'
gazetteer-match support

match requires either --home PATH or an explicit --empty-home. The latter is useful for generic timers, date/time, weather, and state questions that need no home-specific names. spans keeps --home optional, while support does not use a home gazetteer. Supply --vocabulary or --responses to override the language data. Location context is available through --context-area and --context-floor. See the development guide for the complete debugging and coverage workflow.

Design principle

Fuzzy similarity is evidence, not permission. A close spelling match cannot outweigh incompatible Home Assistant slots, contradictory scope, unexplained semantic content, or an equally good competing interpretation. When the matcher cannot choose one valid meaning, it rejects the request rather than guessing.

Metadata

Release files for gazetteer-matcher 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gazetteer-matcher 1.2.0
File Size Uploaded
gazetteer_matcher-1.2.0.tar.gz 103.5 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for gazetteer-matcher 1.2.0
File
gazetteer_matcher-1.2.0-cp311-abi3-win_arm64.whl CPython 3.11 abi3 Windows ARM64 Details
gazetteer_matcher-1.2.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
gazetteer_matcher-1.2.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 Details
gazetteer_matcher-1.2.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64, Linux glibc 2.24+ ARM64 Details
gazetteer_matcher-1.2.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
gazetteer_matcher-1.2.0-cp311-abi3-macosx_10_9_x86_64.whl CPython 3.11 abi3 macOS 10.9+ x86-64 Details

Total release size: 1.4 MB

Release files / gazetteer_matcher-1.2.0.tar.gz

Download URL gazetteer_matcher-1.2.0.tar.gz
Size 103.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a8b47792898cc081d5f29b4548fa82ebdc69294549347ba83f8e12a3e9c3118a
BLAKE2b-256 checksum
How to use checksums
45868649c665f5dc051b62bbe8e28c9165a0a435b54d7e8055d7c91172d0e3b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / gazetteer_matcher-1.2.0-cp311-abi3-win_arm64.whl

Download URL gazetteer_matcher-1.2.0-cp311-abi3-win_arm64.whl
Size 442.2 kB
Tags CPython 3.11 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
ed50d674d451324708f2a0c48f068b7cb1201be5d049eae856d7b635b987fb93
BLAKE2b-256 checksum
How to use checksums
d2921a33e21f7e57535e012964b47fab78dbd1ec98f1501a11320dab5d5f1c2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / gazetteer_matcher-1.2.0-cp311-abi3-win_amd64.whl

Download URL gazetteer_matcher-1.2.0-cp311-abi3-win_amd64.whl
Size 275.0 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
5bd1967cdef3aa0c22dd8dddd3949f91e4e7c67f65a528aae92f0cf0e90c6b11
BLAKE2b-256 checksum
How to use checksums
6612a3d842f8cf113da8ba4db606c84bad515b923dabb0ea7726d142dd9edf56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / gazetteer_matcher-1.2.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL gazetteer_matcher-1.2.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 212.3 kB
Tags CPython 3.11 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
907e9210a8a9fb57136d7332272e79bef29c359fc41da98cb63c3fb5336b6c39
BLAKE2b-256 checksum
How to use checksums
c0135cc0dbbeee7769e0ede0eef42ae96beb92de976bd5176a3a69a79129d38b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / gazetteer_matcher-1.2.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL gazetteer_matcher-1.2.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 211.3 kB
Tags CPython 3.11 Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
56927aea02974b2530ae93125761dd600140251ad5772d33cd4050fbca45932a
BLAKE2b-256 checksum
How to use checksums
aba956e983206b464e51404fad54cde47270ffcd95541b93fd1277694ff9ccdf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / gazetteer_matcher-1.2.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL gazetteer_matcher-1.2.0-cp311-abi3-macosx_11_0_arm64.whl
Size 83.6 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f0a7a105f9cb4c1933916ef6af56bf9a263a8a263cb22dafe94c949e696a337a
BLAKE2b-256 checksum
How to use checksums
a019e35c3efeb2ac3c9623cab69a4db8c588e2bb6dffe7d93020ded8e487a6f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / gazetteer_matcher-1.2.0-cp311-abi3-macosx_10_9_x86_64.whl

Download URL gazetteer_matcher-1.2.0-cp311-abi3-macosx_10_9_x86_64.whl
Size 84.2 kB
Tags CPython 3.11 abi3 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
a2fa70f809e66d8a40fe890ef0936e749ee408c7542065bbf2cf248179099165
BLAKE2b-256 checksum
How to use checksums
4d345d3d9d7c40b4a533fb8b27ac44aa4e6c89dc97fb5a28d1fb4e518a9103d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

7 release files

1.1.0

7 release files

1.0.0

25 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page