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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gazetteer_matcher-1.1.0.tar.gz (89.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

gazetteer_matcher-1.1.0-cp311-abi3-win_arm64.whl (436.4 kB view details)

Uploaded CPython 3.11+Windows ARM64

gazetteer_matcher-1.1.0-cp311-abi3-win_amd64.whl (265.4 kB view details)

Uploaded CPython 3.11+Windows x86-64

gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (202.9 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (201.8 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

gazetteer_matcher-1.1.0-cp311-abi3-macosx_11_0_arm64.whl (74.2 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

gazetteer_matcher-1.1.0-cp311-abi3-macosx_10_9_x86_64.whl (74.7 kB view details)

Uploaded CPython 3.11+macOS 10.9+ x86-64

File details

Details for the file gazetteer_matcher-1.1.0.tar.gz.

File metadata

  • Download URL: gazetteer_matcher-1.1.0.tar.gz
  • Upload date:
  • Size: 89.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gazetteer_matcher-1.1.0.tar.gz
Algorithm Hash digest
SHA256 844d11cb781302aded70f0a8eae8a2d1601e6e2aaa006745a667b500097635cc
MD5 39fd0196712e4847c974908ba3a5b32f
BLAKE2b-256 757d2bc97376715b9d95c769fe07b4143b2e7d51e7d08150714d7cce3e1c0203

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0.tar.gz:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gazetteer_matcher-1.1.0-cp311-abi3-win_arm64.whl.

File metadata

File hashes

Hashes for gazetteer_matcher-1.1.0-cp311-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 ab3749cd1a2498302aecd0fa1d159d467ad17067a279f7dda83ff9a596111701
MD5 12072c08c72438e80bd4efad8fe07518
BLAKE2b-256 1ff5cdc362c96e75463a61eed90941755fc7461ea7c2e76400e2ad219690e4ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0-cp311-abi3-win_arm64.whl:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gazetteer_matcher-1.1.0-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for gazetteer_matcher-1.1.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f81042403497db23862e2dfa4915100a896a097a45ef5f834ef2a75afbd912e3
MD5 8c3ad9a0eb34c1c1e250edb7cc89078c
BLAKE2b-256 dac18233756448c63d59669479c0a3ca6727338627874dfcb8f60fdae219d168

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0-cp311-abi3-win_amd64.whl:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c6c28513c3689768ec1a75fb1b2c3153ab424a65f6992579b311c57652523c5a
MD5 45fb6c51e3b2633fe83fe4545516439a
BLAKE2b-256 0968aab65e4471b594ca83742451247523e020a767cde516c34b94d03070b551

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 edd1c12a3bd8e30ea6f4da8e4554fc1386e21606f08901bf7a24a998602b6105
MD5 f85c26eda1e43e6675fd104112e15869
BLAKE2b-256 6ae537d1158ce9444d7784071a54b1895e2d759dd0b0dedfd34b0877a5aca2c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0-cp311-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gazetteer_matcher-1.1.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gazetteer_matcher-1.1.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0fb123e88528f9862608efd858b386c43332549a6aa4afdcb7611d6d3645b7f0
MD5 e2ad21f8504cc4492f664137be097713
BLAKE2b-256 8239151c2477a934fb048b8a72d425d9dbd506ebe84123d7089cc0c885dd49c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gazetteer_matcher-1.1.0-cp311-abi3-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for gazetteer_matcher-1.1.0-cp311-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 9460da761c68ba57679ee773462bcbf708743c44e92197009def43ac5ac5dd86
MD5 8eab6e5505a65d24b327bfdf128b4270
BLAKE2b-256 0b60094b23d28b1447ee68477d35632677f0c64d20161d0fda7347ba26664044

See more details on using hashes here.

Provenance

The following attestation bundles were made for gazetteer_matcher-1.1.0-cp311-abi3-macosx_10_9_x86_64.whl:

Publisher: publish.yml on OHF-Voice/gazetteer-matcher

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.1.0 This release

7 files

1.0.0

25 files

0.1.0

1 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