- Fix the battery indicator overlapping the mode buttons on expanded climate rows – radiators and other battery-powered thermostats drew their battery badge on top of the Cool/Heat/Auto buttons when the row was on. The expanding rows (thermostat, AC, Home Assistant climate) repositioned every row-1 element except the badge; it now follows the device name (#163, thanks @norbertpotocki)
- Fix Home Assistant connections failing with "NSURLErrorDomain error 12" after long uptime – every connect and credential check created a URLSession that was never invalidated, so each one leaked its client and pooled connections until the process ran out of network flows and only a relaunch helped. Sessions are now created on connect and invalidated on disconnect, reconnects no longer strand old WebSocket tasks, and a pending reconnect is cancelled on disconnect (thanks @damonDevelops)
- Fix red colour scenes never detected as active across the hue seam – scene-active detection compared hue as a plain number, so a scene targeting hue 359° whose bulb reported 0° (both red) read 359° out of tolerance and showed as inactive. Hue is now compared by the shortest on-wheel distance, matching the circular averaging already used for group colour, so colour scenes near the 0°/360° boundary read as active (thanks @YuriNachos)
- Fix custom icons lost on cross-device sync when a room is named like a reserved prefix – a custom icon on an accessory in a room named "scene", "group" or "room" produced a service stable key that began with that prefix (e.g. "scene::Lamp::Light"), so on restore the icon was claimed by the scene/group/room namespace and silently dropped. Service stable names are now resolved before the prefix namespaces during cloud decode (thanks @YuriNachos)
- Half-degree thermostat setpoints – temperature setpoints now step and display in the increment the device actually advertises, typically 0.5 °C, instead of hardcoded whole degrees. A 21.5° setpoint set from Apple Home reads 21.5° rather than 22°, the ± steppers can reach it, and setpoint limits follow the device's advertised min/max. Metadata-driven per device: a 0.5° radiator (Eve Thermo and similar) steps by 0.5°, a whole-degree device is unchanged, and Fahrenheit keeps whole-degree stepping and display. Applies to thermostat targets, heater-cooler thresholds and Home Assistant climate targets (#60, #102, thanks @jeffscottmtl)
- Fix AC temperature skipping degrees in Fahrenheit – heater-cooler steppers moved the underlying Celsius value by 1° (= 1.8 °F), the same bug fixed for thermostats in 3.0.0, so one click jumped 72 to 74. All six AC steppers are now unit-aware and move the displayed degree by exactly one (thanks @jeffscottmtl and @YuriNachos)
- Fix colour-setting scenes never being detected as active – hue and saturation now use the same rounding tolerance as brightness/position, so a scene that set a colour is shown as active right after it fires instead of permanently "off" (#157, thanks @YuriNachos)
- Fix sensor history chart drawn vertically mirrored – the numeric sparkline line rendered upside down (a rising reading drew a falling line, contradicting the hover readout) because SparklineView used AppKit's default non-flipped coordinate system while the y math assumes a flipped view (y = 0 at the top). SparklineView now overrides
isFlippedso the line follows the data; the binary on/off timeline uses a symmetric mid-Y and is unchanged (#150, thanks @YuriNachos) - Fix the group colour swatch showing the wrong hue for lights clustered near red – the group's average hue was a plain arithmetic mean of degrees, so two lights at 350° and 10° (both near red) averaged to 180° (cyan). Hue is now averaged as an angle (mean of unit vectors, recovered with atan2), so colours blend correctly across the 0°/360° boundary while ordinary same-area clusters are unchanged (thanks @YuriNachos)
- Air quality sensors – HomeKit air quality services (SONOFF air quality monitors, Eve Room and similar) were silently dropped and never appeared in the menu; an accessory whose only sensor was air quality vanished entirely. They now show as sensor rows with the reported quality level (Excellent to Poor, localized) plus the CO2 ppm or VOC µg/m³ reading the service carries, and the temperature and humidity readings such devices embed in the air quality service are picked up too (#154, thanks @je-ru)
- CO2 and CO sensors show the measured concentration – rows used to show only the binary CO2/Clear word; the ppm level that HAP requires on every such sensor was never read. The row now reads e.g. "Clear · 563 ppm" and updates live (#155, thanks @je-ru)
- Pro badge on "Record sensor history" – the Advanced pane toggle was just greyed out for free users with no hint why; it now carries the same PRO badge as other Pro features until Pro is active (#149, thanks @bondskin)
- Respect the Home app's "show as" override – a switch or outlet reconfigured to display as a light or fan in Apple Home now shows up as that type everywhere in Itsyhome: menu row, icon, type grouping and auto groups (previously it always appeared as a switch)
- Auto groups – similar devices are folded into one-click groups ("All lights", "All switches", "All blinds", "All ACs", "All fans", "All locks"), both across the whole home at the menu's top level and inside each room. A group appears once 2+ matching devices exist, opens as a submenu with a master toggle plus its member devices, and works on HomeKit and Home Assistant. Each top-level group is draggable anywhere in Settings → Home like any other section, room groups reorder among the room's devices, every group can be hidden with the eye icon, and any auto group can be pinned to the menu bar with the pin icon – its dropdown carries the same master toggle and member rows. On by default; turn the whole feature off in Settings → Advanced
- Live multi-stream camera grid – every HomeKit camera in the panel streams live simultaneously (muted, marked with an orange dot) instead of showing 30-second snapshots. Streams are owned by a dedicated engine that survives panel open/close: closing the panel keeps sessions alive for a 10-second grace so reopening is instant, and rapid open/close no longer stacks draining camera sessions. Opening a camera claims its already-running stream – no renegotiation spinner – and going back returns it to the grid still live. Home Assistant tiles keep snapshots with tap-to-stream
- Camera grid layout – the panel supports 1, 2 or 3 columns (Settings → Cameras, default 2), and any camera can be marked as a full-width tile via the arrows button in the camera list, so important cameras span the whole row while the rest sit side by side. The panel is freely resizable by its corners: tiles scale to fill the dragged size, the chosen size is remembered across opens and relaunches, and changing the column count resets it to the default
- Live or snapshots – a "Live video in grid" toggle in Settings → Cameras switches the grid between live streams and the previous snapshot behaviour. Live tiles are HomeKit-only: in Home Assistant mode the grid keeps snapshot tiles with tap-to-stream (HA streams are negotiated per view over WebRTC/HLS and don't support an always-on grid), and the toggle is hidden
- Fix thermostat temperature skipping every other degree in Fahrenheit – the ± steppers moved the underlying Celsius value by 1° (= 1.8 °F), so 72 jumped to 70. Steps are now unit-aware: in Fahrenheit they move the displayed degree by exactly one. Applies to target temperature and both Auto-mode thresholds, on HomeKit and Home Assistant thermostats (#137, thanks @dsmecher and @LordZork)
- Fix Dock stuck hidden after quitting Itsyhome – Quit used to terminate the process synchronously from inside the status-bar menu's tracking session, leaving the system's menu-tracking state (and with it the Dock's auto-hide) wedged until restart or sleep. Quit now lets the menu close first and tears down the camera panel's window and event monitors before exiting (#141, thanks @LordZork)
- Fix iCloud sync never arriving on a second Mac – the only pull ran at startup before HomeKit had delivered any accessories, so it silently did nothing and was never retried; worse, the fresh Mac's empty lists could then upload and delete the first Mac's synced data before ever reading it. Sync now pulls once per home as soon as accessory data is ready and holds all uploads until that pull has happened, and the sync engine finally logs what it's doing (Console subsystem com.nickustinov.itsyhome, category CloudSync) (#111, thanks @tsmith8674 and @LordZork)
- Fix endless black spinner on sleepy battery doorbells (Aqara G4 and similar) – a stream start against a camera that is still waking can hang without HomeKit ever calling back. Stream negotiation now has a 10-second watchdog that tears the attempt down and retries once (the failed attempt is usually what woke the camera – the manual "close and reopen" that used to be the workaround), and if the retry also hangs the panel returns to the grid instead of spinning forever (#139, thanks @ray19826)
- Complete localization – all strings added since 2.6 (automations, HomeKit bridge, sensor states, sensor history, networks, webhooks, and the new camera grid settings) are now translated into all 11 languages, and the camera panel itself (Back/Close buttons, empty state) is localized for the first time
- Fix camera streams ducking system audio – opening an HLS or WebRTC camera stream no longer lowers the volume of music, podcasts or other playback; the stream players now use a non-ducking audio session that is activated and deactivated in balance with the stream lifecycle (#138, thanks @mvanhorn)
- Batteries submenu – every battery-powered device in one "Batteries" submenu, sorted by charge level with the lowest first so devices that need charging surface at the top. Each row shows the device icon, name and the same battery gauge + percentage as the inline badge (red when the device reports low battery), updating and re-sorting live while the menu is open. Devices are deduped per accessory and it works on both HomeKit and Home Assistant. On by default whenever battery devices exist; hide it with the eye icon in Settings → Home (#144)
- Fully reorderable menu – Settings → Home is now one list containing every top-level section of the menu: Favourites, Groups, Scenes, each room, Other and Batteries, each collapsible with a device count on its header. Drag any section anywhere; the menu follows exactly. Sections without content (no favourites yet, no global groups, no battery devices, ...) are skipped in both the list and the menu, and appear at their saved position once they have content. Existing room orders are preserved, and the webhook API and cloud sync keep seeing the same room ordering as before
- Top-level dividers – every separator in the menu (including the ones under Favourites and Groups that used to be fixed) is now a real, user-managed divider shown in Settings → Home, exactly like the ones inside rooms: drag them anywhere, right-click a section header to add a divider above it, right-click a divider to remove it
- Groups reorder anywhere in their room – a group row can be dragged among the room's accessories (previously groups were pinned to the top and a lone group couldn't be dragged at all), and every group and accessory row now shows a drag handle
- Expand groups in Settings → Home – groups have a chevron revealing their member devices, and dragging those reorders the group. The group's submenu in the menu and its pinned menu-bar dropdown now follow that order instead of regrouping by type, and pinned room dropdowns follow the room's custom order too
- Fix "Record sensor history" staying greyed out after buying Pro – the Advanced pane checked the Pro status only when it was first shown, so the toggle stayed disabled until the app was relaunched; it now unlocks the moment the purchase completes. The HomeKit bridge pane had the same stale gate (enable switch and upsell banner) and now rebuilds on Pro status changes like the other Pro panes
- Virtual HomeKit sensors with automations (Pro) – Itsyhome can now publish its own bridge to Apple Home over HAP, carrying read-only virtual sensors (contact, motion, occupancy, leak, smoke, CO, CO2). Manage them in Settings → HomeKit bridge: enable the bridge, pair it by scanning the QR code (or typing the setup code), add/edit/remove devices and flip their state to test. The sensors can be set by name through the existing webhook verbs, or by the new built-in automations in the same pane: "WHEN a HomeKit accessory holds a state FOR a duration THEN set a virtual sensor", with optional re-pulsing – so Apple Home can automate on conditions HomeKit can't compute itself, like "door open for 15 minutes". Pairings and the bridge identity persist across restarts, with the identity key stored in the Keychain (#129, thanks @mikeburgh)
- Sensor history (Pro, opt-in) – "Record sensor history" in Settings → Advanced keeps 30 days of readings per sensor, shown as a chart in each sensor's submenu: a line for temperature/humidity (thermostat and AC current temperature included), an on/off timeline for binary sensors, with hover readout and a 24h/7d/30d range toggle. Captured off the existing update path (no extra polling), stored locally per home, "Clear history" button included. Periods where nothing was recording (app closed, Mac asleep) show as gaps in the chart rather than a misleading flat line (#133, thanks @mikeburgh)
- Battery level via the webhook API –
/info/<room>/<device>now includesbattery(0–100) andbatteryLowfor battery-powered accessories, resolved the same way as the menu's battery badge on both HomeKit and Home Assistant (#132) - Bind the webhook server to a specific local IP – Settings → Webhooks has a new "Bind" field that restricts the local web server to a single interface address (e.g. a Tailscale mesh IP) instead of listening on all interfaces, so the endpoint is reachable over a private network without router port-forwarding. Empty keeps the default (all interfaces); an invalid address is rejected and falls back to all interfaces so a typo can never brick the server (#126)
- Fix battery indicator not showing for Home Assistant devices – HA battery sensors are usually marked "diagnostic" and were hidden by the entity category filter before the badge could read them; battery sensors are now resolved from the full entity list so the badge appears regardless of the filter (#113-adjacent)
- Reduce idle battery/CPU usage – characteristic updates from chatty bridges no longer walk the (hidden) menu while the dropdown is closed; pinned menu-bar items and webhook clients still update live, and the menu refreshes its values when opened (#113)
- Fix colour changes on Govee/Matter lights being ignored – hue is now written after saturation so the hue value is the one that sticks on Matter bridges, while keeping the small delay that prevents wrong colours on Philips Hue (#127)
- Close the cameras dropdown with Esc – pressing Esc dismisses the camera panel like a regular menu; pinned camera windows keep normal key handling (#131)
- Sensors in the menu – contact, motion, occupancy, leak, smoke, carbon monoxide and carbon dioxide sensors now appear as read-only rows showing their state (Open/Closed, Motion/Clear, Leak/Dry, Smoke/Clear, ...) with state-aware icons (#32)
- Individual temperature and humidity sensors – new "Summarise temperature and humidity" toggle in Settings → Advanced (on by default). When off, each temperature and humidity sensor is shown as its own row in the menu and in Settings → Accessories instead of a single aggregated per-room range
- Pin sensors to the menu bar – pinning any sensor now shows its reading next to the icon (e.g. 21.5°, 45 %, Smoke, Motion) and updates live
- Read-only sensors over webhooks – the binary sensor family is exposed through the local web server:
/listand/statusinclude them,/infoadds adetectedbool (reported as unknown when unreadable, never a false "clear"),/debuglists their characteristics, and value changes publish over the SSE/eventsstream - Home Assistant sensor support – every HA sensor now appears in the menu. Contact, motion, occupancy, leak (moisture), smoke and carbon monoxide binary sensors map to their dedicated rows; any other numeric sensor (CO2, power, pressure, illuminance, air quality, ...) shows its value and unit, and any other binary sensor shows On/Off, each with a device-class icon. Diagnostic sensors stay governed by the entity category filter
- Battery indicator – battery-powered accessories show a small battery icon and percentage next to their name in the menu (sensors, locks, doors, blinds, garage doors and thermostats). Works with both HomeKit (sibling battery service) and Home Assistant (the device's battery sensor)
- Add sensors to custom groups – sensors can now be added to user-created groups. In submenu groups they show as rows with their reading; the aggregate toggle of inline groups ignores read-only sensors
- Scene state + deactivate over webhooks.
/list/scenesand/info/scene/<name>now include an optionalstate: { on: Bool }for HomeKit scenes that have a granular action list (omitted for HA snapshot scenes and other cases where the server can't introspect — clients should fall back to fire-only). The "active" computation matches what the menubar toggle uses: every action's target characteristic must match the device's current value within a per-characteristic tolerance (5 for position/brightness/speed, ~0 for booleans) - New webhook endpoint
GET /off/scene/<name>deactivates a scene with Apple Home semantics — turns off only what the scene turned on, never opens blinds or unlocks doors. Pair with the existingGET /scene/<name>(activate) to expose a full toggle UI on clients that previously only fired scenes SceneStateHelperextracted fromSceneMenuItemso the menubar UI and the webhook layer share one source of truth for "is this scene active" and "deactivate this scene"
- Fix camera snapshots not auto-refreshing on subsequent panel opens – the snapshot and timestamp timers were torn down on close but only restarted via
viewDidAppear, which doesn't fire on later opens; now restarted inpanelDidShowso the timestamp ticks and snapshots refresh every 30s (#117) - Fix camera panel dismissing when clicking inside the feed – the local click monitor compared window identity, so clicks landing on the panel's hosted/child windows were treated as outside; now uses screen-coordinate containment, matching the global monitor
- Expose
speedMin/speedMaxin/infoJSON so webhook clients can render the correct fan speed scale and presets (HomeKit fans can override the 0–100 default — e.g. 0–6 on a 6-speed ceiling fan) - Fix
/inforeporting staleonstate for fans / AC / valves — prefer theActivecharacteristic over theOncharacteristic, matching what the menubar dropdown reads (activeId ?? powerStateId) - Webhook list endpoints now respect the user's reordering from Settings → Accessories:
/list/rooms,/list/scenes,/list/groups,/list/groups/<room>,/list/devices, and/info/<room>all emit items in the same order as the menubar dropdown. Hidden rooms, scenes, and services are also filtered out of/list/*responses (a specific/info/<name>lookup still works for hidden items) - Webhook icon endpoint:
GET /icon/<phosphor-name>?fill=1&size=64returns a PNG of the requested Phosphor icon rendered white on transparent. Lets clients render the same icons the menubar uses (including user-customised icons viaIconResolver) without bundling the SVG set themselves /list/roomsnow includes the Phosphoriconname for each room (paired with the new/icon/<name>endpoint), so clients can render the per-room icon the menubar already uses/list/favourites(alias:/list/favorites) returns the user's curated Favourites (services / device groups / scenes) with akinddiscriminator and the same Phosphor icon names, so clients can render a unified "Favourites" affordance. Order matches the user's drag-ordered Favourites list in Settings- Fix
/onand/offreturning "Action not supported" for thermostats and HA-bridged climate devices (e.g. Ecobee) –executePowerStateonly checkedpowerStateId/activeId, so devices that expose onlyTargetHeatingCoolingStatefell through. Now mirrors the toggle path: on → auto (3), off → off (0); the Temperature submenu still lets the user pick heat/cool explicitly - Auto-mode thermostat support (e.g. Ecobee in auto):
/infoServiceState now emitsheatingThreshold(lo) andcoolingThreshold(hi) as separate fields when the service exposes them. The old fallback that synthesised a singletargetTemperaturefrom the cool threshold has been removed (it was masking the two-setpoint reality and the UI couldn't render auto-mode bands) - New webhook endpoints for thermostats:
/mode/<off|heat|cool|auto>/<target>changes the thermostat mode;/heat/<temp>/<target>and/cool/<temp>/<target>set the heating/cooling threshold independently for auto-mode devices - Fix
/temp/<X>/<thermostat>clobbering auto-mode bands – it used to write the same value to both heat and cool thresholds, so Ecobee silently rejected one side (it enforces a 1 °C minimum spread between lo and hi) and the UI looked unchanged while HA showed lo moved./tempnow writes only the cooling threshold (the "upper comfort bound") when no single targetTemperature characteristic exists; use the new/heatand/coolendpoints for explicit threshold control - Fix Home Assistant light brightness off-by-one –
Int(b * 2.55)andInt(b / 2.55)both truncated toward zero, so writing 50 % to HA stored 127/255 and read back as 49 %. Both conversions now round, so percentages round-trip exactly (or differ by at most 0 % across the boundary) - Webhook
/mode/<m>/<target>now respects the device's actual mode support and accepts HA-specific modes (heat_cool,dry,fan_only, …)./infoServiceState gainsavailableModes– a unified list of mode strings the device will accept (HA climate emits it directly; HK Thermostat / HeaterCooler get translated from their integer valid-state arrays plus the Active characteristic for "off"). The action engine validates writes against availability and returns failure instead of silently dropping unsupported modes. Power flow on HeaterCooler ACs flips Active alongside the mode write, mirroring the menubar's behaviour - Fix
/inforeporting the wrong climate mode for HA-bridged devices using HA-specific modes. The bridge storesheat_coolas3,dryas4,fan_onlyas5,autoas6(extended beyond the HK 0-3 range), but the read-back usedTargetThermostatStatewhich only knows 0-3 with3 = auto. Soheat_coolwas reported asauto, anddry/fan_only/ extended-autoall collapsed tooffeven though the device was actually running them. Read-back now uses the HA extended vocabulary when the service exposesavailableHVACModes
- Fix RGB colour picker setting wrong colour on Hue lights
- Fix camera talk button not working (#114)
- Reduce idle battery usage from chatty HomeKit bridges (#113)
- Fix menu going blank after wake with SSID-based home switching (#112)
- Fix Home Assistant covers grouped in the wrong room when a single device spans multiple areas (#109)
- Return all matches from
/info/<room>/<device>when multiple devices share the same name (#108) - Reorder accessories inside rooms by drag in Settings → Accessories; right-click any accessory to add or remove dividers, or reset the room's order (#115)
- Add Home Assistant
input_booleansupport – treated like a switch with toggle on/off (#64) - Add "Itsyhome for iOS" settings panel promoting the iPhone/iPad companion included with Pro
- Open camera on motion (Pro) – cameras with built-in motion sensors can now auto-open the camera stream when motion is detected; per-camera toggle in Settings → Cameras; works with both HomeKit and Home Assistant; includes 60-second cooldown to prevent repeated triggers (#34)
- Separate auto-close settings card – the auto-close camera popup settings are now in their own card, enabled whenever any auto-open trigger (doorbell or motion) is active
- Fix group keyboard shortcut toggling lights individually – using a keyboard shortcut to toggle a device group toggled each light's state independently (on→off, off→on) instead of treating the group as a whole; now matches menu behavior: if any device is on, all turn off; if all are off, all turn on (#101)
- Fix camera motion auto-open bypassing preference check – HomeKit motion events unconditionally triggered camera streaming even for cameras without motion-open enabled; now all motion events go through the macOS-side preference check before opening the panel or starting a stream (#34)
- Fix Home Assistant entities ignoring per-entity area overrides – entities assigned to a different area than their parent device were always grouped by the device's area; now entity-level area overrides take priority, matching Home Assistant's own behavior (#92)
- Fix devices stuck grayed out – HomeKit notification subscriptions are now throttled per-accessory to avoid overwhelming bridges (e.g. Hue); if a value update arrives for a device marked unreachable, it is automatically restored to reachable; already-subscribed characteristics are skipped on refresh
- Suppress all runtime Home Assistant error popups – HA connection and data errors are now logged silently instead of showing modal alerts; fixes disruptive popups on wake from sleep (#85)
- Add double-click zoom for camera streams – double-click on a camera stream to zoom in at 2× toward the click point, double-click again to zoom out; trackpad pinch-to-zoom also supported (1×–3×), pan while zoomed; overlays and controls stay fixed above the video; zoom resets when switching cameras or closing the stream (#76)
- Add SSID-based auto-switching (Pro) – automatically switch HomeKit home or Home Assistant server URL (with optional per-network access token) based on the current WiFi network; opt-in via Settings → Networks, requires Location Services permission for SSID reading
- Fix thermostat not remembering last active mode – devices like Tado Smart AC report
targetHeatingCoolingState: 0when off, so after a menu rebuild the last active mode defaulted to Heat; now persists the last non-off mode to UserDefaults per device so the correct mode is restored on toggle
- Fix Home Assistant entities grouped in wrong rooms – room assignment for multi-entity devices (e.g. ESPSomfy RTS) was based on whichever entity happened to be iterated first from a dictionary, which changed randomly on each sync; now uses the device's own area directly, falling back to entity-level area only for standalone entities without a device
- Fix invisible window interfering with tiling window managers – the hidden 1×1 Catalyst window was ordered into the window list at launch, causing AeroSpace and similar tiling WMs to tile an invisible window; now blocked from ordering entirely and only briefly allowed when StoreKit needs a presentation context for purchases or restores
- Add
/refreshwebhook endpoint – triggers the same full data reload as the Refresh button in the menu bar; useful when webhook queries return stale HomeKit values for devices like Ecobee thermostats that don't always push characteristic updates reliably - Fix crash on wake from sleep in network monitor – moved all mutable property access into the main queue dispatch to eliminate a data race between the
NWPathMonitorcallback andhandleSystemWake - Suppress transient error alerts after wake from sleep – timeout, connection, and disconnection errors during Home Assistant reconnection are no longer shown as alerts
- Add security system state to webhook info endpoint – the
/info/webhook now returnssecurityStatefor security system devices - Fix "Message too long" error on large HA installations – increased the WebSocket maximum message size from 1 MB to 16 MB
- Security system arm/disarm via webhooks and URL schemes – security systems can now be armed to a specific mode (stay, away, night) or disarmed through webhooks, URL schemes, and commands; previously only toggle was supported
- Fix WebRTC streaming for Nest cameras – the data channel label from
get_client_configwas looked up inside theconfigurationsub-object instead of at the top level; without the data channel the SDP offer lacked the requiredm=applicationline and Nest rejected it - Fix incorrect accessory name normalization – room name stripping now requires a space after the room name, so "Garagenlicht" is no longer incorrectly shortened to "nlicht" in the "Garage" room
- Fix lock groups not toggling – added lock state reading on init and lock target writing on toggle, so lock groups now correctly lock/unlock all members
- Snapshot polling fallback for cameras – cameras that don't support WebRTC or HLS now fall back to polling
/api/camera_proxyfor JPEG snapshots at 1-second intervals - Simple light controls – new toggle in Settings → Advanced to show only the on/off switch for lights
- Advanced settings tab – moved temperature units and simple light controls into a dedicated Advanced tab
- Entity category filter setting – new dropdown in Settings → Home Assistant to choose which entity categories to hide
- Temperature unit setting – new dropdown in General settings to override the system locale for temperature display
- Auto-close doorbell camera popup – new setting to automatically close the camera popup after a doorbell ring, with configurable delay
- Fix HA connection stuck on "Connecting" forever –
sendAndWait()now has a 30-second timeout;handleDisconnection()now cancels all pending requests when the WebSocket drops - Detect local network permission denied – shows a specific error directing the user to System Settings instead of silently failing
- Auto-reconnect when network becomes available – automatically reconnects to Home Assistant when the network path changes to satisfied
- Fix http connections blocked on App Store builds – replaced
NSAllowsLocalNetworkingwithNSAllowsArbitraryLoadsin ATS settings - Fix WebRTC streaming for Nest cameras – the app now fetches
camera/webrtc/get_client_configto detect cameras that need a data channel and reorders SDP m-lines - Fix cameras not showing without STREAM feature flag – the filter now only excludes cameras with state "unavailable"
- Camera debug endpoint – new
/debug/cameraswebhook endpoint probes each camera's snapshot, HLS, and WebRTC support - Fix swing button shown on A/C units without "off" swing mode – hidden for climate entities whose available swing modes don't include "off"
- Localization – translations for 12 languages
- Fix crash on launch for some Home Assistant setups – replaced duplicate-unsafe dictionary construction
- Home Assistant support – connect to a Home Assistant instance as an alternative to HomeKit, with support for climate, lights, fans, covers, locks, humidifiers, valves, garage doors, security systems, cameras (snapshots, WebRTC, and HLS streaming), and scenes
- Dual RGB + color temperature support – lights exposing both hue/saturation and color temperature (e.g. Govee Neon Rope 2 via Matter) now show both picker buttons and sliders instead of only one
- Continuous color temperature slider – the color temperature picker is now a horizontal warm-to-cool gradient bar instead of 5 discrete circle presets
- Slider reflects light color – the brightness slider tint updates to match the current RGB or color temperature of the light
- Remember camera window position and size – the camera panel remembers its position and size per camera, so reopening the same camera restores where you left it
- SSE event stream – new
/eventsendpoint on the webhook server streams real-time device state changes via Server-Sent Events, usable withcurl -N, browserEventSource, or any SSE client - Real-time accessory updates – accessories now update instantly when toggled from the Home app or other controllers, instead of waiting for the menu to be opened; also re-reads characteristic values when a device becomes reachable again after being offline
- Hide mode selector for single-mode climate devices – heater-cooler and thermostat devices that only support one mode (e.g. heat-only radiators like Eve Thermo) no longer show the Cool/Heat/Auto mode selector; devices with two valid modes show only those two buttons
- Fan speed control via webhooks and URL schemes – fan rotation speed can now be set through webhooks (
/speed/50/Room/Fan), URL schemes (itsyhome://speed/50/Room/Fan), and commands (set speed 50 Room/Fan), with automatic clamping to device min/max limits (contributed by @loganprit) - Group display options – groups can now be shown as expandable submenus with individual device controls, not just a single toggle row; two new settings per group – "Group switch" and "Submenu" – control whether the toggle row and/or submenu are shown
- Hide "Other" section – the "Other" section (devices with no room) now has an eyeball toggle in Settings → Home to hide it from the menu, matching rooms and scenes
- Default to https for remote HA URLs – bare hostnames for remote services (Nabu Casa, DuckDNS, custom domains) now default to
https://instead ofhttp://, so the WebSocket connection useswss://as required; local addresses (.local, private IPs,localhost) still default tohttp:// - Add ATS local networking exception – added
NSAllowsLocalNetworkingto App Transport Security so localhttp://andws://connections aren't blocked by macOS - Fix crash when connecting to Nabu Casa cloud URLs – the app no longer crashes when the Home Assistant server URL triggers an invalid WebSocket connection; URL scheme is now validated before connecting, and
wss://URLs are accepted directly - Fix crash from concurrent state updates – a data race in the entity state mapper that could cause crashes during rapid state changes is now fixed with proper thread synchronization
- Fix crash when iCloud sync updates camera view – iCloud sync notifications could arrive on a background thread, causing a crash when the camera collection view reloaded off the main queue; notifications are now dispatched to the main thread
- Fix HA lock state always showing unlocked – Home Assistant sends lock state as a string ("locked", "unlocked"), but the webhook server was converting it with
intValue()which returned 0 for strings, causing all HA locks to appear unlocked - Fix HA climate toggle not working – climate entities had
activeIdset which caused toggle to write to an unhandled "active" characteristic; removedactiveIdfor climate so toggle correctly uses HVAC mode (off/auto) - Fix HA thermostat showing wrong temperature – thermostats on Home Assistant instances configured for Fahrenheit showed doubled-converted values (e.g. 156° instead of 70°); the app now fetches the HA unit system at connect time and normalizes all temperatures to Celsius internally
- Fix HA not reconnecting after Mac sleep – the app now listens for system wake events and automatically reconnects to Home Assistant instead of staying stuck on "Loading Home Assistant..."
- Fix roomless accessories not toggling via webhooks – devices without a room (shown in "Other") could be read via
/info/but not controlled via/toggle/because DeviceResolver had no bare device name resolution; added a new resolution step for unqualified device names - Fix CLI/webhook toggle failing until Refresh clicked – after an HA reconnect, the action engine bridge reference is now updated immediately so CLI and webhook commands work without needing to click Refresh first
- Fix pinned room not updating after hiding accessories – toggling accessory visibility via the eye icon now immediately updates pinned room menus without needing to unpin and re-pin
- Fix doorbell notifications ignoring disabled setting – disabling "Show doorbell camera on ring" now correctly prevents both the camera stream and the doorbell sound from triggering
- Fix camera snapshot timer draining battery – the 30-second snapshot polling timer now stops when the camera panel is closed, preventing continuous wake-ups on battery-powered cameras
- Fix group brightness turning on off lights – dragging the brightness slider in a light group no longer turns on lights that were off
- Fix group row disappearing on drag in settings – dragging a group row in the Home settings tab when it was the only group in its section caused it to vanish; drag initiation is now blocked when there is only one group
- Fix phantom window in Mission Control – the app no longer appears as an empty window in Mission Control when "Group windows by application" is enabled
- Fix camera-only rooms missing from settings — rooms containing only cameras or unsupported sensors now appear in settings so they can be hidden
- Doorbell notifications — when a HomeKit doorbell rings, the camera panel automatically opens in the top-right corner with a live stream of the doorbell camera, pinned to the desktop
- Doorbell sound — plays a chime sound when a doorbell rings (configurable in Settings → Cameras)
- Doorbell settings — new toggles in Settings → Cameras to control automatic camera display and sound on doorbell rings
- Per-camera aspect ratios — cameras with non-16:9 native ratios (4:3, 1:1, vertical, etc.) are detected automatically and rendered without black bars in both grid and stream views
- Pin camera to desktop — pin button in stream mode keeps the camera window visible when clicking away, with floating window level and toggle support
- Zoom stream button — magnifying glass button in stream mode toggles between 1x and 2x window size
- Strip room name from accessories in rooms — accessories displayed in room submenus have the room name prefix removed (e.g. "Living Room AC" shows as "AC" in the Living Room submenu)
- Fix pinned rooms ignoring hidden accessories — accessories marked as hidden now stay hidden in pinned room menus, matching the main menu bar behaviour
- Fix scene deactivation reversing all devices — turning off a scene now only turns off devices the scene turned on, matching Apple Home behaviour; locks, garage doors, and already-off lights are no longer reversed
- Fix pinned scenes not updating state — pinned scenes now receive real-time characteristic updates, so activating one scene correctly deactivates others without needing to reopen the menu
- Fix crash on launch with Home permission — removed force-unwrapped UUID conversions in menu building that caused a crash when processing HomeKit data, preventing the menu bar icon from ever appearing
- Fix sensor-only rooms missing from settings — rooms containing only temperature/humidity sensors now appear in the settings room list so they can be hidden
- Fix GitHub link in about section — pointed to incorrect repository URL
- Fix cameras not updating on home switch — camera panel now reloads when switching between homes, stopping any active stream and showing the new home's cameras
- Fix crash with duplicate room names — homes with identically named rooms no longer crash on launch
Initial release.