iobroker.hannah
v0.32.5
Published
Connects ioBroker to Hannah voice assistant via bidirectional gRPC — streams device states, presence and commands in real time.
Readme

ioBroker.hannah
Hannah adapter for ioBroker
Connects ioBroker to the Hannah voice assistant via a bidirectional gRPC stream. Device states, presence information and text commands flow from ioBroker to Hannah in real time; Hannah sends SetState commands back when it controls devices.
This adapter replaces the previous MQTT-based integration and eliminates the message-loop problems that came with retained topics and wildcard subscriptions.
Features
- Bidirectional gRPC stream — persistent connection with automatic reconnect
- Device discovery via ioBroker enums (rooms × functions) with configurable filters
- Extra state prefixes — subscribe to any additional state tree (e.g. car tracker, weather adapter)
- Snapshot on connect — current state values are pushed to Hannah immediately after connecting, replacing MQTT retained messages
- Resident presence — forwards presence state changes from the Residents adapter
- Text commands — write to
hannah.<instance>.textCommandto send text queries to Hannah - SetState — Hannah can set ioBroker states directly via the same gRPC channel
- Notifications — forward messages to Hannah via
sendToor the native ioBroker Notification Manager; LLM reformulation for system messages, direct TTS forsendDirect - Announcements — play TTS in specific satellite rooms and/or for a specific Person via
sendTowith a room list and/or roomie ID, without LLM or Telegram - Blockly support — custom blocks for direct messages and room/Person announcements
Requirements
- ioBroker js-controller ≥ 5.0
- Node.js ≥ 22
- A running Hannah Core instance with gRPC enabled (default port 50051)
Installation
Install via the ioBroker admin interface
Configuration
Connection tab
| Field | Description | Default |
|-------|-------------|---------|
| Hannah Host | IP address or hostname of the Hannah Core server | 127.0.0.1 |
| gRPC Port | Port Hannah Core listens on | 50051 |
Device Discovery tab
Select which rooms and functions Hannah should be aware of. Leaving both lists empty includes everything.
Extra State Prefixes — additional ioBroker state ID prefixes to stream to Hannah, e.g.:
| Use case | Prefix |
|----------|--------|
| Car tracker (VW-Connect) | javascript.0.virtualDevice.Auto |
| Weather (openweathermap adapter) | openweathermap.0.forecast |
| User variables | 0_userdata.0 |
Integrations tab
| Field | Description | |-------|-------------| | Residents Adapter Instance | Instance number of the Residents adapter for presence tracking |
Adapter states
| State | Type | Description |
|-------|------|-------------|
| hannah.<instance>.info.connection | boolean | true while connected to Hannah Core |
| hannah.<instance>.textCommand | string | Write a text query here (ack=false) to send it to Hannah |
Hannah Core configuration
The adapter expects HannahService.AgentConnect to be available on the configured host/port. No additional Hannah-side configuration is required — the adapter identifies itself automatically on connect.
Changelog
0.32.5 (2026-07-15)
- Fixed:
iaq/iaq_accuracy/co2_equiv/voc_equivsensor states no longer log "has no existing object" warnings if a satellite's first sensor update arrives before BSEC2 has produced a valid IAQ reading
0.32.4 (2026-07-13)
- Fixed:
last_seensatellite state now uses roledateinstead ofvalue.time(which requires a numeric epoch timestamp, not the ISO string this adapter stores) - Fixed: satellite/room online indicators now use role
indicator.reachableinstead ofindicator.connected(reserved for instances) - Fixed: firmware version state now uses role
info.firmwareinstead of the generictext - Fixed: the virtual "all" satellite room folder no longer has a German name
- Fixed: BLE tag states no longer have German object names, and tag labels are now sanitized before being used in object IDs
- Fixed: sensor
pressurestate now uses unitmbarinstead ofhPaper the role definition, and satellite device IDs are now sanitized before being used in sensor object IDs - Fixed:
textCommand/textAnswerstates now use roletextinstead of the genericstate, and a typo intextCommand's display name was corrected - Fixed: a pending
ask(sendTowith aresident_answeredcallback) is no longer left dangling forever if Hannah Core disconnects before an answer arrives - Fixed: HTTP requests to a satellite's NVS endpoint and to the firmware update server now time out instead of hanging indefinitely if the target is unreachable
- Changed: satellite default credentials (WiFi/MQTT passwords, OTA/asset/NVS tokens) are now encrypted and protected in the adapter configuration, matching the existing firmware source token
- Fixed: removed a stale, untranslated
Write NVSkey from the non-English admin UI translations
0.32.3 (2026-07-12)
- Added: device snapshot now reports whether each state is writable (
AgentDevice.writable, from ioBroker'scommon.write) — lets Hannah/the WebUI exclude read-only states (sensors, etc.) from control actions - Changed:
@m1kad0/hannah-protobumped to 0.5.2
0.32.2 (2026-07-12)
- Added:
state-watcher.ts's device-type detection now recognizes a "Szene"/"scene" function, resolving to typescene— lets room-scoped scene states be enum-discovered like any other device without being pulled into "Licht"-category group commands
0.32.1 (2026-07-11)
- Changed:
@m1kad0/hannah-protobumped to 0.5.0. No functional change for this adapter (it never called the removedRoutine*RPCs).
0.32.0 (2026-07-11)
- Added:
state-watcher.tsnow classifies each state's value type (Boolean/Numeric/Enum/Color/Text) from ioBroker's owncommon.type/role/statesand sends it to Hannah Core alongside the existing snapshot data — lets Hannah build a proper trigger-editor dropdown instead of requiring a free-text state ID
0.31.3 (2026-07-09)
- Added:
NvsDialog("Rewrite NVS") now offers a Serial/Wireless toggle — Wireless pushes WiFi, MQTT broker/port, OTA channel and the OTA/asset tokens straight to an already-connected satellite via itsPOST /nvsendpoint, no cable needed. Wireless is only enabled for satellites that are currently online; anything outside that field set (WiFi user/pass for MQTT, OTA/asset URLs, TLS skip) still requires Serial - Fixed:
FlashDialog/NvsDialognow also write the satellite's wireless-update bearer token (satNvsTokenfrom the Satellite Defaults) into NVS during flash/rewrite — previously it was never set on a fresh flash and got silently wiped on every Serial rewrite, leaving the wireless write path permanently disabled - Added:
NvsDialog's "Display Name" field now actually renames an already-paired satellite (via the newsetSatelliteDisplayNamesendTo command) — previously it was silently discarded, since it was only ever sent through the pre-pairingprovisionSatellitecall, which has no effect on an already-paired device. Requires the new "Your Hannah User ID" setting (Satellite Defaults tab) to be configured; without it, renaming is skipped rather than failing the whole write
0.31.2 (2026-07-09)
- Fixed:
FlashDialog/NvsDialogno longer leave a permanent, unclaimed pending satellite registered with Hannah Core when a WebSerial flash fails or is never attempted (unsupported browser, missing driver, non-HTTPS page, cancelled port picker) — the satellite is now registered only once a live connection to the ESP is confirmed, right before the actual flash write - Changed:
NvsDialog("Rewrite NVS") no longer regenerates the satellite's pairing seed or re-registers it with Hannah Core on every rewrite — editing an already-known satellite's settings no longer forces an unwanted re-pairing
0.31.1 (2026-07-08)
- Fixed: a satellite could end up with two separate room object trees (e.g.
Leonie_Schlafzimmerandleonie_schlafzimmer) if its room string changed case or formatting between updates — room paths are now built from a case-insensitive canonical key, and an offline update reporting a differently-formatted room than the satellite was last online with now also cleans up the old path instead of only the online case
0.31.0 (2026-07-08)
- Fixed: a satellite's object tree is now cleaned up from its old room immediately when a room reassignment arrives, instead of leaving a stale path behind until the satellite happened to reconnect
0.30.3 (2026-07-05)
- Changed: replaced the manually-synced
hannah.protofiles and@grpc/proto-loaderwith the published@m1kad0/hannah-protonpm package (typed@grpc/grpc-jsclient, no local codegen). No functional change.
0.30.2 (2026-07-04)
- Added: the adapter now sends a protocol-version header with every request to Hannah Core, so version mismatches between the two are caught with a clear error instead of unexplained misbehavior
0.30.1 (2026-07-03)
- Changed:
hannah.protosplit by scope into several files on the Hannah side; the adapter's proto loader now resolvesimportstatements between them (includeDirs). No functional change. - Fixed:
npm run buildonly copiedhannah.protointobuild/proto/, not the other scope files added above — adapter crashed on startup (ENOENT: .../build/proto/shared.proto) once installed from a packaged build
0.30.0 (2026-07-02)
- Added: illuminance/lux sensors are now recognized as their own device category (
illuminance_sensor) — via thevalue.brightnessrole, or a read-only state under a "Helligkeit"/"Lux" function
0.29.2 (2026-06-30)
- Fixed: stale satellite/room object trees that Hannah Core no longer reports are now actually removed instead of just marked offline —
markUnknownOffline()renamedremoveUnknownSatellites(). Hannah's satellite tracking is stateful now (reports every known satellite regardless of connection status, pushessatellite_deletedon real deletion), so "not reported at all" reliably means genuinely gone (#83)
0.29.1 (2026-06-30)
- Added: Blockly "Hannah announce" block now has a "Person (optional)" input, generating the new
personfield
0.29.0 (2026-06-30)
- Added:
ownerstate undersatellites.rooms.<room>.<device>.*— shows the Person a satellite is assigned to in Hannah Core, if any (populated from the extendedGetSatellitesresponse, refreshed on (re)connect likelast_seen/room_mismatch) - Added:
sendTo('announce', ...)accepts a new optionalpersonfield (roomie ID, e.g."leonie") to target a specific Person directly, in addition to or independent ofroom/rooms— routes through Hannah Core'sAnnounceRPC instead of the room-onlysatellite_controlstream path used otherwise
0.28.0 (2026-06-29)
- Added: virtual
satellites.rooms.allroom ("Alle") — always present, not tied to any satellite. Exposesannouncement/announcementSsml/announcementRephrase,dndandmutestates that broadcast to every connected satellite (Hannah Core already resolvesroom == "all"as a broadcast target).
0.27.1 (2026-06-27)
- Changed:
GrpcClient.getSatellites()now returns every satellite Hannah Core knows about (not just currently-connected ones), with newroom_id/room_display_name/last_seen/connected/room_mismatchfields.onConnected's initial sync now usesconnectedinstead of assuming every returned satellite is online, and falls back to the DB-assigned room when a satellite isn't currently connected (its live room is empty then) — lets provisioned-but-never-connected satellites show up correctly instead of being skipped - Added:
last_seenandroom_mismatchstates undersatellites.rooms.<room>.<device>.*, populated from the extendedGetSatellitesresponse - Fixed:
updateSatelliteNvsnow rejects with a clear "not connected" error instead of pushing to an empty IP when the target satellite is known but currently offline
0.27.0 (2026-06-26)
- Added:
updateSatelliteNvssendTocommand — pushes a key-value map to a satellite's newPOST /nvsHTTP endpoint to remotely update WiFi/MQTT/OTA-channel/seed/wakeword-threshold settings without physical access. Resolves the satellite's IP viaGrpcClient.getSatellites(), authenticates with the newsatNvsTokenadmin config field (Satellite Defaults tab)
0.26.1 (2026-06-25)
- Added:
ResidentsWatcher.handleSetResidentMood()— writes an incomingAgentSetResidentMoodcommand toresidents.<instance>.<segment>.<id>.mood.state, same path pattern as the existing presence write; dispatched inmain.tsalongside the existingset_residentcase
0.26.0 (2026-06-21)
- Added:
ResidentsWatchernow also tracks pets (residents.<instance>.pet.*), not just roomies/guests — presence updates and the resident snapshot carry atypefield (ROOMIE/GUEST/PET) instead of the removedis_guestboolean - Fixed: the resident snapshot sent to Hannah Core always reported
presence_state: 0regardless of the actual state; it now reads the real value from<resident>.presence.state - Added: resident snapshot now includes
mood_level, read from<resident>.mood.stateif present
0.25.0 (2026-06-20)
- Added:
resolveType()now maps rolevalue.humidityto the newhumidity_sensordevice type (Refs https://dev.kernstock.net/gessinger/voice/hannah/-/work_items/47) - Changed: satellite deletion now happens via the new
satellite_deletedAgentCommandsent by Hannah Core (SatelliteWatcher.deleteSatellite()+SensorWatcher.deleteSensors()are unchanged, only the trigger moved); the AdminUI "Remove" button and thedeleteSatellitesendTohandler are removed — deletion is now done from Hannah's own Web UI satellite list, the only place that also clears RoomManager's DB entry (Refs https://dev.kernstock.net/gessinger/voice/hannah/-/work_items/42)
0.24.1 (2026-06-20)
- Fixed:
StateWatcher.onStateChange()dropped every state change withack:false, including states subscribed viaAgentWatchMore(trigger_engine) — manually/directly written flags (e.g.0_userdatabooleans with no backing device to confirm them) never received an explicitack:trueand were silently never forwarded to Hannah Core. WatchMore states are monitoring-only (never written to viahandleSetState), so there's no feedback-loop risk in forwarding them regardless ofack— the filter now only applies to enum-discovered device states
0.24.0 (2026-06-19)
- Fixed:
StateWatcher.resolveType()read a non-standardcommon.hannah.typefield for the device-type override, which is never reliably persisted by ioBroker — now reads the officially documentedcommon.custom["<adapter-namespace>"]structure ({enabled: true, type: "..."}), matching the convention from the ioBroker objects schema docs
0.23.0 (2026-06-19)
- Added:
FlashDialog— "Download image" button combines firmware partitions + generated NVS into a single flat binary and triggers a browser download, as an alternative to WebSerial flashing (works in any browser, e.g. Safari) (Refs #61) - Fixed:
FlashDialog.prepareFirmwareAndNvs()now checksresult.ok/result.errorfrom theprovisionSatellitesendTo call instead of always logging "Satellite registered." — provisioning failures (e.g. unknown room) are now surfaced instead of silently swallowed (Refs #66) - Added:
StateWatchersends the fullenum.rooms.*catalog to Hannah Core (send_rooms, independent of devices) on connect and on enum change, so Hannah'sRoomManagerknows about rooms before any device/satellite exists in them (Refs #66)
0.22.0 (2026-06-19)
- Fixed:
SatelliteWatcher.handleSatelliteUpdatenow skips satellites with empty room andonline=trueto prevent invalid ioBroker state IDs ending in.(Refs #37)
0.21.1 (2026-06-19)
- Fixed:
FlashDialogroom dropdown was empty — usedgetForeignObjects('enum.rooms.*')(not valid forenumobject type) instead ofgetEnums('rooms'), the method already used correctly inapp.tsx
0.21.0 (2026-06-18)
- Changed:
NvsDialog— removedroomfield; re-flashing NVS no longer requires room selection;provisionSatellitecall no longer passesroomId(Refs #35) - Changed:
FlashDialog— room free-text field replaced with dropdown populated fromenum.rooms.*;provisionSatellitenow called before flash withseed+roomId;seedwritten to NVS partition (Refs #35) - Changed:
provisionSatellitesendTo handler —roomIdis now optional; enables seed-only re-provisioning without changing the satellite's room assignment (Refs #35)
0.20.0 (2026-06-18)
- Changed:
StateWatchersends enum ID segment asroom(e.g.wohnzimmer) and allcommon.namelanguages asroom_namesmap — language-neutral object keys (Refs #58) - Changed: satellite state paths use room ID from
AgentSatelliteUpdate.room→satellites.rooms.wohnzimmerinstead ofsatellites.rooms.Wohnzimmer(Refs #58)
0.19.1 (2026-06-18)
- Fixed: Added missing 'ble' folder to resolve E3009.
0.19.0 (2026-06-18)
- Changed:
handleSatelliteUpdateaccepts optionaldisplayNameparameter; uses it (falling back todeviceId) forcommon.namein ioBroker (Refs #52) - Changed:
_ensureSatelliteStatescallsextendObjectaftersetObjectNotExistsAsyncso renames are applied to already-existing objects (Refs #52) - Updated: proto —
AgentSatelliteUpdate.display_name(field 8),Satellite.display_name(field 5) — Core now sends the provisioned human-readable name to the adapter (Refs #52) - Changed:
device_idis now always the eFuse MAC —serialfield removed from adapter API;handleSatelliteUpdate,getSatellitesreturn type, andmarkUnknownOfflineno longer reference serial (Refs #54) - Updated: proto —
serialfields removed fromSatellite,SatelliteRegistration,AgentSatelliteUpdate; field numbers 4/7 reserved (Refs #54) - Changed: NvsDialog — removed
device_idNVS write (eFuse MAC is now computed on device); renamed "Device ID" field to "Display Name"; Display Name is sent to Hannah Core viaprovisionSatelliteonly (Refs #54)
0.18.0 (2026-06-18)
- Added: Satellite Identity (Refs #52) — paired satellites now use their eFuse-MAC-based hardware serial as stable ioBroker object key (
satellites.rooms.<room>.<serial>.*) instead of the mutable device_id; unpaired/UDP satellites fall back to device_id as before - Added:
provisionSatellitesendTo command — generates a pairing seed in Hannah Core before flashing so the satellite can auto-pair on first connect - Added: NVS flash dialog now registers the satellite in Hannah Core (via
provisionSatellite) and writes the pairing seed to NVS so the satellite links its hardware serial to the pre-configured identity on first boot - Updated: proto —
Satellite.serial(field 4),SatelliteRegistration.serial/seed(fields 4+5),AgentSatelliteUpdate.serial(field 7),ProvisionSatelliteRPC +ProvisionSatelliteRequestmessage
0.17.0 (2026-06-16)
- Added: IAQ, IAQ accuracy, CO₂ equivalent and VOC equivalent states under
satellites.sensors.<device>— populated when satellite uses BME680 with BSEC2 (Refs #17)
0.16.0 (2026-06-16)
- Added:
askcommand forsendTo— pose a question to a resident via Hannah TTS; the resident's spoken answer is returned as{ answer: string }in thesendTocallback; payload:{ room?: string, text: string } - Updated: proto —
AgentAskResidentgainscorrelation_id; newAgentResidentAnsweredmessage andresident_answeredvariant inAgentCommandoneof
0.15.3 (2026-06-13)
- Added: "Disable TLS certificate validation" checkbox in flash and NVS-rewrite dialogs — stored as NVS key
tls_skip; default off; useful for satellites connecting to servers with self-signed certificates - Added: same option in the satellite defaults tab of the adapter settings
0.15.2 (2026-06-12)
- Fixed: firmware download failed with "Invalid character in header content [Authorization]" when the configured firmware source token contained a trailing newline or whitespace — the token is now trimmed before being used as a Bearer header
- Fixed: deleting a satellite left orphaned objects behind — the sensor tree (
satellites.sensors.<device>, a separate object branch) and the room container (satellites.rooms.<room>, including its shared room-level states) were never removed; deletion now runs in the backend via adeleteSatellitecommand that removes the satellite tree, the sensor tree, and the room container when it becomes empty (nodevicechildren left) - Fixed: the WebSerial port in the flash dialog was not released when the overlay was closed (only the monitor reader was cancelled, never
port.close()) — the serial connection stayed locked until the whole page was left; closing the dialog, pressing "Stop monitor", or unmounting now fully releases the reader, esptool transport and port - Changed: the delete button in the satellites tab is hidden for online satellites — an online satellite would immediately re-register itself via its own updates, so only offline ones can be removed
0.15.1 (2026-06-11)
- Fixed:
wakewordNVS key removed from flash and NVS-rewrite dialogs — wake-word on/off is compile-time only;ww_thresholdremains - Fixed: adapter checker E0058 — removed unsupported
allowScriptsfield frompackage.json - Fixed: adapter checker E1084/E1105 — removed deprecated
fa-iconandiconfromadminTab, convertedadminTab.nameto i18n object, fixedadminUI.tabvalue to"html" - Fixed: adapter checker E5043 — changed
'http'and'https'imports to'node:http'/'node:https'infirmware-manager.ts - Fixed: adapter checker W1073/W1074 — added
firmwareSourceTokentoprotectedNativeandencryptedNativeinio-package.json
0.15.0 (2026-06-11)
- Added: web flasher — flash new satellites directly from the admin UI via WebSerial with full device provisioning (WiFi, MQTT, OTA, asset server) written as NVS partition in one step
- Added: serial monitor mode in flash dialog — streams the full boot log immediately after flashing
- Fixed: NVS CRC was calculated incorrectly by
esp-nvs-utils; switched to@m1kad0/esp-nvs-utils— ESP-IDF 6.0 no longer erases the NVS partition on first boot
0.14.0 (2026-06-09)
- Added: satellite
addressstate (info.iprole) — populated fromAgentSatelliteUpdate.addresson registration; IP extracted fromip:portUDP address - Added: admin tab "Hannah Satellites" — card view per satellite showing name, room, online status, firmware version badge, and link to satellite HTTP config page (
http://<ip>/) - Added:
SatelliteWatcher.markUnknownOffline()— on connect, setsonline: falsefor satellite device objects not reported by Hannah Core, preventing stale online states after rename/reassignment - Added: delete button per satellite card in admin tab — removes full ioBroker object tree on confirmation
0.13.0 (2026-06-05)
- Fixed:
infochannel object was missing — adapter checker E3009; created beforeinfo.connectionstate inonReady - Fixed: satellite room objects were
channeltype — adapter checker E2003 (device after channel); changed tofolderso satellite devices remain valid under them - Fixed:
indicator.updaterole onupdate_availablestate is unknown — changed toindicator - Fixed: room and device names containing spaces (e.g. "Leonie Schlafzimmer") produced invalid state IDs —
sanitizeId()now replaces non-[a-zA-Z0-9_,-]characters with_in ID paths;common.nameretains the original name;satellite_controlgRPC messages use the original room name via reverse map
0.12.1 (2026-06-04)
- Fixed:
announcementSsmlandannouncementRephrasestates were silently ignored by Hannah Core — proto-loader useskeepCase: trueso field names must be snake_case on the wire; added explicitprotoKeymapping insatellites.ts
0.12.0 (2026-06-04)
- Added:
announcementRephrasestate per room — writes text to Hannah Core asAgentSatelliteControl.announcement_rephrase; Hannah LLM reformulates before TTS
0.11.3 (2026-06-02)
- Changed: update dependencies (
@grpc/grpc-jsto 1.14.4,@grpc/proto-loaderto 0.8.1,@iobroker/typesto 7.1.2) - Changed: update dev dependencies (
@tsconfig/node20→@tsconfig/node22) - Fixed: replace
process.exit(1)withthrow new Error()in verify-package-contents script
0.11.2 (2026-06-01)
- Changed: minimum Node.js version bumped to 22
- Changed: CI pipeline updated to Node 22 (lint/check) and Node 24 (deploy)
- Changed:
@alcalzone/release-scriptand plugins updated to 5.2.0 - Changed: use
this.setTimeout/this.clearTimeoutin adapter class - Changed: removed outdated i18n keys from all translation files
- Fixed: added link to
CHANGELOG_OLD.mdat end of changelog section
0.11.1 (2026-06-01)
- Fixed: deduplicate notification messages before joining to prevent doubled text when ioBroker registers the same message twice for an adapter instance
0.11.0 (2026-05-27)
- Changed: volume and mute states moved from room-level (
satellites.rooms.<room>.volume/mute) to per-satellite (satellites.rooms.<room>.<deviceId>.volume/mute) - Changed:
AgentSatelliteControlnow supports optionaldevice_idfor per-satellite volume/mute commands; room-level commands (dnd, announcement) unchanged - Changed:
AgentSatelliteUpdatenow carries optionalvolumeandmutefields — adapter updates per-satellite states when received
0.10.0 (2026-05-25)
- New:
climatedevice type — detected via funcId keywords (klima,aircon,climate); supportsmode,fanSpeed,current, andexpectedstates
0.9.0 (2026-05-24)
- New:
SensorWatcher— handlesAgentSensorUpdatecommands; createshannah.<instance>.satellites.sensors.<device>.{temperature,pressure,humidity,gas_resistance}states on first update - Fixed:
satellites.sensorsfolder object is created before the per-device channel to avoid state creation failure
0.8.0 (2026-05-24)
- New:
BleWatcher— handlesAgentBleUpdatecommands from Hannah Core; createshannah.<instance>.ble.<label>.room,.satellite, and.rssistates on first update and keeps them current on every location change
0.7.0 (2026-05-23)
- New: Per-satellite state
satellites.rooms.<room>.<device>.firmware_version— updated whenever the satellite reports its running firmware version at boot - New: Per-satellite state
satellites.rooms.<room>.<device>.update_available(indicator.update) — set totruewhen the satellite reports a pending OTA update, reset tofalseon the next boot version report - New: Per-satellite button
satellites.rooms.<room>.<device>.update_now— triggers an immediate firmware update (bypasses residents/away check) viaTriggerFirmwareUpdategRPC RPC - Changed: Build artifacts (
build/,admin/build/) removed from git;prepackhook builds automatically onnpm pack/npm publish; Auto-Build GitHub Action removed - Changed:
nogit: trueset inio-package.json— adapter is distributed via npm only
0.6.0 (2026-05-22)
- New: ioBroker DeviceManager support — satellites are shown as devices with mute toggle and volume slider controls
- New: Satellite objects are now created as
type: device(previouslychannel) for DeviceManager compatibility
0.5.0 (2026-05-06)
- New:
AgentDeviceproto carries adevice_typefield (field 5) — resolved fromcommon.hannah.typeoverride, ioBroker role (e.g.level.temperature→thermostat,sensor.window→window), or function enum IDs; supported types:light,socket,thermostat,temperature_sensor,window,door,blind
0.4.2 (2026-05-04)
- Fixed: automated TypeScript build via GitHub Actions
0.4.1 (2026-05-04)
- Fixed: Deployment Issues. Not all required files where inside the package
0.4.0 (2026-05-03)
- Fixed: States may only be set if the state is writable (
common.write === true). - New:
AgentDevicenow includes afloorfield — resolved fromcommon.flooron the device object, with a fallback that scans the state ID path for known floor abbreviations (EG, OG, UG, DG, KG, ZG). - New: Configurable floor mappings — define custom label→abbreviation pairs in the Device Discovery tab (e.g. "Erdgeschoss" → "EG"); mappings normalize both
common.floorvalues and ID path segments, and extend (not replace) the built-in abbreviation set.
0.3.2 (2026-05-03)
- Fixed: Device names in Telegram and Hannah were showing the full state ID instead of the readable name
0.3.1 (2026-05-02)
- Fixed: The adapter sends too much data to Hannah
0.3.0 (2026-05-02)
- New: Device snapshot on connect — the adapter now sends room, device name, function and current value for every subscribed state immediately after connecting, so Hannah Core no longer needs to query the ioBroker REST API for device discovery
- New: Resident snapshot on connect — all known residents are forwarded to Hannah Core once after connecting, replacing the previous API-based resident lookup
- New:
AgentDeviceproto message carries full metadata (room, device, functions, current value) per state;AgentDeviceSnapshotwraps the complete list - Improved: Enum lookups during snapshot are now fetched once and reused across all states instead of once per state, significantly reducing startup time for large installations
0.2.1 (2026-05-01)
- Fixed: Hannah could set any state. That could be a security Issue. Hannah can now only edit the states that the adapter actively manages.
0.2.0 (2026-04-30)
- New: Send direct messages to Hannah via
sendTo('hannah.<instance>', 'sendDirect', { text: '...' })— plays via TTS on all satellites and forwards to Telegram, no LLM involved - New: Native ioBroker Notification Manager integration — system notifications are automatically forwarded to Hannah and reformulated by the LLM before being spoken and sent to Telegram
- New: Announcements via
sendTo('hannah.<instance>', 'announce', { rooms: ['Wohnzimmer', 'Küche'], text: '...' })— plays TTS in specific rooms only, bypasses LLM and Telegram. Userooms: ['all']to address every satellite - New: Blockly block "Hannah say" for direct voice messages
- New: Blockly block "Hannah announce" with a list input for target rooms
- Fixed: Duplicate gRPC connections on reconnect — old stream is now properly closed before opening a new one
- Fixed:
prepublishOnlyinstead ofprepack— installing the adapter locally no longer triggers a full build
0.1.0 (2026-04-30)
- New: Native AgentTextAnswer via gRPC pushes responses directly to hannah..textAnswer
- New: Dedicated resident_set gRPC command for residents.set_presence() to eliminate the final MQTT dependency
- New: Satellite state management integrated into adapter via GetSatellites() and gRPC subscriptions (NotifySatelliteRegistered/Gone)
- New: Automatic satellite state initialization under hannah..satellites.- at startup
- Fixed: Removed redundant residentsPrefix from StateWatcher to prevent duplicate state_update transmissions
- Fixed: Consolidated resident tracking into ResidentsWatcher for a single, clean telemetry path
- Fixed: Replaced legacy JavaScript satellite/room logic with native adapter functionality
- Fixed: Full deprecation of the ioBroker-to-Hannah MQTT feedback channel in favor of gRPC streams
0.0.2 (2026-04-28)
- Fixed: ControlDevice feedback channel — device state updates correctly after Hannah sets a state
- Fixed: Wildcard pattern matching for subscribed states
- Fixed: Resident presence subscription restricted to configured instance
- Fixed: Only forward confirmed states (ack=true) to Hannah; commands (ack=false) are ignored
- New: Text command state moved into adapter namespace (
hannah.<instance>.textCommand) - New: Automatic reloading of enum subscriptions when rooms or functions change in ioBroker
0.0.1 (2026-04-27)
- Initial release
- Bidirectional gRPC stream (state updates, resident presence, text commands, SetState)
- Enum-based device discovery with room × function filtering
- Extra state prefix support for arbitrary state trees
- Snapshot-on-connect replaces MQTT retained messages
For older entries see CHANGELOG_OLD.md.
License
MIT License
Copyright (c) 2026 M1kad0 [email protected]
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
