Problem z powtarzającym się błędem w programie asystenta domowego

0

Od jakiegoś czasy pracuje nad domowym asystentem, bazującym na rozpoznawaniu głosu. Częściowe rozwiązanie kodu znalazłem w internecie. Jednak po uruchomieniu programu występuje dosyć często błąd z którym nie mogę sobie poradzić.


from asyncio import subprocess
from urllib import response
import speech_recognition as sr
import webbrowser
import pyttsx3
import os
import requests
import json
from datetime import datetime as dt
import keyboard
from time import sleep
import wikipedia


engine = pyttsx3.init()
engine.setProperty('volume', 0.70)
engine.setProperty("voice", "polish")
engine.setProperty("rate", 110)


class Zapoznanie:
    def __init__(self):

        # powitanie użytkownika
        engine.say("   Witaj, nazywam się Komputer.")
        engine.say(
            "Moim zadaniem jest ci pomóc, możesz zadawać pytania, przechodzić do różnych działów i uczyć ciebie a przy okazji i siebie.")
        engine.say("Mam nadzieję że nasza współpraca będzie owocna.")
        engine.say("A teraz powiedz co chcesz zrobić?")
        engine.runAndWait()


class Program:
    def __init__(self):
        self.now = dt.now()
        self.text = self.recognise()

        self.word_list = self.text.split(" ")

        if ("komputer" in self.text and self.word_list[0] == "komputer"):

            if "koniec" in self.text or "exit" in self.text or "zakończ" in self.text or "zakończ program" in self.text or "stop" in self.text:
                engine.say("dowidzenia! Miło było z tobą pracować!")
                engine.runAndWait()
                quit()

            elif "przerwa" in self.text or "pausa" in self.text or "pauza" in self.text:
                self.pauza()

            elif "godzina" in self.text or "czas" in self.text or "zegar" in self.text or "zegarek" in self.text:
                self.czas()

            elif "data" in self.text or "dzień" in self.text:
                self.data_1()

        if self.text != "komputer":
            print("nie rozumiem......")
            engine.say("   Niestety nie rozumiem....powiedz jeszcze raz!")
            engine.runAndWait()

    def recognise(self, msg="Słucham..."):
        self.r = sr.Recognizer()

        with sr.Microphone() as source:
            print(msg)
            audio = self.r.listen(source)

            try:
                self.recognised_text = self.r.recognize_google(
                    audio, language="pl-PL")
                print("Powiedziałeś: "+self.recognised_text)
                return self.recognised_text.lower()

            except sr.UnknownValueError:
                print("Nie mogłem zrozumieć co powiedziałeś!")
                engine.say("Nie mogłem zrozumieć co powiedziałeś!")
                engine.runAndWait()

            except sr.RequestError as e:
                print("ERROR: ", e)
                engine.say("Wystąpił jakiś błąd!")
                engine.runAndWait()

        self.recognise()

    def pauza(self):
        engine.say("Poprosiłeś o pause")
        engine.say("Ile sekund ma trwać przerwa?")
        engine.runAndWait()
        przerwa = self.recognise(msg="Ile sekund ma trwać przerwa?")

        engine.say("Zawieszam działanie na "+przerwa+" sekund")
        engine.runAndWait()
        sleep(int(przerwa))
        #self.text = self.recognise()
        engine.say("Witaj ponownie! Przywracam działanie")
        engine.say("Jestem gotowy do pracy...")
        engine.runAndWait()

    def czas(self):
        self.godz = self.now.strftime("%H")
        self.min = self.now.strftime("%M")

        self.zegar = {1: "pierwsza w nocy", 2: "druga w nocy", 3: "trzecia w nocy", 4: "czwarta w nocy", 5: "piąta rano",
                      6: "szósta rano", 7: "siódma rano", 8: "ósma rano", 9: "dziewiąta rano", 10: "dziesiąta rano",
                      11: "jedenasta przed południem", 12: "dwunasta w południe", 13: "trzynasta", 14: "czternasta", 15: "piętnasta",
                      16: "szestnasta", 17: "siedemnasta", 18: "osiemnasta", 19: "dziewiętnasta", 20: "dwudziesta",
                      21: "dwudziesta pierwsza", 22: "dwudziesta druga", 23: "dwudziesta trzecia", 24: "dwudziesta czwarta"}
        engine.say("jest godzina"+str(self.zegar.get(int(self.godz))
                                      )+",    minut"+str(self.min))
        engine.runAndWait()

    def data_1(self):
        self.rok = int(self.now.strftime("%Y"))
        self.miesiac = int(self.now.strftime("%m"))
        self.dzien = int(self.now.strftime("%d"))
        self.dzien_tygodnia = int(self.now.strftime("%w"))
        self.dzien_roku = int(self.now.strftime("%j"))

        self.miesiac_slownie = {1: "styczeń", 2: "luty", 3: "marzec", 4: "kwiecień", 5: "maj", 6: "czerwiec",
                                7: "lipiec", 8: "sierpień", 9: "wrzesień", 10: "październik", 11: "listopad", 12: "grudzień"}

        self.dzien_tygodnia_slownie = {1: "poniedziałek", 2: "wtorek",
                                       3: "środa", 4: "czwartek", 5: "piątek", 6: "sobota", 0: "niedziela"}

        d_tyg = str(self.dzien_tygodnia_slownie.get(int(self.dzien_tygodnia)))
        mies = str(self.miesiac_slownie.get(int(self.miesiac)))

        engine.say("dzisiaj jest: "+d_tyg+"      "+str(self.dzien) +
                   "       "+mies+"      rok  "+str(self.rok)+",   dzień roku"+str(self.dzien_roku))
        engine.runAndWait()

    def stolica(self):
        stolica = {"Polska": "Warszawa", "Czechy": "Praga", "USA": "Waszynkton",
                   "Stany Zjednoczone": "Waszynkton", "Afganistan": "Kabul",
                   "Albania": "Tirana", "Algieria": "Algier", "Andora": "Andora",
                   "Angola": "Luanda", "Antigua": "Saint John’s", "Barbuda": "Saint John’s",
                   "Arabia Saudyjska": "Rijad", "Argentyna": "Buenos Aires",
                   "Armenia": "Erywań", "Australia": "Canberra", "Austria": "Wiedeń",
                   "Azerbejdżan": "Baku", "Bahamy": "Nassau", "Bachamy": "Nassau",
                   "Bahrajn": "Manama", "Bachrajn": "Manama", "Bangladesz": "Dhaka", "Barbados": "Bridgetown",
                   "Belgia": "Bruksela", "Belize": "Belmopan", "Benin": "Porto-Novo", "Bhutan": "Thimphu",
                   "Bchutan": "Thimphu", "Białoruś": "Mińsk", "Boliwia": "Sucre", "Bośnia i Hercegowina": "Sarajewo",
                   "Bośnia": "Sarajewo", "Hercegowina": "Sarajewo", "Chercegowina": "Sarajewo", "Botswana": "Gaborone",
                   "Brazylia": "Brasilia", "Brunei": "Bandar Seri Begawan", "Bułgaria": "Sofia", "Burkina Faso": "Wagadugu",
                   "Burkina": "Wagadugu", "Burundi": "Gitega", "Chile": "Santiago", "Chińska Republika Ludowa": "Pekin",
                   "Chiny": "Pekin", "Chorwacja": "Zagrzeb", "Cypr": "Nikozja", "Czad": "Ndżamena", "Czarnogóra": "Podgorica",
                   "Dania": "Kopenhaga", "Demokratyczna Republika Konga": "Kinszasa", "Kongo": "Kinszasa",
                   "Dominika": "Roseau", "Dominikana": "Santo Domingo", "Dżibuti": "Dżibuti", "Egipt": "Kair",
                   "Ekwador": "Quito", "Erytrea": "Asmara", "Estonia": "Tallinn", "Eswatini": "Mbabane", "Etiopia": "Addis Abeba",
                   "Fidżi": "Suva", "Filipiny": "Manila", "Finlandia": "Helsinki", "Francja": "Paryż", "Gabon": "Libreville",
                   "Gambia": "Bandżul", "Ghana": "Akra", "Grecja": "Ateny", "Grenada": "Saint George’s", "Gruzja": "Tbilisi",
                   "Gujana": "Georgetown", "Gwatemala": "Gwatemala", "Gwinea": "Konakry", "Gwinea Bissau": "Bissau",
                   "Gwinea Równikowa": "Malabo", "Haiti": "Port-au-Prince", "Hiszpania": "Madryt", "Holandia": "Amsterdam",
                   "Honduras": "Tegucigalpa", "Indie": "Nowe Delhi", "Indonezja": "Dżakarta", "Irak": "Bagdad",
                   "Iran": "Teheran", "Irlandia": "Dublin", "Islandia": "Reykjavik",
                   "Izrael": "Jerozolima (nieuznawana przez ONZ), Tel Awiw-Jafa (siedziba większości ambasad, stolica według ONZ)",
                   "Jamajka": "Kingston", "Japonia": "Tokio", "Jemen": "Sana", "Jordania": "Amman",
                   "Kambodża": "Phnom", "Kamerun": "Jaunde", "Kanada": "Ottawa", "Katar": "Doha", "Kazachstan": "Astana",
                   "Kenia": "Nairobi", "Kirgistan": "Biszkek", "Kiribati": "Bairiki (na atolu Tarawa)", "Kolumbia": "Bogota",
                   "Komory": "Moroni", "Kongo": "Brazzaville", "Korea Południowa": "Seul", "Korea Północna": "Pjongjang",
                   "Kosowo": "Prisztina", "Kostaryka": "San José", "Kuba": "Hawana", "Kuwejt": "Kuwejt", "Laos": "Wientian",
                   "Lesotho": "Maseru", "Liban": "Bejrut", "Liberia": "Monrovia", "Libia": "Trypolis", "Liechtenstein": "Vaduz",
                   "Litwa": "Wilno", "Luksemburg": "Luksemburg", "Łotwa": "Ryga", "Macedonia Północna": "Skopje",
                   "Madagaskar": "Antananarywa", "Malawi": "Lilongwe", "Malediwy": "Male", "Malezja": "Kuala Lumpur (stolica państwa) Putrajaya (siedziba władz)",
                   "Mali": "Bamako", "Malta": "Valletta", "Maroko": "Rabat", "Mauretania": "Nawakszut", "Mauritius": "Port Louis",
                   "Meksyk": "Meksyk", "Mikronezja": "Palikir", "Mjanma": "Naypyidaw", "Mołdawia": "Kiszyniów",
                   "Monako": "Monako", "Mongolia": "Ułan Bator", "Mozambik": "Maputo", "Namibia": "Windhuk",
                   "Nauru": "Yaren (brak oficjalnej stolicy)", "Nepal": "Katmandu", "Niemcy": "Berlin",
                   "Niger": "Niamey", "Nigeria": "Abudża", "Nikaragua": "Managua", "Norwegia": "Oslo",
                   "Nowa Zelandia": "Wellington", "Oman": "Maskat", "Palestyna": "Okręg Gazy", "Pakistan": "Islamabad",
                   "Palau": "Ngerulmud", "Panama": "Panama", "Papua-Nowa Gwinea": "Port Moresby",
                   "Paragwaj": "Asunción", "Peru": "Lima", "Południowa Afryka": "Pretoria",
                   "Portugalia": "Lizbona", "Republika Środkowo Afrykańska": "Bangi",
                   "Republika Zielonego Przylądka": "Praia", "Rosja": "Moskwa", "Rumunia": "Bukareszt",
                   "Rwanda": "Kigali", "Saint Kitts i Nevis": "Basseterre", "Saint Lucia": "Castries",
                   "Saint Vincent i Grenadyny": "Kingstown", "Salwador": "San Salvador", "Samoa": "Apia",
                   "San Marino": "San Marino", "Senegal": "Dakar", "Serbia": "Belgrad", "Seszele": "Victoria",
                   "Sierra Leone": "Freetown", "Singapur": "Singapur", "Słowacja": "Bratysława", "Słowenia": "Lublana",
                   "Somalia": "Mogadiszu", "Sri Lanka": "Kolombo", "Sudan": "Chartum", "Sudan Południowy": "Dżuba",
                   "Surinam": "Paramaribo", "Syria": "Damaszek", "Szwajcaria": "Berno (brak oficjalnej stolicy)",
                   "Szwecja": "Sztokholm", "Tadżykistan": "Duszanbe", "Tajlandia": "Bangkok", "Tajwan": "Tajpej",
                   "Tanzania": "Dodoma", "Timor Wschodni": "Dili", "Togo": "Lomé", "Tonga": "Nukuʻalofa",
                   "Trynidad i Tobago": "Port-of-Spain", "Tunezja": "Tunis", "Turcja": "Ankara",
                   "Turkmenistan": "Aszchabad", "Tuvalu": "Vaiaku (na atolu Funafuti)", "Uganda": "Kampala",
                   "Ukraina": "Kijów", "Urugwaj": "Montevideo", "Uzbekistan": "Taszkent", "Vanuatu": "Port Vila",
                   "Watykan": "Watykan", "Wenezuela": "Caracas", "Węgry": "Budapeszt", "Wielka Brytania": "Londyn",
                   "Wietnam": "Hanoi", "Włochy": "Rzym", "Wybrzeże Kości Słoniowej": "Jamusukro", "Wyspy Marshalla": "Majuro",
                   "Wyspy Salomona": "Honiara", "Wyspy Świętego Tomasza i Książęca": "São Tomé", "Zambia": "Lusaka",
                   "Zimbabwe": "Harare", "Zjednoczone Emiraty Arabskie": "Abu Zabi", "Abchazja": "Suchu", "Cypr Północny": "Nikozja",
                   "Górski Karabach": "Stepanakert", "Naddniestrze": "Tyraspol", "Osetia Południowa": "Cchinwali",
                   "Palestyna": "Jerozolima", "Republika Chińska": "Tajpej", "Sahara Zachodnia": "Al-Ujun", "Somaliland": "Hargejsa"}

        engine.say("... Jakiego kraju interesuje cię stolica?")
        engine.runAndWait()
        stolica_kogo = self.recognise(
            msg="Jakiego kraju interesuje cię stolica?")
        try:
            engine.say("... Stolica "+stolica_kogo+"..." +
                       str(stolica.get(stolica_kogo)))
            engine.runAndWait()
        except:
            engine.say("... Oj coś poszło nie tak! ... Spróbuj ponownie!...")
            engine.runAndWait()

    # pomysły
    # def przypomnienia
    # def zapisz przypomnienie
    # def imieniny

    # działy
    # geografia
    # matematyka
    # rozrywka

    # ustawienia
    # nagrywanie glosu
    # tworzenie historii pogaduszek


start = Zapoznanie()

while True:
    start2 = Program()

Program bardzo często wyrzuca błąd:

  File "/home/slavo/Dokumenty/Python/SI/index.py", line 224, in <module>
    start2 = Program()
  File "/home/slavo/Dokumenty/Python/SI/index.py", line 38, in __init__
    self.word_list = self.text.split(" ")
AttributeError: 'NoneType' object has no attribute 'split'

Ale niestety to nie jedyny błąd, następne co bardzo mnie irytuje jest brak rozpoznanej mowy co drugi raz. Dla przykładu:

wołam: komputer godzina ( komputer odpowiada o ile nie wyskoczy błąd o którym pisałem wcześniej)
Komputer odpowiada: podając godzinę
wołam: komputer data
Komputer odpowiada: nie rozumiem spróbuj jeszcze raz
wołam: komputer data
Komputer odpowiada: prawidłowo

Wygląda to tak jakby komputer za szybko działał i nie nadąża z rejestracją głosu.

Czy mogę Was prosić w rozwiązaniu problemu, a może jakaś inna metoda na rozumowanie ludzkiej mowy. Za wszelką pomoc z góry dziękuję.

3

Trzeba odpalić debuger albo dać logi i zobaczyć co i gdzie się dzieje. Przyczyna błędu jest taka, że z jakiegoś powodu metoda

self.text = self.recognise()

nic nie zwraca. Ja bym zobaczył co tam wypisuje na konsoli w tym czasie.

0
S4t napisał(a):

Trzeba odpalić debuger albo dać logi i zobaczyć co i gdzie się dzieje. Przyczyn błędu jest taka, że z jakiegoś powodu metoda

self.text = self.recognise()

nic nie zwraca. Ja bym zobaczył co tam wypisuje na konsoli w tym czasie.

Program zatrzymuje się na liniii:
self.word_list = self.text.split(" ")
i wypluwa taki błąd:

Wystąpił wyjątek: AttributeError
'NoneType' object has no attribute 'split'
  File "/home/slavo/Dokumenty/Python/SI/index.py", line 38, in __init__
    self.word_list = self.text.split(" ")
  File "/home/slavo/Dokumenty/Python/SI/index.py", line 227, in <module>
    start2 = Program()
    ```
49

@S4t: Już Ci wyjaśnił. Program próbuje splitować pusty obiekt, bo dostał pusty wsad tekstowy. Musisz znaleźć przyczynę dlaczego tak się dzieje. Debuger w łapę i do dzieła.

Tak na szybko to wygląda na to, że rozpoznawanie głosu przez ten gotowy moduł działa w kratkę. Pytanie, czy masz na to jakiś wpływ.

0
ledi12 napisał(a):

@S4t: Już Ci wyjaśnił. Program próbuje splitować pusty obiekt, bo dostał pusty wsad tekstowy. Musisz znaleźć przyczynę dlaczego tak się dzieje. Debuger w łapę i do dzieła.

Tak na szybko to wygląda na to, że rozpoznawanie głosu przez ten gotowy moduł działa w kratkę. Pytanie, czy masz na to jakiś wpływ.

No właśnie nie mam, przyczyną może być to co napisałem, że komendy działają co drugi raz i pewnie dla tego dostaje pusty obiekt. Nie mam pojęcia jak to obejść lub naprawić

46
slavoHeys napisał(a):
ledi12 napisał(a):

@S4t: Już Ci wyjaśnił. Program próbuje splitować pusty obiekt, bo dostał pusty wsad tekstowy. Musisz znaleźć przyczynę dlaczego tak się dzieje. Debuger w łapę i do dzieła.

Tak na szybko to wygląda na to, że rozpoznawanie głosu przez ten gotowy moduł działa w kratkę. Pytanie, czy masz na to jakiś wpływ.

No właśnie nie mam, przyczyną może być to co napisałem, że komendy działają co drugi raz i pewnie dla tego dostaje pusty obiekt. Nie mam pojęcia jak to obejść lub naprawić

  • Potestować jaki jest najlepszy sposób na wydanie takiej komendy głosowej (jak głośno, z jakiej odległości, pod jakim kątem mikrofon) etc
  • Rozszerzyć metodę o mechanizm powtarzania dopóki głos nie zostanie poprawnie złapany (na razie masz tylko obsługę błędu).
  • Poszukać innego modułu
1
ledi12 napisał(a):
slavoHeys napisał(a):
ledi12 napisał(a):

@S4t: Już Ci wyjaśnił. Program próbuje splitować pusty obiekt, bo dostał pusty wsad tekstowy. Musisz znaleźć przyczynę dlaczego tak się dzieje. Debuger w łapę i do dzieła.

Tak na szybko to wygląda na to, że rozpoznawanie głosu przez ten gotowy moduł działa w kratkę. Pytanie, czy masz na to jakiś wpływ.

No właśnie nie mam, przyczyną może być to co napisałem, że komendy działają co drugi raz i pewnie dla tego dostaje pusty obiekt. Nie mam pojęcia jak to obejść lub naprawić

Nauczyć się python, a potem wdrożyć punkty od @ledi12 a nie próbować drogi na skróty.

  • Potestować jaki jest najlepszy sposób na wydanie takiej komendy głosowej (jak głośno, z jakiej odległości, pod jakim kątem mikrofon) etc
  • Rozszerzyć metodę o mechanizm powtarzania dopóki głos nie zostanie poprawnie złapany (na razie masz tylko obsługę błędu).
  • Poszukać innego modułu

1 użytkowników online, w tym zalogowanych: 0, gości: 1