#!/usr/bin/env python3

# This script is an adaption of the servo_demo.py script for the AIY voice HAT,
# optimized for the AIY based Baille type symbol display

import aiy.audio
import aiy.cloudspeech
import aiy.voicehat

from gpiozero import LED

#from gpiozero import Button

from time import sleep

# Dictionary: an artificially modified Braille alphabet,
# numbers and some symbols taken from the Nemeth extension of Braille

Braille_6A = {
" " : "123456",  # space
"A" : "1",
"B" : "12",
"C" : "14",
"D" : "145",
"E" : "15",
"F" : "124",
"G" : "1245",
"H" : "125",
"I" : "24",
"J" : "245",
"K" : "13",
"L" : "123",
"M" : "134",
"N" : "1345",
"O" : "135",
"P" : "1234",
"Q" : "12345",
"R" : "1235",
"S" : "234",
"T" : "2345",
"U" : "136",
"V" : "1236",
"X" : "1346",
"Y" : "13456",
"Z" : "1356",
"W" : "2456",
"#" : "3456", # Number Prefix, i.e. next signs are numbers
"," : "2",
"." : "256",  # Full stop, end of sentence (GB)
"?" : "236",
"!" : "235",
"'" : "3",
"-" : "24",
";" : "23",
"Cap" : "6",  # Next letter is in Capitals; Number-Stop ?
"" : "",

# Nemeth Braille code is a mathematical expansion for 6-Point Braille
# see: https://en.wikipedia.org/wiki/Nemeth_Braille

"1" : "2",    # Nemeth Code '1', Braille 'comma'  
"2" : "23",
"3" : "25",
"4" : "256", 
"5" : "26",
"6" : "235",   # Nemeth '6', Braille '!'
"7" : "2356",
"8" : "236",  # Nemeth '8', Braille '?'
"9" : "35",
"0" : "356",
"+" : "346",
"-" : "36",
"/" : "34",
"(" : "12356",
")" : "23456",

"*" : "1346" # '*' is a two pattern symbol in Nemeth, here replaced by an 'x' to omit breaks 
}

""" for reasons of simplicity, the standard Braille number patterns given below 
    were replaced by the corresponing Nemeth-Codes

"1" : "1",  
"2" : "12",
"3" : "14",
"4" : "145",
"5" : "15",
"6" : "124",
"8" : "1245",
"9" : "24",
"0" : "245",

"""

#Text = "rbhTZkl 9t64+34#!"  # Sampletext, for debugging purposes

def main():
    
 recognizer = aiy.cloudspeech.get_recognizer()

 recognizer.expect_phrase('goodbye') # keyword, ends the program

 button = aiy.voicehat.get_button()   # AIY Button status
 led = aiy.voicehat.get_led()         # AIY Button-LED status

 aiy.audio.get_recorder().start()
 
 led_1 = LED(26) # 1st connector, servo0, GPIO 26 # upper left
 led_2 = LED(6)  # 2nd connector, servo1, GPIO 06 # middle left
 led_3 = LED(13) # 3rd connector, servo2, GPIO 13 # lower left
 led_4 = LED(5)  # 4st connector, servo3, GPIO 05 # upper right
 led_5 = LED(12) # 5th connector, servo4, GPIO 12 # middle right  
 led_6 = LED(24) # 4st connector, servo3, GPIO 13 # lower right  

 #distance= Button(5)    # distance sensor connected to servo3/GPIO 05, not used here

 aiy.audio.say("Hello!", lang="en-GB")   
 aiy.audio.say("To start, please push the button", lang="en-GB")
 aiy.audio.say("If you tell me Goodbye, I will end the program", lang="en-GB")
 
 while True:             # starts loop

    led.set_state(aiy.voicehat.LED.BLINK)   

    print("To activate voice recognition, press the blue button, then speak")
    print()

    button.wait_for_press()
    print('Listening...')
    aiy.audio.say("I am listening", lang="en-GB")    
    led.set_state(aiy.voicehat.LED.BLINK_3)

    text = recognizer.recognize()               # text string of the reognized sentence
    led.set_state(aiy.voicehat.LED.OFF)

    if text is None:
       aiy.audio.say('Sorry, I did not hear you.', lang="en-GB")

    elif 'goodbye' in text:
             aiy.audio.say("Goodbye", lang="en-GB")              
             aiy.audio.say('Arrivederci', lang="it-IT")
             aiy.audio.say('Auf Wiedersehen', lang="de-DE") 
             sleep (3)
             print('bye!')
             break       # stops loop and ends program

    else:
        print('You said "', text, '"')      # Lets you check the systems interpretation, including captialization
        aiy.audio.say('I guess you said', lang="en-GB")
        aiy.audio.say(text, lang="en-GB")   # acustic verification

        Text_up = text.upper()              # transfers all to upper case  
        print (Text_up)

        Text_Len = len(Text_up)             
        print (Text_Len)

        for i in range (Text_Len):

           Lett = Text_up [i]         # Picks a single letter, starting with first, i.e. [0]
           print ("Letter=", Lett)

           Lett_B = Braille_6A[Lett]  # Picks the corresponding code from the dictionary. A missing sign will break the code!
           print (Lett_B)

           if ("1" in Lett_B):
             print ("LED 1")      
             led_1.on()      # activates LED at servo0"

           if "2" in Lett_B:
             print ("LED 2")
             led_2.on()

           if "3" in Lett_B:
             print ("LED 3")
             led_3.on()

           if "4" in Lett_B:
             print ("LED 4")
             led_4.on()

           if "5" in Lett_B:
             print ("LED 5")
             led_5.on()

           if "6" in Lett_B:
             print ("LED 6")
             led_6.on() 

           sleep (1) # display pattern for a second
           print()

           led_1.off() # inactivate all LEDs on servos0-5n
           led_2.off()
           led_3.off()
           led_4.off()
           led_5.off()
           led_6.off()
           sleep(0.3)  # a short dark break, to indicate the end of the letter 
             
if __name__ == '__main__':
 main()
