Update voice language picker (#39775)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Darren Griffin 2025-07-04 14:50:01 +01:00 committed by Shay Levy
parent c74d7aed65
commit bb5a3e4914
8 changed files with 645 additions and 625 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ source/_data/analytics_data.json
source/_data/blueprint_exchange_data.json
source/_data/version_data.json
source/_data/alerts_data.json
source/_data/language_scores.json
source/_stash
source/stylesheets/screen.css
source/.jekyll-cache/

View File

@ -113,3 +113,14 @@ task :version_data do
file.write(JSON.generate(remote_data))
end
end
desc "Download supported language data from ohf-voice.github.io"
task :language_scores_data do
uri = URI('https://ohf-voice.github.io/intents/language_scores.json')
remote_data = JSON.parse(Net::HTTP.get(uri))
File.open("#{source_dir}/_data/language_scores.json", "w") do |file|
file.write(JSON.generate(remote_data))
end
end

View File

@ -0,0 +1,4 @@
<svg width="122" height="123" viewBox="0 0 122 123" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="120" height="120" rx="8" transform="matrix(1 0 0 -1 0.999512 121.471)" fill="white" stroke="#002332" stroke-width="2"/>
<path d="M85.6127 57.9451L63.3872 35.9726C62.0755 34.6758 59.9267 34.6758 58.615 35.9726L36.3872 57.9451C35.0755 59.2419 34 61.8066 34 63.6417V83.6612C34 85.4963 35.5188 86.9978 37.375 86.9978H58.1357L48.994 77.9601C48.5237 78.1203 48.022 78.2115 47.5 78.2115C44.9575 78.2115 42.8875 76.165 42.8875 73.6515C42.8875 71.1379 44.9575 69.0915 47.5 69.0915C50.0425 69.0915 52.1125 71.1379 52.1125 73.6515C52.1125 74.1698 52.0203 74.6658 51.8582 75.1307L58.975 82.1664V56.3902C57.445 55.6473 56.3875 54.0947 56.3875 52.2996C56.3875 49.786 58.4575 47.7396 61 47.7396C63.5425 47.7396 65.6125 49.786 65.6125 52.2996C65.6125 54.0947 64.555 55.6473 63.025 56.3902V74.4678L70.1035 67.4699C69.964 67.0339 69.8875 66.5713 69.8875 66.0908C69.8875 63.5772 71.9575 61.5308 74.5 61.5308C77.0425 61.5308 79.1125 63.5772 79.1125 66.0908C79.1125 68.6043 77.0425 70.6508 74.5 70.6508C73.9375 70.6508 73.402 70.5462 72.9047 70.3638L63.025 80.1311V87H84.625C86.4812 87 88 85.4985 88 83.6634V63.644C88 61.8088 86.9267 59.2464 85.6127 57.9473V57.9451Z" fill="#002332"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,3 +1,9 @@
<svg width="520" height="500" viewBox="0 0 520 500" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M282.483 9.76654L282.483 9.76683L496.516 220.99C502.714 227.117 508.411 236.334 512.56 246.229C516.709 256.123 519.287 266.643 519.287 275.357V467.933C519.287 485.253 504.883 499.5 487.347 499.5H279.485H32.6596C15.1236 499.5 0.719727 485.253 0.719727 467.933V275.357C0.719727 266.642 3.25437 256.165 7.38059 246.293C11.5067 236.422 17.2042 227.204 23.4906 220.99C23.4906 220.99 23.4907 220.99 23.4907 220.99L237.347 9.76669L237.35 9.76407C249.67 -2.58667 269.983 -2.5902 282.483 9.76654Z" fill="#E5F7FE" stroke="white"/>
<svg width="660" height="780" viewBox="0 0 660 780" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M301.128 12.3232C316.832 -3.43998 342.719 -3.44313 358.65 12.3262H358.651L630.534 281.002C638.424 288.811 645.67 300.554 650.944 313.15C656.219 325.747 659.5 339.146 659.5 350.255V738.682C659.5 760.79 641.14 778.971 618.792 778.971H41.208C18.8597 778.971 0.5 760.79 0.5 738.682V350.255C0.5 339.145 3.72558 325.8 8.97168 313.232C14.2177 300.665 21.4638 288.923 29.4658 281.002L301.125 12.3262L301.128 12.3232Z" fill="url(#paint0_linear_1813_708)" stroke="white"/>
<defs>
<linearGradient id="paint0_linear_1813_708" x1="683" y1="596.5" x2="213.5" y2="92" gradientUnits="userSpaceOnUse">
<stop stop-color="#E5F7FE"/>
<stop offset="1" stop-color="#E5F7FE" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 813 B

View File

@ -27,7 +27,8 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<a href="#features">Features</a>
<a href="#specs">Specs</a>
<a href="#faq">FAQ</a>
<a href="https://support.nabucasa.com/hc/en-us/categories/24451727188125-Home-Assistant-Voice-Preview-Edition" target="_blank" rel="noopener">Docs</a>
<a href="https://support.nabucasa.com/hc/en-us/categories/24451727188125-Home-Assistant-Voice-Preview-Edition"
target="_blank" rel="noopener">Docs</a>
<a href="#" class="cta buy">Buy now</a>
</div>
<div class="burger">
@ -40,7 +41,8 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<a href="#features">Features</a>
<a href="#specs">Specs</a>
<a href="#faq">FAQ</a>
<a href="https://support.nabucasa.com/hc/en-us/categories/24451727188125-Home-Assistant-Voice-Preview-Edition" target="_blank" rel="noopener">Docs</a>
<a href="https://support.nabucasa.com/hc/en-us/categories/24451727188125-Home-Assistant-Voice-Preview-Edition"
target="_blank" rel="noopener">Docs</a>
<a href="#" class="cta buy">Buy now</a>
</div>
</div>
@ -217,7 +219,8 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
alt="Front view of the Voice Preview Edition showing the speaker holes">
<div class="wrapper">
<a class="button secondary buy">Buy now</a>
<small>* Recommended MSRP. Prices differ between regions due to varying local market costs and conditions, and subject to individual retailers.</small>
<small>* Recommended MSRP. Prices differ between regions due to varying local market costs and conditions,
and subject to individual retailers.</small>
</div>
</div>
</div>
@ -461,9 +464,8 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<div class="grid"></div>
</div>
<div class="wrapper">
<div class="fs-medium">Bringing<br>choice to<br>voice</div>
<div class="subtitle">If you have powerful hardware, run voice fully locally, or offload speech processing to
our privacy-first cloud for speedy performance.</div>
<div class="fs-medium">Bringing choice<br> to voice</div>
<div class="subtitle">Run voice fully locally, or offload speech processing to our privacy-first cloud.</div>
</div>
</div>
</section>
@ -473,25 +475,61 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<div class="grid"></div>
</div>
<div class="wrapper">
<div class="info-sides">
<div class="info-side">
<div class="side-info-wrapper">
<div class="side-info">
<span>Local</span>
<p>Your voice never leaves your home and the processing is pretty accurate, but is hardware-intensive.</p>
<img src="/images/voice-pe/local-cloud/house.svg" class="house-bg" loading="lazy">
<div class="graphic-wapper-revised">
<div class="graphic">
<div class="sides">
<div class="side local">
<div class="cards">
<div class="graphic-card">
<span>Focused local processing</span>
<p>Limited to a set list of common home control phrases, this allows even low-powered hardware
system to process speech locally and offline.</p>
<div class="line">
<span>
<span></span>
<span></span>
</span>
</div>
</div>
<div class="graphic-card">
<span>Full local processing</span>
<p>Full speech processing is done locally, requiring high processing power for adequate speed and
accuracy.</p>
<div class="line">
<span>
<span></span>
<span></span>
</span>
</div>
</div>
</div>
<div class="info-side">
<div class="side-info-wrapper">
<div class="side-info">
<span>Cloud</span>
<p>Your voice is processed on a private cloud, allowing Assist to run fast and very accurately on low-powered hardware.</p>
<div class="devices">
<div class="device device--voice-pe">
<img loading="lazy" src="/images/voice-pe/local-cloud/vpe-graphic.svg"
alt="Generic outline drawing of the Voice Preview Edition">
</div>
<div class="line-dashed"></div>
<div class="device device--ha">
<img loading="lazy" src="/images/voice-pe/local-cloud/ha-instance.svg"
alt="Generic outline drawing of the Voice Preview Edition">
</div>
</div>
</div>
<div class="side cloud">
<div class="cards">
<div class="graphic-card">
<div class="h-line"></div>
<span>Home Assistant Cloud</span>
<p>Your voice is processed privately on Home Assistant Cloud, allowing Assist to run very accurately
on low-powered hardware.</p>
</div>
</div>
</div>
</div>
<div class="graphic-wrapper">
</div>
</div>
<div class="graphic-wrapper" style="display: none;">
<div class="house-bg" data-bg-image-lazy></div>
<div class="graphic">
<div class="sides" data-side="cloud">
@ -588,140 +626,91 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
</div>
<div class="wrapper">
<div class="language-card">
<div class="h2">Breaking language barriers</div>
<div class="h2">Check supported languages</div>
<div class="subtitle">Assist aims to support more languages than other voice assistants, but this is still a
work in progress, and we need your help.</div>
<div class="form-title h3">Check supported languages here</div>
<div class="input-wrapper">
<select id="language-select">
<option data-display="Select">Choose your language</option>
<option value="af-ZA">Afrikaans</option>
<option value="sq-AL">Albanian</option>
<option value="am-ET">Amharic</option>
<option value="ar-JO">Arabic</option>
<option value="hy-AM">Armenian</option>
<option value="az-AZ">Azerbaijani</option>
<option value="eu-ES">Basque</option>
<option value="bn-IN">Bengali</option>
<option value="bs-BA">Bosnian</option>
<option value="bg-BG">Bulgarian</option>
<option value="my-MM">Burmese</option>
<option value="ca-ES">Catalan</option>
<option value="zh-HK">Chinese (Cantonese)</option>
<option value="zh-CN">Chinese (Mandarin)</option>
<option value="hr-HR">Croatian</option>
<option value="cs-CZ">Czech</option>
<option value="da-DK">Danish</option>
<option value="nl-BE">Dutch (Belgium)</option>
<option value="nl-NL">Dutch (Netherlands)</option>
<option value="en-US">English</option>
<option value="et-EE">Estonian</option>
<option value="fil-PH">Filipino</option>
<option value="fi-FI">Finnish</option>
<option value="fr-FR">French</option>
<option value="gl-ES">Galician</option>
<option value="ka-GE">Georgian</option>
<option data-display="Select">Select your language</option>
<option value="af-ZA">Afrikaans (South Africa)</option>
<option value="ar-JO">Arabic (Jordan)</option>
<option value="bg-BG">Bulgarian (Bulgaria)</option>
<option value="bn-BD">Bengali (Bangladesh)</option>
<option value="bn-IN">Bengali (India)</option>
<option value="ca-ES">Catalan (Spain)</option>
<option value="cs-CZ">Czech (Czech Republic)</option>
<option value="da-DK">Danish (Denmark)</option>
<option value="de-DE">German (Germany)</option>
<option value="de-CH">German (Switzerland)</option>
<option value="el-GR">Greek</option>
<option value="gu-IN">Gujarati</option>
<option value="he-IL">Hebrew</option>
<option value="hi-IN">Hindi</option>
<option value="hu-HU">Hungarian</option>
<option value="is-IS">Icelandic</option>
<option value="id-ID">Indonesian</option>
<option value="ga-IE">Irish</option>
<option value="it-IT">Italian</option>
<option value="ja-JP">Japanese</option>
<option value="jv-ID">Javanese</option>
<option value="kn-IN">Kannada</option>
<option value="kk-KZ">Kazakh</option>
<option value="km-KH">Khmer</option>
<option value="ko-KR">Korean</option>
<option value="lo-LA">Lao</option>
<option value="lv-LV">Latvian</option>
<option value="lt-LT">Lithuanian</option>
<option value="lb-LU">Luxembourgish</option>
<option value="mk-MK">Macedonian</option>
<option value="ms-MY">Malay</option>
<option value="ml-IN">Malayalam</option>
<option value="mt-MT">Maltese</option>
<option value="mr-IN">Marathi</option>
<option value="mn-MN">Mongolian</option>
<option value="ne-NP">Nepali</option>
<option value="nb-NO">Norwegian</option>
<option value="ps-AF">Pashto</option>
<option value="fa-IR">Persian</option>
<option value="pl-PL">Polish</option>
<option value="pt-BR">Portuguese (Brazil)</option>
<option value="el-GR">Greek (Greece)</option>
<option value="en-US">English (United States)</option>
<option value="en-GB">English (United Kingdom)</option>
<option value="es-ES">Spanish (Spain)</option>
<option value="es-MX">Spanish (Mexico)</option>
<option value="et-EE">Estonian (Estonia)</option>
<option value="eu-ES">Basque (Spain)</option>
<option value="fa-IR">Persian (Iran)</option>
<option value="fi-FI">Finnish (Finland)</option>
<option value="fr-FR">French (France)</option>
<option value="ga-IE">Irish (Ireland)</option>
<option value="gl-ES">Galician (Spain)</option>
<option value="gu-IN">Gujarati (India)</option>
<option value="he-IL">Hebrew (Israel)</option>
<option value="hi-IN">Hindi (India)</option>
<option value="hr-HR">Croatian (Croatia)</option>
<option value="hu-HU">Hungarian (Hungary)</option>
<option value="id-ID">Indonesian (Indonesia)</option>
<option value="is-IS">Icelandic (Iceland)</option>
<option value="it-IT">Italian (Italy)</option>
<option value="ka-GE">Georgian (Georgia)</option>
<option value="kn-IN">Kannada (India)</option>
<option value="ko-KR">Korean (South Korea)</option>
<option value="lb-LU">Luxembourgish (Luxembourg)</option>
<option value="lt-LT">Lithuanian (Lithuania)</option>
<option value="lv-LV">Latvian (Latvia)</option>
<option value="ml-IN">Malayalam (India)</option>
<option value="mn-MN">Mongolian (Mongolia)</option>
<option value="mr-IN">Marathi (India)</option>
<option value="ms-MY">Malay (Malaysia)</option>
<option value="nb-NO">Norwegian Bokmål (Norway)</option>
<option value="ne-NP">Nepali (Nepal)</option>
<option value="nl-BE">Dutch (Belgium)</option>
<option value="nl-NL">Dutch (Netherlands)</option>
<option value="pl-PL">Polish (Poland)</option>
<option value="pt-PT">Portuguese (Portugal)</option>
<option value="ro-RO">Romanian</option>
<option value="ru-RU">Russian</option>
<option value="sr-RS">Serbian</option>
<option value="si-LK">Sinhala</option>
<option value="sk-SK">Slovak</option>
<option value="sl-SI">Slovenian</option>
<option value="so-SO">Somali</option>
<option value="es-ES">Spanish</option>
<option value="su-ID">Sundanese</option>
<option value="sw-KE">Swahili</option>
<option value="sv-SE">Swedish</option>
<option value="ta-IN">Tamil</option>
<option value="te-IN">Telugu</option>
<option value="th-TH">Thai</option>
<option value="tr-TR">Turkish</option>
<option value="uk-UA">Ukrainian</option>
<option value="ur-IN">Urdu</option>
<option value="uz-UZ">Uzbek</option>
<option value="vi-VN">Vietnamese</option>
<option value="cy-GB">Welsh</option>
<option value="zu-ZA">Zulu</option>
<option value="pt-BR">Portuguese (Brazil)</option>
<option value="ro-RO">Romanian (Romania)</option>
<option value="ru-RU">Russian (Russia)</option>
<option value="sk-SK">Slovak (Slovakia)</option>
<option value="sl-SI">Slovenian (Slovenia)</option>
<option value="sr-RS">Serbian (Serbia)</option>
<option value="sv-SE">Swedish (Sweden)</option>
<option value="sw-KE">Swahili (Kenya)</option>
<option value="te-IN">Telugu (India)</option>
<option value="th-TH">Thai (Thailand)</option>
<option value="tr-TR">Turkish (Turkey)</option>
<option value="uk-UA">Ukrainian (Ukraine)</option>
<option value="ur-IN">Urdu (India)</option>
<option value="vi-VN">Vietnamese (Vietnam)</option>
<option value="zh-CN">Chinese (China)</option>
<option value="zh-HK">Chinese (Hong Kong)</option>
<option value="zh-TW">Chinese (Taiwan)</option>
</select>
</div>
<div class="supported-cards">
<div class="supported-card local warning" data-state="3">
<div class="supported-card local warning" data-state="-1">
<div class="heading">
<span>Local</span>
<span>Local processing</span>
</div>
<div class="state-bar">
<span></span><span></span><span></span>
<div class="description">
</div>
<div class="info state-0">Not supported <a href="#faq-language-not-supported"><svg
xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none">
<mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="16" height="16">
<path fill="#D9D9D9" d="M0 0h16v16H0z" />
</mask>
<g mask="url(#a)">
<path
d="M7.333 11.333h1.334v-4H7.334v4ZM8 6a.645.645 0 0 0 .475-.192.645.645 0 0 0 .192-.475.645.645 0 0 0-.192-.475A.645.645 0 0 0 8 4.667a.645.645 0 0 0-.475.191.645.645 0 0 0-.192.475c0 .19.064.348.192.475A.645.645 0 0 0 8 6Zm0 8.667a6.492 6.492 0 0 1-2.6-.525 6.732 6.732 0 0 1-2.117-1.425A6.732 6.732 0 0 1 1.86 10.6 6.491 6.491 0 0 1 1.333 8c0-.922.175-1.789.526-2.6a6.732 6.732 0 0 1 1.425-2.117c.6-.6 1.305-1.075 2.116-1.425A6.492 6.492 0 0 1 8 1.333c.922 0 1.789.175 2.6.525.811.35 1.517.825 2.117 1.425.6.6 1.075 1.306 1.425 2.117.35.811.525 1.678.525 2.6 0 .922-.175 1.789-.525 2.6a6.732 6.732 0 0 1-1.425 2.117c-.6.6-1.306 1.075-2.117 1.425a6.492 6.492 0 0 1-2.6.525Zm0-1.334c1.49 0 2.75-.516 3.784-1.55 1.033-1.033 1.55-2.294 1.55-3.783 0-1.489-.517-2.75-1.55-3.783C10.75 3.183 9.489 2.667 8 2.667c-1.489 0-2.75.516-3.783 1.55C3.184 5.25 2.667 6.51 2.667 8c0 1.489.517 2.75 1.55 3.783C5.25 12.817 6.51 13.333 8 13.333Z"
fill="#002332" />
</g>
</svg></a></div>
<div class="info state-1">Needs more work</div>
<div class="info state-2">Ready to use</div>
<div class="info state-3">Fully supported</div>
</div>
<div class="supported-card cloud check" data-state="-1">
<div class="supported-card cloud warning" data-state="-1">
<div class="heading">
<span>Home Assistant Cloud</span>
</div>
<div class="state-bar">
<span></span><span></span><span></span>
</div>
<div class="info state-0">Not supported <a href="#faq-language-not-supported-cloud"><svg
xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none">
<mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="16" height="16">
<path fill="#D9D9D9" d="M0 0h16v16H0z" />
</mask>
<g mask="url(#a)">
<path
d="M7.333 11.333h1.334v-4H7.334v4ZM8 6a.645.645 0 0 0 .475-.192.645.645 0 0 0 .192-.475.645.645 0 0 0-.192-.475A.645.645 0 0 0 8 4.667a.645.645 0 0 0-.475.191.645.645 0 0 0-.192.475c0 .19.064.348.192.475A.645.645 0 0 0 8 6Zm0 8.667a6.492 6.492 0 0 1-2.6-.525 6.732 6.732 0 0 1-2.117-1.425A6.732 6.732 0 0 1 1.86 10.6 6.491 6.491 0 0 1 1.333 8c0-.922.175-1.789.526-2.6a6.732 6.732 0 0 1 1.425-2.117c.6-.6 1.305-1.075 2.116-1.425A6.492 6.492 0 0 1 8 1.333c.922 0 1.789.175 2.6.525.811.35 1.517.825 2.117 1.425.6.6 1.075 1.306 1.425 2.117.35.811.525 1.678.525 2.6 0 .922-.175 1.789-.525 2.6a6.732 6.732 0 0 1-1.425 2.117c-.6.6-1.306 1.075-2.117 1.425a6.492 6.492 0 0 1-2.6.525Zm0-1.334c1.49 0 2.75-.516 3.784-1.55 1.033-1.033 1.55-2.294 1.55-3.783 0-1.489-.517-2.75-1.55-3.783C10.75 3.183 9.489 2.667 8 2.667c-1.489 0-2.75.516-3.783 1.55C3.184 5.25 2.667 6.51 2.667 8c0 1.489.517 2.75 1.55 3.783C5.25 12.817 6.51 13.333 8 13.333Z"
fill="#002332" />
</g>
</svg></a></div>
<div class="info state-1">Needs more work</div>
<div class="info state-2">Ready to use</div>
<div class="info state-3">Fully supported</div>
<div class="description"></div>
</div>
</div>
<a href="https://www.home-assistant.io/voice_control/contribute-voice" target="_blank" rel="noopener"
@ -1022,17 +1011,21 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<div class="faq-item-content-animation">
<div class="faq-item-content-transform-wrapper">
<div class="faq-item-content">
<p>Yes, provided your language is supported and you have hardware powerful enough to run local
text-to-speech and speech-to-text models at a speed that is acceptable to you. Speech-to-text is
the main limiting factor for many languages to run locally, as it has mixed results and often
requires powerful hardware.</p>
<p>We recommend using at least an Intel N100 or equivalent processor;
this will allow you to use OpenAIs Whisper Base model for speech-to-text locally. This model
runs reasonably fast for languages that have large public datasets to train on, such as English
and Spanish. However, for languages with less data available, you will need Whispers Small or
Large models that require significantly more powerful hardware to run. For some languages, no
public datasets exist yet for local models to be trained on by OpenAI, and until they exist and
they train models, you will not be able to run those languages fully locally.</p>
<p>Yes, provided your language is supported. For some languages, you can set up Assist and your
Voice Preview Edition to use a Focused Local model, which uses Speech-to-Phrase add-on. It can run
locally and accurately on lower-power hardware, by generating a local speech-to-text model
specifically for your Home Assistant installation. It is limited to predefined sentences aimed at
controlling your home, but not able to process general speech. For instance, it could turn on a
device, but would not be able to add something to your shopping list.</p>
<p>For other languages, Speech-to-Phrase may not be supported, which will require Fully Local
speech-to-text solution, such as the Whisper add-on. Fully local speech-to-text requires powerful
hardware to be accurate and responsive. If you wish to use OpenAIs Whisper, we recommend using at
least an Intel N100 or equivalent processor. This will allow you to use the Whisper Base model for
speech-to-text locally. This model runs reasonably fast for languages that have large public
datasets to train on, such as English and Spanish. However, for languages with less data
available, you will need Whispers Small or Large models that require significantly more powerful
hardware to run.</p>
</div>
</div>
</div>
@ -1051,13 +1044,11 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<div class="faq-item-content-animation">
<div class="faq-item-content-transform-wrapper">
<div class="faq-item-content">
<p>You do not need Home Assistant Cloud. However, if you are running less powerful hardware, like
Home Assistant Green or a Raspberry Pi 4, we believe this provides the best experience. By doing
so, you can leverage our cloud for speech processing, ensuring superior accuracy and faster
performance not possible on your low-powered device.</p>
<p>Additionally, some languages have poor or
non-existent support by the local speech-to-text software we leverage (OpenAIs Whisper), but
are well-supported by the speech processing used by Home Assistant Cloud.</p>
<p>You do not need Home Assistant Cloud. However, for some languages, we believe that Home Assistant
Cloud provides the best experience. There are languages that are not supported by the local
speech-to-text models we leverage (either our focused local Speech-to-Phrase model, or the fully
local Whisper by OpenAI), but are well-supported by the speech processing used by Home Assistant
Cloud.</p>
</div>
</div>
</div>
@ -1182,17 +1173,17 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
<div class="faq-item-content-transform-wrapper">
<div class="faq-item-content">
<p>Yes, Home Assistant can be configured to use any speech-to-text integration that supports the
Wyoming protocol. Currently, the only locally-run speech-to-text add-on available for Home
Assistant users is OpenAIs Whisper. This has mixed results, missing languages, and is
hardware-intensive.</p>
<p>That led us to build an alternative - <a href="https://github.com/rhasspy/rhasspy-speech"
target="_blank" rel="noopener">Rhasspy Speech</a> can run locally and
accurately on lower-power hardware, though this does not provide full speech-to-text
capabilities. Based on the Rhasspy project, it is able to create local speech-to-text models,
but is limited to predefined sentences aimed at controlling your home, and will not be able to
process general speech. For instance, it could turn on a device, but will not be able to add
something to your shopping list. We expect to share the first version of Rhasspy Speech during
the next Voice livestream in 2025.</p>
Wyoming protocol. The most commonly used fully local speech-to-text add-on available for Home
Assistant users is OpenAIs Whisper. This has mixed results; specifically, it lacks support for
some languages and is hardware-intensive.</p>
<p>Our alternative speech-to-text model, <a href="https://github.com/OHF-Voice/speech-to-phrase"
target="_blank" rel="noopener">Speech-To-Phrase</a>, can run locally and accurately on
lower-power hardware, though this does not provide full speech-to-text capabilities. Based on the
<a href="https://github.com/rhasspy/rhasspy" target="_blank" rel="noopener">Rhasspy project</a>,
it is able to create focused local speech-to-text models, limited to predefined sentences aimed at
controlling your home, but not able to process general speech. For instance, it could turn on a
device, but would not be able to add something to your shopping list.
</p>
</div>
</div>
</div>
@ -1383,4 +1374,7 @@ frontpage_image: /images/frontpage/voice-pe-frontpage.jpg
{% include custom/buy-dialog.html product="voice-pe" %}
<script>
window.language_scores = {{ site.data.language_scores | jsonify }};
</script>
<script src="/voice-pe/script.js" type="text/javascript"></script>

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="61" height="259" viewBox="0 0 61 259" fill="none">
<path d="M60 259V21C60 10 51 1 40 1C28 1 12 1 0 1" stroke="#DB582E" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 192 B

View File

@ -15,7 +15,6 @@ document.addEventListener('DOMContentLoaded', function () {
registerCarousels();
registerVideoModal();
registerBurgerIcon();
registerCycleLocalCloud();
registerLanguageSelectChange();
registerFeatureCycle();
registerFaqItems();
@ -29,7 +28,7 @@ function addBodyLoaded() {
let languageSelect = null;
function registerNiceSelect() {
languageSelect = NiceSelect.bind(document.querySelector("select#language-select"), { searchable: true });
languageSelect = NiceSelect.bind(document.querySelector("select#language-select"), { searchable: true, placeholder: 'Select your language' });
}
function scrollIfFragment() {
@ -437,47 +436,6 @@ function registerBurgerIcon() {
});
}
function registerCycleLocalCloud() {
// add intersection observer to #product-features. Only execute once
const sides = document.querySelector('#local-cloud .sides');
if (!sides) return;
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
observer.disconnect();
// set css variable for
let lastSide = 'cloud';
let interval = null;
interval = setInterval(() => {
// toggle between data-side="local" and data-side="cloud"
sides.setAttribute('data-side', '');
setTimeout(() => {
lastSide = lastSide === 'local' ? 'cloud' : 'local';
sides.setAttribute('data-side', lastSide);
}, 500);
}, 5000);
// if hover on left side, set to local
sides.querySelector('.side.local').addEventListener('mouseenter', function () {
clearInterval(interval);
sides.setAttribute('data-side', 'local');
});
// if hover on right side, set to cloud
sides.querySelector('.side.cloud').addEventListener('mouseenter', function () {
clearInterval(interval);
sides.setAttribute('data-side', 'cloud');
});
}
});
}, {
threshold: .5
});
observer.observe(sides);
}
function registerLanguageSelectChange() {
const browserLocale = navigator.language || navigator.userLanguage;
@ -488,97 +446,32 @@ function registerLanguageSelectChange() {
});
}
function updateLanguageSupports(locale = null) {
let data = {
"en-US": [3, 3],
"es-ES": [3, 3],
"pt-BR": [3, 3],
"pt-PT": [2, 2],
"de-DE": [3, 3],
"de-CH": [0, 2],
"it-IT": [2, 2],
"ru-RU": [2, 2],
"ja-JP": [0, 0],
"tr-TR": [0, 1],
"ko-KR": [0, 1],
"fr-FR": [0, 3],
"ca-ES": [0, 3],
"pl-PL": [0, 3],
"nl-BE": [0, 3],
"nl-NL": [0, 3],
"id-ID": [0, 1],
"zh-HK": [0, 2],
"zh-CN": [0, 1],
"ms-MY": [0, 1],
"sv-SE": [0, 2],
"uk-UA": [0, 2],
"th-TH": [0, 1],
"vi-VN": [0, 1],
"fi-FI": [0, 3],
"no-NO": [0, 0],
"gl-ES": [0, 2],
"ar-JO": [0, 2],
"ur-IN": [0, 0],
"el-GR": [0, 1],
"ro-RO": [0, 3],
"da-DK": [0, 2],
"ta-IN": [0, 0],
"hr-HR": [0, 3],
"mk-MK": [0, 0],
"sk-SK": [0, 1],
"he-IL": [0, 2],
"sr-RS": [0, 1],
"hu-HU": [0, 3],
"bg-BG": [0, 2],
"cs-CZ": [0, 1],
"bs-BA": [0, 0],
"sl-SI": [0, 2],
"az-AZ": [0, 0],
"et-EE": [0, 1],
"lv-LV": [0, 1],
"af-ZA": [0, 0],
"cy-GB": [0, 0],
"fa-IR": [0, 1],
"lt-LT": [0, 1],
"jv-ID": [0, 0],
"sw-KE": [0, 0],
"sw-TZ": [0, 0],
"is-IS": [0, 1],
"mt-MT": [0, 0],
"ps-AF": [0, 0],
"mr-IN": [0, 0],
"bn-IN": [0, 0],
"lb-LU": [0, 0],
"hi-IN": [0, 0],
"gu-IN": [0, 0],
"km-KH": [0, 0],
"ne-NP": [0, 0],
"lo-LA": [0, 0],
"te-IN": [0, 1],
"kn-IN": [0, 0],
"ml-IN": [0, 1],
"kk-KZ": [0, 0],
"so-SO": [0, 0],
"uz-UZ": [0, 0],
"ka-GE": [0, 1],
"my-MM": [0, 0],
"mn-MN": [0, 0],
"hy-AM": [0, 0],
"am-ET": [0, 0],
"nb-NO": [0, 3],
"eu-ES": [0, 1],
"fil-PH": [0, 0],
"ga-IE": [0, 0],
"si-LK": [0, 0],
"sq-AL": [0, 0],
"su-ID": [0, 0],
"wuu-CN": [0, 0],
"yue-CN": [0, 0],
"zu-ZA": [0, 0]
};
const languageDescriptions = {
'local': {
0: 'Running this language locally is not supported.',
1: 'Full local processing is supported for this language, which requires powerful hardware (Intel N100 or greater) to provide adequate performance.',
2: 'Focused local processing is supported for this language, which works on even low-powered systems, but is limited to home control commands.',
3: 'Both Focused and Full local processing are supported for this language.'
},
'cloud': {
0: 'Cloud processing is not supported for this language.',
1: 'Cloud processing is supported for this language, allowing fast and accurate processing even on low-powered Home Assistant systems.'
}
}
let elems = document.querySelectorAll('.supported-cards .supported-card');
if (!elems) return;
function updateLanguageSupports(locale = null) {
let data = window.language_scores;
if(!data || !locale) {
console.warn('No language data available or locale not provided.');
return;
}
const localElem = document.querySelector('.supported-cards .supported-card.local');
const cloudElem = document.querySelector('.supported-cards .supported-card.cloud');
if (!localElem || !cloudElem) return;
const localElemDescription = localElem.querySelector('.description');
const cloudElemDescription = cloudElem.querySelector('.description');
let supports = data[locale];
let foundLocale = locale;
@ -595,12 +488,27 @@ function updateLanguageSupports(locale = null) {
document.querySelector('#language-select').value = foundLocale;
languageSelect.update();
elems.forEach(elem => elem.setAttribute('data-state', '-1'));
if (supports.focused_local === 0 && supports.full_local === 0) {
localElem.setAttribute('data-state', '0');
localElemDescription.innerHTML = languageDescriptions.local[0];
} else if (supports.full_local > 0 && supports.focused_local === 0) {
localElem.setAttribute('data-state', '1');
localElemDescription.innerHTML = languageDescriptions.local[1];
} else if (supports.focused_local > 0 && supports.full_local === 0) {
localElem.setAttribute('data-state', '2');
localElemDescription.innerHTML = languageDescriptions.local[2];
} else if (supports.focused_local > 0 && supports.full_local > 0) {
localElem.setAttribute('data-state', '3');
localElemDescription.innerHTML = languageDescriptions.local[3];
}
elems.forEach((elem, index) => {
// set data-state to the value of the value
elem.setAttribute('data-state', supports[index]);
});
if (supports.cloud === 0) {
cloudElem.setAttribute('data-state', '0');
cloudElemDescription.innerHTML = languageDescriptions.cloud[0];
} else if (supports.cloud > 0) {
cloudElem.setAttribute('data-state', '3');
cloudElemDescription.innerHTML = languageDescriptions.cloud[1];
}
}

File diff suppressed because it is too large Load Diff