How-To Guides

Smarter Parenting with Home Assistant: Learn How To Spell with Spelling Assistant

Google Nest Mini and a wireless button switch

As parents, we often find ourselves seeking support in our quest to raise well-rounded, educated children. In today's technologically advanced world, it is no surprise that we are looking to integrate more digital assistance into our homes and our parenting strategies. In this post, I want to introduce you to an innovative solution I've implemented in my own home to assist my children's educational development. I've aptly named this solution the "Spelling Assistant".

The Problem

The problem that spurred the creation of Spelling Assistant is not uncommon among parents worldwide. As someone who doesn't read Chinese, my wife and I found ourselves at a loss when it came to helping our kids practice their Chinese spellings. As part of their school curriculum, they would come home with a list of words they needed to memorize. Our role was to read these words aloud for them to write and then check for accuracy. The issue? We couldn't read the words, and sometimes our work schedules interfered with this task.

The Solution

That's when the Spelling Assistant came to the rescue. Using Home Assistant, a Google Nest, and a wireless button switch, we managed to turn a challenging task into a simple and efficient learning experience.

The process begins with me or my wife entering the list of words into the Home Assistant via the frontend or through Telegram, separated by a pipe symbol (|). We then select the correct language, and our part is done. The spelling practice session is initiated by the child simply pressing the wireless button.

The Spelling Assistant in Home Assistant frontend
Or we can use Telegram to set the words and language.

The Features

The Spelling Assistant offers several features that make it incredibly user-friendly for both parents and children:

  1. Simple to operate. The system is designed around a single button. Press it once to start the test. Subsequent single presses will move to the next word.
  2. Controlled repetition. A double press repeats the current word, making sure your child can hear it as many times as needed.
  3. Cancellation feature. A long press stops or cancels the test.
  4. Randomized words. This ensures a varied and comprehensive spelling practice session.
  5. Word-dependent timer. The system calculates how long to stay on each word based on its length.
  6. Distraction-free learning. The lack of a screen minimizes distractions, promoting focus and concentration.
  7. Multilingual support. Currently, the Spelling Assistant supports Chinese, Malay, and English.
  8. Child-led operation. Apart from setting up the words, parents don't need to be involved, fostering independence in the children.

Here is a live demo on how it works:

Setup Guide

The Prerequisite

TTS Component Installation

The ideal text-to-speech (TTS) component for this project would be Google Translate TTS, given its widespread use and high-quality performance. However, it falls short in fulfilling my requirements, primarily because it doesn't support the Malay language, a vital aspect of my needs. While Indonesian is the closest language to Malay that is available, the pronunciation doesn't quite hit the mark.

Fortunately, there's an alternative custom TTS component that caters perfectly to my language requirements (Malay, Chinese, and English). It's called Microsoft Edge TTS for Home Assistant, which we will be utilizing for this project due to its comprehensive language support.

The installation process for the Edge TTS custom component is straightforward. Simply copy the respective folder to the 'custom_components' directory in your Home Assistant configuration folder. Then, to integrate the component into your system, you'll need to add the following line to your YAML configuration file:

tts:
  - platform: edge_tts

Source Code

With all the prerequisites and the TTS component installation in place, we are ready to roll up our sleeves and delve into the coding aspect of this project. To make the process more convenient for you, I've already crafted the necessary code. All you need to do is copy it and paste it into your Home Assistant.

However, it's important to understand that some entities are unique to my setup and may not be the same with yours. Therefore, some customization might be necessary. Please modify the following entity names in the code to match the ones in your configuration for the system to function properly.

  • media_player.google_home_mini
  • sensor.spelling_button_action

Here is the complete source code for the Spelling Assistant package in Home Assistant written in YAML:

##########################################################
# TTS
##########################################################
tts:
  - platform: edge_tts

##########################################################
# Input Text
##########################################################
input_text:
  spelling_words:
    name: Spelling Words (separate by |)
  current_word:
    name: Current Word
  balance_words:
    name: Balance Words

##########################################################
# Input Select
##########################################################
input_select:
  spelling_language:
    name: Spelling Language
    options:
      - English
      - Chinese
      - Malay

##########################################################
# Timer
##########################################################
timer:
  spelling_test_timer:
    name: 'Spelling Test Timer'
    duration: '00:01:00'

##########################################################
# Automation
##########################################################
automation:
  - alias: 'Spelling Speak Word'
    trigger:
      - platform: state
        entity_id: input_text.current_word
      - platform: state
        entity_id: sensor.spelling_button_action
        to: 'double'
    action:
      - service: tts.edge_tts_say
        entity_id: media_player.google_home_mini
        data_template:
          language: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              zh-CN
            {%- elif is_state('input_select.spelling_language', 'Malay') -%}
              ms-MY
            {%- else -%}
              en-GB-SoniaNeural
            {%- endif -%}
          message: "{{ states('input_text.current_word') }}"

  - alias: 'Spelling Set New Word'
    initial_state: 'on'
    trigger:
      - platform: event
        event_type: timer.finished
        event_data:
          entity_id: timer.spelling_test_timer
    action:
      - service_template: >-
          {%- if states('input_text.balance_words') == '' -%}
            script.spelling_test_ends
          {%- else -%}
            script.set_current_word
          {%- endif -%}

  - alias: 'Spelling Button Single Click Action'
    initial_state: 'on'
    trigger:
      - platform: state
        entity_id: sensor.spelling_button_action
        to: 'single'
    action:
      - service_template: >-
          {%- if states('timer.spelling_test_timer') == 'active' -%}
            {%- if states('input_text.balance_words') == '' -%}
              script.spelling_test_ends
            {%- else -%}
              script.set_current_word
            {%- endif -%}
          {%- else -%}
            script.start_spelling_test
          {%- endif -%}

  - alias: 'Spelling Ends'
    trigger:
      - platform: state
        entity_id: sensor.spelling_button_action
        to: 'hold'
    action:
      - service: timer.cancel
        entity_id: timer.spelling_test_timer
      - service: tts.edge_tts_say
        entity_id: media_player.google_home_mini
        data_template:
          language: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              zh-CN
            {%- elif is_state('input_select.spelling_language', 'Malay') -%}
              ms-MY
            {%- else -%}
              en-GB-SoniaNeural
            {%- endif -%}
          message: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              拼写测试已取消
            {%- elif is_state('input_select.spelling_language', 'Malay') -%}
              Ujian ejaan telah dibatal.
            {%- else -%}
              Spelling test cancelled.
            {%- endif -%}
            
#--------------------------------------------------------#
# Telegram
#--------------------------------------------------------#
  - alias: 'Telebot Set Spelling Words'
    initial_state: 'on'
    trigger:
      platform: event
      event_type: telegram_command
      event_data:
        command: '/spelling_words'
    action:
      - service: input_text.set_value
        data_template:
          entity_id: input_text.spelling_words
          value: >-
            {% for words in trigger.event.data["args"] %} {{ words }} {% endfor %}
      - service: telegram_bot.send_message
        data_template:
          message: "OK, spelling words set. What language is this?"
          title: ''
          target: '{{ trigger.event.data.chat_id }}'
          disable_notification: true
          keyboard:
            - "/spell_english, /spell_chinese, /spell_malay"
            
  - alias: 'Telebot Set Spelling Language English'
    initial_state: 'on'
    trigger:
      - platform: event
        event_type: telegram_command
        event_data:
          command: '/spell_english'
      - platform: event
        event_type: telegram_command
        event_data:
          command: '/spell_chinese'
      - platform: event
        event_type: telegram_command
        event_data:
          command: '/spell_malay'
    action:
      - service: input_select.select_option
        data_template:
          entity_id: input_select.spelling_language
          option: >-
            {{ trigger.event.data.command|replace('/spell_','')|capitalize }}
      - service: telegram_bot.send_message
        data_template:
          message: 'OK, spelling language set. You can start spelling test by clicking /start_spelling or simply tell Alexa "Start spelling test". Good luck!'
          title: ''
          target: '{{ trigger.event.data.chat_id }}'
          disable_notification: true
            
  - alias: 'Telebot Start Spelling Test'
    initial_state: 'on'
    trigger:
      - platform: event
        event_type: telegram_command
        event_data:
          command: '/start_spelling'
    action:
      - service: script.start_spelling_test
      - service: telegram_bot.send_message
        data_template:
          message: 'Spelling starting now. Good luck!'
          title: ''
          target: '{{ trigger.event.data.chat_id }}'
          disable_notification: true

##########################################################
# Script
##########################################################
script:
  start_spelling_test:
    alias: 'Start Spelling Test'
    sequence:
      - service: tts.edge_tts_say
        entity_id: media_player.google_home_mini
        data_template:
          language: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              zh-CN
            {%- elif is_state('input_select.spelling_language', 'Malay') -%}
              ms-MY
            {%- else -%}
              en-GB-SoniaNeural
            {%- endif -%}
          message: >-
            {%- if is_state('input_text.spelling_words', '') -%}
              {%- if is_state('input_select.spelling_language', 'Chinese') -%}
                对不起。 找不到拼写单词。
              {%- elif is_state('input_select.spelling_language', 'Malay') -%}
                Harap maaf. Kata ejaan tidak dijumpai.
              {%- else -%}
                I'm sorry. Spelling words not found.
              {%- endif -%}
            {%- else -%}
              {%- if is_state('input_select.spelling_language', 'Chinese') -%}
                现在开始拼写测试
              {%- elif is_state('input_select.spelling_language', 'Malay') -%}
                Ujian ejaan bermula sekarang.
              {%- else -%}
                Spelling test starting now.
              {%- endif -%}
            {%- endif -%}
            
      - condition: template
        value_template: "{{ states('input_text.spelling_words') != '' }}"
            
      - service: input_text.set_value
        data_template:
          entity_id: input_text.balance_words
          value: >-
            {% set spelling_words = states('input_text.spelling_words') %}

            {% set spelling_words_array = spelling_words.split('|') %}

            {% for words in spelling_words_array|unique if words|trim != '' %}
              {{- words|trim -}}
              {{- "|" if not loop.last -}}
            {% endfor %}
          
      - delay: 4
            
      - service: script.set_current_word
            
  set_current_word:
    alias: 'Set Current Word'
    sequence:
      - service: input_text.set_value
        data_template:
          entity_id: input_text.current_word
          value: >-
            {%- set words_array = states('input_text.balance_words').split('|') -%}
            {%- set current_word = words_array | random -%}
            {{ current_word }}
            
      - service: input_text.set_value
        data_template:
          entity_id: input_text.balance_words
          value: >-
            {% set balance_words = states('input_text.balance_words') %}

            {% set balance_words_array = balance_words.split('|') %}

            {% for words in balance_words_array if words|trim != '' and words != states('input_text.current_word') %}
              {{- words|trim -}}
              {{- "|" if not loop.last -}}
            {% endfor %}
      
      - service: timer.start
        data_template:
          entity_id: timer.spelling_test_timer
          duration: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              {{ states('input_text.current_word')|length*7 }}
            {%- else -%}
              {{ states('input_text.current_word')|length }}
            {%- endif -%}
            
  spelling_test_ends:
    alias: 'Spelling Test Ends'
    sequence:
      - service: timer.cancel
        entity_id: timer.spelling_test_timer
      - service: tts.edge_tts_say
        entity_id: media_player.google_home_mini
        data_template:
          language: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              zh-CN
            {%- elif is_state('input_select.spelling_language', 'Malay') -%}
              ms-MY
            {%- else -%}
              en-GB-SoniaNeural
            {%- endif -%}
          message: >-
            {%- if is_state('input_select.spelling_language', 'Chinese') -%}
              拼写测试完成
            {%- elif is_state('input_select.spelling_language', 'Malay') -%}
              Ujian ejaan sudah tamat.
            {%- else -%}
              Spelling test completed.
            {%- endif -%}
            

Conclusion

The Spelling Assistant is an example of smarter parenting through the innovative use of home technology. It offers a solution to a common problem, giving parents a chance to take advantage of tech to enhance their children's learning. Not only does this system allow us to aid our children despite language barriers or busy schedules, but it also promotes self-reliance and tech-familiarity among the younger generation. After all, raising well-educated children doesn't just mean academics - it's about preparing them for the digital world too.

Comments

Related posts