shivasiddharth / GassistPi

Google Assistant for Single Board Computers
Other
1.02k stars 304 forks source link

websocket connection #355

Closed bimbim2401 closed 6 years ago

bimbim2401 commented 6 years ago

Hi, what do you think about the idea to have a facial recognition with a cam ( usb or pi cam ), i order to say "hello xxx" when it detect you

in the magic mirror there is a module MMM-Assistant which have an interaction with MMM-facial-recognition like this.

But i prefere your assistant which is more stable and works better and which is totally free, this is one reason that i am totaly agree with the fact to create a module with gassitpi

@shivasiddharth , Do you think that gassistPi can receive notification to say something ?

bimbim2401 commented 6 years ago

Maybe do you think it could be simple to have a socket to listen to notifications in gassistpi. In the socket we can ask gassistPI to say something. Like in the control with gassistpi of the magic mirror with get request we can have a code in python which create a web service or something like this to received notification

If you give me some information I can try to make it

bimbim2401 commented 6 years ago

I find this code which listen to a websocket in python

import asyncio import websockets

from actions import say

async def hello(websocket, path): name = await websocket.recv() print(f"< {name}") greeting = f"Hello {name}!" print(f"> {greeting}") say(greeting) start_server = websockets.serve(hello, 'localhost', 8080) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

So now i have just to add the say method from action in order to make gassistpi talk when i send a notification on the websocket with my javascript module. I think it will work.

@shivasiddharth as i have the bug in the issue https://github.com/shivasiddharth/GassistPi/issues/356 i try to find another solution to start manually a conversation with the assistant. My idea is to send a get request from javascript to my python script, here are my possibilities

Can you give me some help to choose the best way for doing it ?

bimbim2401 commented 6 years ago

Hummm doesn t work for now, i have issue with the installation of websockets it say that no module name webosckets.

I think the 3 solutions are not good so this is another one

Create a thread with the previous websockets script

in the main.py line 256

class WebSocketsListener(Thread): """Thread chargé d'ecouter les messages sur la websocket."""

def __init__(self, assistant):
    Thread.__init__(self)
    self.assistant = assistant

async def hello(websocket, path):
    message = await websocket.recv()
    print(message)
    if 'assistant'.lower() in str(message).lower():
        if 'on'.lower() in str(message).lower():
            # event = Assistant.New(EventType.ON_CONVERSATION_TURN_STARTED, {})
            self.assistant.start_conversation()
        elif 'say'.lower() in str(message).lower():
            #traitement pour récuperer la chaine a dire dans la variable text
            say(text)

def run(self):
    """Code à exécuter pendant l'exécution du thread."""
    start_server = websockets.serve(hello, 'localhost', 8080)
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()

and then in the main just before the event processing

webSocketsListener = WebSocketsListener(assistant) webSocketsListener.start()

for event in events: ... ....

hope it will work

bimbim2401 commented 6 years ago

cannot succeed to make it works, please @aandroide @shivasiddharth or maybe some one else can help me to intercept get request in the main.py

i really need this functionnality to make gassistPI talk when i want by sending a message from a web browser

bimbim2401 commented 6 years ago

Hey,

i have succeed to make it works with the following in the main.py, my problem was due to the port which was already in use, and then i have to take another one.

add the import

from threading import Thread
from urllib.parse import unquote

then just before the main function add

class WebSocketsListener(Thread):
"""Thread chargé d'ecouter les messages sur la websocket."""

def __init__(self, assistant):
    Thread.__init__(self)
    self.websocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.websocket.bind(('127.0.0.1', 8081))
    self.assistant = assistant

def run(self):
    print ("Open socket")

    while True:
        self.websocket.listen(5)
        client, address = self.websocket.accept()
        print (format( address ))

        response = client.recv(255)
        if response != "":
            print (response)
            str_response = response.decode("utf-8")
            if 'assistant' in str_response:

                if 'mode' in str_response:
                    if 'start' in str_response:
                        print("start the assistant") 
                        self.assistant.start_conversation()
                    if 'stop' in str_response: 
                        print("stop  the assistant") 
                        self.assistant.stop_conversation()

                elif 'say' in str_response:
                    token = str_response[str_response.find("say=")+4:str_response.find("HTTP")-1]
                    token = unquote(token)
                    say(token)

    print ("Close socket")
    client.close()
    stock.close()

in the main function just before the for event in events

    webSocketsListener = WebSocketsListener(assistant)
    webSocketsListener.start()

With this, open a web browser and write http://127.0.0.1:8081/assistant?mode=start it will start manually the assistant like with the hotword"ok google" http://127.0.0.1:8081/assistant?mode=stop to stop the assistant if the conversation is too long http://127.0.0.1:8081/assistant?say=Hello karim how are you and then gassistPI will say what you write

Maybe can you add this functionality in your future release ?

shivasiddharth commented 6 years ago

Closing this for inactivity.

aandroide commented 6 years ago

I'm interested in your idea of ​​integrating the websocket. can you publish the whole main.py and what do you have installed?

bimbim2401 commented 6 years ago

I am working on a old gassitpi I need to update it to put my main.py but all my code is above.

alainros commented 1 year ago

Hi, Do you have an update version? I'm trying to integrate your code snippet but it crash on startup no no error log :(

Here is how I add the last part;

    if args.project_id:
        register_device(args.project_id, credentials,
                        args.device_model_id, assistant.device_id)
    webSocketsListener = WebSocketsListener(assistant)
    webSocketsListener.start()
    for event in events:
        process_event(event, assistant.device_id)