Skip to content

Releases: sfox38/TikTokTTS

TikTokTTS v1.2.5

Choose a tag to compare

@sfox38 sfox38 released this 05 Jul 06:19
21b3fdb

v1.2.5

  • Fix: Selecting the (loading...) placeholder in the device dropdown (shown when no media players are available yet) no longer crashes the select.select_option service call with an IndexError
  • Fix: Calling tiktoktts.set_random_voices after the last config entry was unloaded (e.g. the entry is disabled) no longer crashes with a KeyError; the pool is still validated and persisted
  • Refactor: The shared select/text/button entities are now forwarded by a single owning config entry instead of every entry, deleting the per-platform singleton guards and per-entry bookkeeping flags. Re-homing the shared entities to a surviving entry (when the owner is unloaded while another entry remains) now runs as a tracked Home Assistant task that is skipped during shutdown and no-ops when the owner was merely reloaded - replacing a raw call_soon hook that could race HA shutdown
  • Refactor: The language and voice dropdowns no longer hold direct references to each other. They coordinate through dispatcher signals plus one hass.data key, which removes the startup readiness event, its 10-second timeout, and the entity object previously stashed in hass.data for the service handler. Behaviour (restore on restart, default-voice preservation, random-voice handling) is unchanged and covered by tests
  • Perf: Direct API mode now remembers the endpoint that last served a request and tries it first, so when the configured endpoint is down, a multi-chunk message no longer re-probes it (with full retries) for every chunk
  • Perf: Direct API mode now has an overall per-message deadline (120 s) so a long message during an outage cannot stall a tts.speak call for many minutes while every chunk walks the whole endpoint fallback list
  • Perf: The device dropdown's media-player discovery now filters state events inside Home Assistant's event dispatch (event_filter), so routine attribute updates from active players never wake the integration at all
  • Perf: Static assets (card JS, icon) are now served with cache headers; the card URL already carries a ?v=<version> cache-buster so upgrades still load the new card immediately
  • Security: The TikTok session_id field in the setup and options forms is now a masked password input instead of plain text
  • Fix: Connection-test responses in the config flow are now properly released via context managers, and unexpected connection-test failures are logged with a traceback instead of being silently reported as "unknown error"
  • Meta: manifest.json now declares integration_type: service and iot_class: cloud_push (matching core TTS integrations)
  • Tests: 133 tests (up from 118); new coverage for the two crash fixes above, endpoint memoization, the per-message deadline, device selection and restore-wait behaviour, Speak-button guard paths, the options-save reload cycle, and config-flow unknown-error branches. The frontend tests now read the version from manifest.json instead of hardcoding it, so version bumps no longer break the suite
  • CI: Added ruff check and ruff format --check to the test workflow; the codebase is now Ruff-formatted

v1.2.4

  • Fix: Dashboard card no longer crashes with the name "tiktoktts-card" has already been used with this registry after upgrading. Older versions registered the card as a Lovelace dashboard resource; the current version registers it via the frontend module API, so on upgrade both could load the card and define the element twice. The card now guards against double-registration. If you upgraded, you can also remove the leftover /tiktoktts/tiktoktts-card.js entry under Settings -> Dashboards -> Resources.

v1.2.2

Choose a tag to compare

@sfox38 sfox38 released this 13 Jun 00:43
7d932c7

Changelog

v1.2.2

  • Fix: Lovelace card resource is now removed only on true integration deletion, not on every reload or options save (was wiping the card resource on every settings change)
  • Fix: Language-aware voice fallback - if the configured default voice is not available for the requested language, the integration now correctly falls back to the first voice of that language (matches the documented behaviour)
  • Fix: Direct API retry tuning - the configured endpoint gets 3 attempts × 20 s; each automatic fallback endpoint gets 1 attempt × 10 s (was using the same retry count for all endpoints)
  • Fix: All failure paths now raise HomeAssistantError so errors surface in the HA UI and automation traces instead of silently returning empty audio
  • Fix: aiohttp sessions are now properly closed via async with context managers (previously leaked connections on errors)
  • Fix: Options flow now saves sanitized values (trailing slashes stripped from endpoint, whitespace stripped from session_id) instead of raw user input
  • Fix: async_delete_issue is now called after a successful direct-API options save, clearing the expired-session repair issue
  • Fix: Voice dropdown no longer resets on every random-voice pool save - only resets when the language actually changes
  • Fix: Restored voice is now correctly re-applied after restart even when the restored language differs from the startup default
  • Fix: button.tiktoktts_speak now guards against speaking the literal strings "unavailable" or "unknown"
  • Fix: ConfigEntryState import moved to module level in button.py
  • Fix: Redundant native_value property removed from MessageTextEntity (base class handles _attr_native_value)
  • Fix: JS card - Speak button now cancels any pending debounce and flushes the current message to HA before pressing the button, preventing a race where the last typed characters could be missed
  • Fix: services.yaml - languages field now uses a proper multi-select selector with all 16 language codes instead of a bare object selector
  • Fix: Dead "unknown" error key removed from strings.json and translations/en.json
  • Fix: Lovelace resource URL match tightened to exact path equality (was startsWith, could match unrelated resources)
  • Fix: manifest.json version now read lazily via executor job in frontend/__init__.py to avoid blocking I/O on the event loop at import time
  • Docs: README corrected - cache limitation for voice: random in automations, chunking behaviour, proxy privacy note, proxy-wins-over-direct note, GitHub capitalisation, image tag attributes

v1.2.1

Choose a tag to compare

@sfox38 sfox38 released this 01 May 05:57
2981c50

General improvements and bug fixes, plus documentation updates

v1.2.0

Choose a tag to compare

@sfox38 sfox38 released this 29 Mar 09:09
47e3d94

v1.2

New Feature: Random Voice

Configure a pool of language groups and the integration picks a different voice on every tts.speak call.

Setup: Press the 🎲 button next to Speak in the dashboard card, tick the language groups you want, press "Save and close". Then select 🎲 Random Voice from the language dropdown.

Automations: Pass voice: random in options:

options:
  voice: random

A fresh voice is picked on every call from both the dashboard card and automation callers. The pool persists across restarts and is independent of config entries.


Bug Fixes

Switching connection modes (proxy/direct) now works correctly. Disabling or deleting one connection mode while the other is active no longer destroys the shared dashboard entities (language, voice, device, message, speak button). Those entities now survive and transfer cleanly to the remaining connection entry.

Speak button no longer targets a stale TTS entity. After removing one connection mode, the button was staying locked to the old entity. It now checks loaded config entry states rather than potentially stale hass.states.

Message length. HA's text entity enforces a 255 character limit with a colour-coded live counter.

Language dropdown icon was rendering incorrectly. Replaced with a clean MDI translate glyph.

Random Voice state restore on restart was partially broken - the language dropdown restored correctly but the voice dropdown showed a real voice name instead of "Random Voice". Both now restore correctly.


Dashboard Card Changes

  • 🎲 dice button added alongside Speak button to open the Random Voice settings panel.
  • Speak button no longer full width.
  • Status feedback line removed as it was unnecessary.
  • Message textarea capped at 255 characters with a live counter.

Internal

  • Random voice pool stored via HA's Store class (.storage/tiktoktts_random_voices.json) - the correct HA-idiomatic approach for user preference data independent of config entries.
  • _RandomVoiceAwareCache dict subclass replaces HA's TTS SpeechManager.mem_cache to force cache misses for voice=random calls, ensuring a fresh voice is picked every time from any call source.
  • services.yaml added to suppress HA startup log warning about undescribed services.
  • Shared platforms (select, text, button) now tracked per config entry to prevent the "already been setup" error when switching between connection modes.

v1.1

New Features

  • New Voices: Now has over 100 unique voices, in multiple languages
  • Additional endpoints: For Direct API usage
  • Custom Dashboard Card: Use this card to easily preview voices or to send impromptu messages around your home.

v1.0

This is a modernized fork of the original philipp-luettecke/tiktoktts integration, updated for current Home Assistant versions with significant new features and bug fixes.

Important

If you are upgrading from the original integration, please read the Upgrading from the Original Integration section in the README before installing. A clean removal of the old integration is required.


Bug Fixes

  • Fixed PLATFORMS declaration: was a single value instead of a list, causing the integration to fail silently on modern HA versions
  • Fixed missing commas in SUPPORTED_VOICES: several singing/expressive voice entries were being silently concatenated into invalid strings by Python
  • Fixed default language and voice: changed from German (de / de_001) to English US (en_us / en_us_001)
  • Fixed broken GitHub URL in original en.json (pointed to wrong repository)

New Features

  • UI config flow: integration is now configured via Settings -> Devices & Services, no configuration.yaml editing required
  • Live connection test: endpoint and session ID are validated before saving, so failures are caught at setup time
  • Options flow: change endpoint, voice, or session ID at any time via the gear icon, changes take effect immediately without a restart
  • Direct TikTok API mode: optional alternative to the proxy that calls TikTok's internal API directly using a browser session cookie, with automatic fallback across 4 known regional endpoints
  • Automatic text chunking: direct mode splits long messages at sentence and word boundaries to respect TikTok's 200-character per-request limit
  • Retry logic: both proxy and direct modes retry failed requests up to 2 times with backoff before giving up
  • Stable entity ID: always tts.tiktoktts_proxy or tts.tiktoktts_direct, no longer a random UUID

Technical / Internal Changes

  • Migrated from legacy Provider base class to modern TextToSpeechEntity
  • Replaced deprecated async_timeout library with Python's built-in asyncio.timeout
  • All hardcoded strings (API paths, field names, status codes, retry config) moved to const.py
  • Config stored entirely in entry.data - single source of truth for both setup and options flows
  • Full developer documentation added to all files

Credits

Role Person / Project
Original integration philipp-luettecke/tiktoktts
Community TTS proxy Weilbyte/tiktok-tts
Voice list reference oscie57/tiktok-voice

Version 1.1

Choose a tag to compare

@sfox38 sfox38 released this 18 Mar 06:51
0e2459b

TikTok TTS: v1.1

✨ New Features

  • New Voices: Now has over 100 unique voices, in multiple languages
  • Additional endpoints: For Direct API usage
  • Custom Dashboard Card: Use this card to easily preview voices or to send impromptu messages around your home.


v1.0.0

This is a modernized fork of the original philipp-luettecke/tiktoktts integration, updated for current Home Assistant versions with significant new features and bug fixes.

Important

If you are upgrading from the original integration, please read the Upgrading from the Original Integration section in the README before installing. A clean removal of the old integration is required.


🐛 Bug Fixes

  • Fixed PLATFORMS declaration: was a single value instead of a list, causing the integration to fail silently on modern HA versions
  • Fixed missing commas in SUPPORTED_VOICES: several singing/expressive voice entries were being silently concatenated into invalid strings by Python
  • Fixed default language and voice: changed from German (de / de_001) to English US (en_us / en_us_001)
  • Fixed broken GitHub URL in original en.json (pointed to wrong repository)

✨ New Features

  • UI config flow: integration is now configured via Settings -> Devices & Services, no configuration.yaml editing required
  • Live connection test: endpoint and session ID are validated before saving, so failures are caught at setup time
  • Options flow: change endpoint, voice, or session ID at any time via the gear icon, changes take effect immediately without a restart
  • Direct TikTok API mode: optional alternative to the proxy that calls TikTok's internal API directly using a browser session cookie, with automatic fallback across 4 known regional endpoints
  • Automatic text chunking: direct mode splits long messages at sentence and word boundaries to respect TikTok's 200-character per-request limit
  • Retry logic: both proxy and direct modes retry failed requests up to 2 times with backoff before giving up
  • Stable entity ID: always tts.tiktoktts_proxy or tts.tiktoktts_direct, no longer a random UUID

🔧 Technical / Internal Changes

  • Migrated from legacy Provider base class to modern TextToSpeechEntity
  • Replaced deprecated async_timeout library with Python's built-in asyncio.timeout
  • All hardcoded strings (API paths, field names, status codes, retry config) moved to const.py
  • Config stored entirely in entry.data - single source of truth for both setup and options flows
  • Full developer documentation added to all files

Credits

Role Person / Project
Original integration philipp-luettecke/tiktoktts
Community TTS proxy Weilbyte/tiktok-tts
Voice list reference oscie57/tiktok-voice

TikTok TTS v1.0

Choose a tag to compare

@sfox38 sfox38 released this 15 Mar 10:27
48f4d43

TikTok TTS: v1.0.0

This is a modernized fork of the original philipp-luettecke/tiktoktts integration, updated for current Home Assistant versions with significant new features and bug fixes.

Important

If you are upgrading from the original integration, please read the Upgrading from the Original Integration section in the README before installing. A clean removal of the old integration is required.


🐛 Bug Fixes

  • Fixed PLATFORMS declaration: was a single value instead of a list, causing the integration to fail silently on modern HA versions
  • Fixed missing commas in SUPPORTED_VOICES: several singing/expressive voice entries were being silently concatenated into invalid strings by Python
  • Fixed default language and voice: changed from German (de / de_001) to English US (en_us / en_us_001)
  • Fixed broken GitHub URL in original en.json (pointed to wrong repository)

✨ New Features

  • UI config flow: integration is now configured via Settings -> Devices & Services, no configuration.yaml editing required
  • Live connection test: endpoint and session ID are validated before saving, so failures are caught at setup time
  • Options flow: change endpoint, voice, or session ID at any time via the gear icon, changes take effect immediately without a restart
  • Direct TikTok API mode: optional alternative to the proxy that calls TikTok's internal API directly using a browser session cookie, with automatic fallback across 4 known regional endpoints
  • Automatic text chunking: direct mode splits long messages at sentence and word boundaries to respect TikTok's 200-character per-request limit
  • Retry logic: both proxy and direct modes retry failed requests up to 2 times with backoff before giving up
  • Stable entity ID: always tts.tiktoktts_proxy or tts.tiktoktts_direct, no longer a random UUID

🔧 Technical / Internal Changes

  • Migrated from legacy Provider base class to modern TextToSpeechEntity
  • Replaced deprecated async_timeout library with Python's built-in asyncio.timeout
  • All hardcoded strings (API paths, field names, status codes, retry config) moved to const.py
  • Config stored entirely in entry.data - single source of truth for both setup and options flows
  • Full developer documentation added to all files

Credits

Role Person / Project
Original integration philipp-luettecke/tiktoktts
Community TTS proxy Weilbyte/tiktok-tts
Voice list reference oscie57/tiktok-voice