Cozmo人工智慧機器人SDK使用筆記(9)-判斷部分if_this_then_that

zhangrelay發表於2019-01-28

Cozmo判斷部分有3個主題:

  1. gmail
  2. sport
  3. stock

1. gmail

此示例演示瞭如何使用“If This Then That”(http://ifttt.com)使Cozmo在Gmail帳戶收到電子郵件時作出迴應。以下說明將引導您在IFTTT網站上設定小程式。當呼叫applet觸發器(傳送在此示例中啟動的Web伺服器收到的Web請求)時,Cozmo將播放動畫,說出電子郵件發件人的姓名並在他的臉上顯示郵箱影象。

If This Then That" Gmail example

This example demonstrates how "If This Then That" (http://ifttt.com) can be used
make Cozmo respond when a Gmail account receives an email. Instructions below
will lead you through setting up an applet on the IFTTT website. When the applet
trigger is called (which sends a web request received by the web server started
in this example), Cozmo will play an animation, speak the email sender's name and
show a mailbox image on his face.

Please place Cozmo on the charger for this example. When necessary, he will be
rolled off and back on.

Follow these steps to set up and run the example:
    1) Provide a a static ip, URL or similar that can be reached from the If This
        Then That server. One easy way to do this is with ngrok, which sets up
        a secure tunnel to localhost running on your machine.

        To set up ngrok:
        a) Follow instructions here to download and install:
            https://ngrok.com/download
        b) Run this command to create a secure public URL for port 8080:
            ./ngrok http 8080
        c) Note the HTTP forwarding address shown in the terminal (e.g., http://55e57164.ngrok.io).
            You will use this address in your applet, below.

        WARNING: Using ngrok exposes your local web server to the internet. See the ngrok
        documentation for more information: https://ngrok.com/docs

    2) Set up your applet on the "If This Then That" website.
        a) Sign up and sign into https://ifttt.com
        b) Create an applet: https://ifttt.com/create
        c) Set up your trigger.
            1. Click "this".
            2. Select "Gmail" as your service. If prompted, click "Connect",
                select your Gmail account, and click “Allow” to provide permissions
                to IFTTT for your email account. Click "Done".
            3. Under "Choose a Trigger", select “Any new email in inbox".
        d) Set up your action.
            1. Click “that".
            2. Select “Maker Webhooks" to set it as your action channel. Connect to the Maker channel if prompted.
            3. Click “Make a web request" and fill out the fields as follows. Remember your publicly
                accessible URL from above (e.g., http://55e57164.ngrok.io) and use it in the URL field,
                followed by "/iftttGmail" as shown below:

                 URL: http://55e57164.ngrok.io/iftttGmail
                 Method: POST
                 Content Type: application/json
                 Body: {"FromAddress":"{{FromAddress}}"}

            5. Click “Create Action" then “Finish".

    3) Test your applet.
        a) Run this script at the command line: ./ifttt_gmail.py
        b) On ifttt.com, on your applet page, click “Check now”. See that IFTTT confirms that the applet
            was checked.
        c) Send an email to the Gmail account in your recipe
        d) On your IFTTT applet webpage, again click “Check now”. This should cause IFTTT to detect that
            the email was received and send a web request to the ifttt_gmail.py script.
        e) In response to the ifttt web request, Cozmo should roll off the charger, raise and lower
            his lift, announce the email, and then show a mailbox image on his face.

import asyncio
import re
import sys


try:
    from aiohttp import web
except ImportError:
    sys.exit("Cannot import from aiohttp. Do `pip3 install --user aiohttp` to install")

import cozmo

from common import IFTTTRobot


app = web.Application()


async def serve_gmail(request):
    '''Define an HTTP POST handler for receiving requests from If This Then That.

    You may modify this method to change how Cozmo reacts to the email
    being received.
    '''

    json_object = await request.json()

    # Extract the name of the email sender.
    from_email_address = json_object["FromAddress"]

    # Use a regular expression to break apart pieces of the email address
    match_object = re.search(r'([\w.]+)@([\w.]+)', from_email_address)
    email_local_part = match_object.group(1)

    robot = request.app['robot']
    async def read_name():
        try:
            async with robot.perform_off_charger():
                '''If necessary, Move Cozmo's Head and Lift to make it easy to see Cozmo's face.'''
                await robot.get_in_position()

                # First, have Cozmo play an animation
                await robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeStartled).wait_for_completed()

                # Next, have Cozmo speak the name of the email sender.
                await robot.say_text("Email from " + email_local_part).wait_for_completed()

                # Last, have Cozmo display an email image on his face.
                robot.display_image_file_on_face("../face_images/ifttt_gmail.png")

        except cozmo.RobotBusy:
            cozmo.logger.warning("Robot was busy so didn't read email address: "+ from_email_address)

    # Perform Cozmo's task in the background so the HTTP server responds immediately.
    asyncio.ensure_future(read_name())

    return web.Response(text="OK")

# Attach the function as an HTTP handler.
app.router.add_post('/iftttGmail', serve_gmail)


if __name__ == '__main__':
    cozmo.setup_basic_logging()
    cozmo.robot.Robot.drive_off_charger_on_connect = False

    # Use our custom robot class with extra helper methods
    cozmo.conn.CozmoConnection.robot_factory = IFTTTRobot

    try:
        app_loop = asyncio.get_event_loop()  
        sdk_conn = cozmo.connect_on_loop(app_loop)

        # Wait for the robot to become available and add it to the app object.
        app['robot'] = app_loop.run_until_complete(sdk_conn.wait_for_robot())
    except cozmo.ConnectionError as e:
        sys.exit("A connection error occurred: %s" % e)

    web.run_app(app)

2. sport

此示例演示瞭如何使用“If This Then That”(http://ifttt.com)使Cozmo在您指定的團隊進行遊戲內或最終分數更新時做出響應。 以下說明將引導您在IFTTT網站上設定小程式。 當呼叫applet觸發器(傳送在此示例中啟動的Web伺服器接收的Web請求)時,Cozmo將播放動畫,在他的臉上顯示影象,並說出遊戲內更新。

If This Then That" sports example

This example demonstrates how "If This Then That" (http://ifttt.com) can be used
make Cozmo respond when there is an in-game or final score update for the team
you specify. Instructions below will lead you through setting up an applet on
the IFTTT website. When the applet trigger is called (which sends a web request
received by the web server started in this example), Cozmo will play an animation,
show an image on his face, and speak the in-game update.

Please place Cozmo on the charger for this example. When necessary, he will be
rolled off and back on.

Follow these steps to set up and run the example:
    1) Provide a a static ip, URL or similar that can be reached from the "If This
        Then That" server. One easy way to do this is with ngrok, which sets up
        a secure tunnel to localhost running on your machine.

        To set up ngrok:
        a) Follow instructions here to download and install:
            https://ngrok.com/download
        b) Run this command to create a secure public URL for port 8080:
            ./ngrok http 8080
        c) Note the HTTP forwarding address shown in the terminal (e.g., http://55e57164.ngrok.io).
            You will use this address in your applet, below.

        WARNING: Using ngrok exposes your local web server to the internet. See the ngrok
        documentation for more information: https://ngrok.com/docs

    2) Set up your applet on the "If This Then That" website.
        a) Sign up and sign into https://ifttt.com
        b) Create an applet: https://ifttt.com/create
        c) Set up your trigger.
            1. Click "this".
            2. Select "ESPN" as your service.
            3. Under "Choose a Trigger", select “New in-game update".
            4. In section "Complete Trigger Fields", enter your sport and team and click “Create Trigger".

        d) Set up your action.
            1. Click “that".
            2. Select “Maker Webhooks" to set it as your action channel. Connect to the Maker channel if prompted.
            3. Click “Make a web request" and fill out the fields as follows. Remember your publicly
                accessible URL from above (e.g., http://55e57164.ngrok.io) and use it in the URL field,
                followed by "/iftttSports" as shown below:

                 URL: http://55e57164.ngrok.io/iftttSports
                 Method: POST
                 Content Type: application/json
                 Body: {"AlertBody":"{{AlertBody}}"}

            5. Click “Create Action" then “Finish".

    3) Test your applet.
        a) Run this script at the command line: ./ifttt_sports.py
        b) On ifttt.com, on your applet page, click “Check now”. See that IFTTT confirms that the applet
            was checked.
        c) Wait for new in-game updates for your team and see Cozmo react! Cozmo should roll off the charger, raise
            and lower his lift, show an image on his face and speak the in-game update.

import asyncio
import sys


try:
    from aiohttp import web
except ImportError:
    sys.exit("Cannot import from aiohttp. Do `pip3 install --user aiohttp` to install")

import cozmo

from common import IFTTTRobot


app = web.Application()


async def serve_sports(request):
    '''Define an HTTP POST handler for receiving requests from If This Then That.

    You may modify this method to change how Cozmo reacts to
    an in-game update from IFTTT.
    '''

    json_object = await request.json()

    # Extract the text for the in-game update.
    alert_body = json_object["AlertBody"]

    robot = request.app['robot']
    async def read_name():
        try:
            async with robot.perform_off_charger():
                '''If necessary, Move Cozmo's Head and Lift to make it easy to see Cozmo's face.'''
                await robot.get_in_position()

                # First, have Cozmo play an animation
                await robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeStartled).wait_for_completed()

                # Next, have Cozmo speak the text from the in-game update.
                await robot.say_text(alert_body).wait_for_completed()

                # Last, have Cozmo display a sports image on his face.
                robot.display_image_file_on_face("../face_images/ifttt_sports.png")

        except cozmo.RobotBusy:
            cozmo.logger.warning("Robot was busy so didn't read update: '" + alert_body +"'")

    # Perform Cozmo's task in the background so the HTTP server responds immediately.
    asyncio.ensure_future(read_name())

    return web.Response(text="OK")

# Attach the function as an HTTP handler.
app.router.add_post('/iftttSports', serve_sports)


if __name__ == '__main__':
    cozmo.setup_basic_logging()
    cozmo.robot.Robot.drive_off_charger_on_connect = False

    # Use our custom robot class with extra helper methods
    cozmo.conn.CozmoConnection.robot_factory = IFTTTRobot

    try:
        app_loop = asyncio.get_event_loop()  
        sdk_conn = cozmo.connect_on_loop(app_loop)

        # Wait for the robot to become available and add it to the app object.
        app['robot'] = app_loop.run_until_complete(sdk_conn.wait_for_robot())
    except cozmo.ConnectionError as e:
        sys.exit("A connection error occurred: %s" % e)

    web.run_app(app)

 


此IFTTT示例使用Flask Web框架並且是同步的,與其他非同步的IFTTT示例不同並使用aiohttp。在此示例中,IFTTT Web請求由函式receive_ifttt_web_request接收。進入該方法的每個Web請求都會新增到Queue ifttt_queue,並且HTTP狀態程式碼200或503會立即返回到IFTTT。該佇列由worker函式檢查,該函式在後臺執行緒上執行(由run函式啟動)。當worker函式在佇列中找到新請求時,請求將從佇列中刪除並在方法then_that_action中處理。

與ifttt_sports.py示例一樣,此示例演示瞭如何使用“If This Then That”(http://ifttt.com)使Cozmo在您指定的團隊有遊戲內或最終得分更新時做出響應。以下說明將引導您完成設定
在IFTTT網站上釋出一個applet。當呼叫applet觸發器(傳送在此示例中啟動的燒瓶伺服器接收的Web請求)時,Cozmo將播放動畫,在他的臉上顯示影象,並說出遊戲內更新。

If This Then That" sports example

This IFTTT example uses the Flask web framework and is synchronous, unlike the other
IFTTT examples which are asynchronous and use aiohttp. In this example, IFTTT web
requests are received by function receive_ifttt_web_request. Each web request that comes
into that method is added to Queue ifttt_queue and an HTTP status code of 200 or 503 is
immediately returned to IFTTT. The queue is checked by the worker function, which is
running on a background thread (started by the run function). When a new request is
found on the queue by the worker function, the request is removed from the queue and
processed in method then_that_action.

Like the ifttt_sports.py example, this example demonstrates how "If This Then That"
(http://ifttt.com) can be used make Cozmo respond when there is an in-game or final
score update for the team you specify. Instructions below will lead you through setting
up an applet on the IFTTT website. When the applet trigger is called (which sends a web
request received by the flask server started in this example), Cozmo will play an
animation, show an image on his face, and speak the in-game update.

Please place Cozmo on the charger for this example. When necessary, he will be
rolled off and back on.

Follow these steps to set up and run the example:
    1) Provide a a static ip, URL or similar that can be reached from the "If This
        Then That" server. One easy way to do this is with ngrok, which sets up
        a secure tunnel to localhost running on your machine.

        To set up ngrok:
        a) Follow instructions here to download and install:
            https://ngrok.com/download
        b) Run this command to create a secure public URL for port 8080:
            ./ngrok http 8080
        c) Note the HTTP forwarding address shown in the terminal (e.g., http://55e57164.ngrok.io).
            You will use this address in your applet, below.

        WARNING: Using ngrok exposes your local web server to the internet. See the ngrok
        documentation for more information: https://ngrok.com/docs

    2) Set up your applet on the "If This Then That" website.
        a) Sign up and sign into https://ifttt.com
        b) Create an applet: https://ifttt.com/create
        c) Set up your trigger.
            1. Click "this".
            2. Select "ESPN" as your service.
            3. Under "Choose a Trigger", select “New in-game update".
            4. In section "Complete Trigger Fields", enter your sport and team and click “Create Trigger".

        d) Set up your action.
            1. Click “that".
            2. Select “Maker" to set it as your action channel. Connect to the Maker channel if prompted.
            3. Click “Make a web request" and fill out the fields as follows. Remember your publicly
                accessible URL from above (e.g., http://55e57164.ngrok.io) and use it in the URL field,
                followed by "/iftttSports" as shown below:

                 URL: http://55e57164.ngrok.io/iftttSports
                 Method: POST
                 Content Type: application/json
                 Body: {"AlertBody":"{{AlertBody}}"}

            5. Click “Create Action" then “Finish".

    3) Test your applet.
        a) Run this script at the command line: ./ifttt_sports.py
        b) On ifttt.com, on your applet page, click “Check now”. See that IFTTT confirms that the applet
            was checked.
        c) Wait for new in-game updates for your team and see Cozmo react! Cozmo should roll off the charger, raise
            and lower his lift, show an image on his face and speak the in-game update.

import json
import queue
import sys
import threading

import cozmo
sys.path.append('../lib/')
import flask_helpers

from common import IFTTTRobot


try:
    from flask import Flask, request
except ImportError:
    sys.exit("Cannot import from flask: Do `pip3 install --user flask` to install")


flask_app = Flask(__name__)
ifttt_queue = queue.Queue()
robot = None


@flask_app.route('/iftttSports', methods=['POST'])
def receive_ifttt_web_request():
    '''Web request endpoint named "iftttSports" for IFTTT to call when a new in-game
        update for your team is posted on ESPN.

        In the IFTTT web request, in the URL field, specify this method
        as the endpoint. For instance, if your public url is http://my.url.com,
        then in the IFTTT web request URL field put the following:
        http://my.url.com/iftttSports. Then, this endpoint will be called when
        IFTTT checks and discovers that a new in-game update for your team is
        posted on ESPN.
    '''

    # Retrieve the data passed by If This Then That in the web request body.
    json_object = json.loads(request.data.decode("utf-8"))

    # Extract the text for the in-game update.
    alert_body = json_object["AlertBody"]

    # Add this request to the queue of in-game updates awaiting Cozmo's reaction.
    ifttt_queue.put((then_that_action, alert_body))

    # Return promptly so If This Then That knows that the web request was received
    # successfully.
    return ""


def then_that_action(alert_body):
    '''Controls how Cozmo responds to the in-game update.

    You may modify this method to change how Cozmo reacts to
    the update from IFTTT.
    '''

    try:
        with robot.perform_off_charger():
            '''If necessary, Move Cozmo's Head and Lift to make it easy to see Cozmo's face.'''
            robot.get_in_position()

            # First, have Cozmo play an animation
            robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeStartled).wait_for_completed()

            # Next, have Cozmo speak the text from the in-game update.
            robot.say_text(alert_body).wait_for_completed()

            # Last, have Cozmo display a sports image on his face.
            robot.display_image_file_on_face("../face_images/ifttt_sports.png")

    except cozmo.exceptions.RobotBusy:
        pass


def worker():
    while True:
        item = ifttt_queue.get()
        if item is None:
            break
        queued_action, action_args = item
        queued_action(action_args)


def run(sdk_conn):
    global robot
    robot = sdk_conn.wait_for_robot()

    threading.Thread(target=worker).start()

    # Start flask web server so that /iftttSports can serve as endpoint.
    flask_helpers.run_flask(flask_app, "127.0.0.1", 8080, False, False)

    # Putting None on the queue stops the thread. This is called when the
    # user hits Control C, which stops the run_flask call.
    ifttt_queue.put(None)


if __name__ == '__main__':
    cozmo.setup_basic_logging()
    cozmo.robot.Robot.drive_off_charger_on_connect = False

    # Use our custom robot class with extra helper methods
    cozmo.conn.CozmoConnection.robot_factory = IFTTTRobot

    try:
        cozmo.connect(run)
    except cozmo.ConnectionError as e:
        sys.exit("A connection error occurred: %s" % e)

3. stock

此示例演示瞭如何使用“If This Then That”(http://ifttt.com)使Cozmo在股票程式碼符號增加1%或更多時作出響應。 以下說明將引導您在IFTTT網站上設定小程式。 當呼叫applet觸發器(傳送在此示例中啟動的Web伺服器接收的Web請求)時,Cozmo將播放動畫,說出公司名稱和增加的百分比,並在他的臉上顯示股票市場影象。

If This Then That" Stock example

This example demonstrates how "If This Then That" (http://ifttt.com) can be used
make Cozmo respond when a stock ticker symbol increases by 1% or more. Instructions
below will lead you through setting up an applet on the IFTTT website. When the applet
trigger is called (which sends a web request received by the web server started
in this example), Cozmo will play an animation, speak the company name and the
percentage increase, and show a stock market image on his face.

Please place Cozmo on the charger for this example. When necessary, he will be
rolled off and back on.

Follow these steps to set up and run the example:
    1) Provide a a static ip, URL or similar that can be reached from the If This
        Then That server. One easy way to do this is with ngrok, which sets up
        a secure tunnel to localhost running on your machine.

        To set up ngrok:
        a) Follow instructions here to download and install:
            https://ngrok.com/download
        b) Run this command to create a secure public URL for port 8080:
            ./ngrok http 8080
        c) Note the HTTP forwarding address shown in the terminal (e.g., http://55e57164.ngrok.io).
            You will use this address in your applet, below.

        WARNING: Using ngrok exposes your local web server to the internet. See the ngrok
        documentation for more information: https://ngrok.com/docs

    2) Set up your applet on the "If This Then That" website.
        a) Sign up and sign into https://ifttt.com
        b) Create an applet: https://ifttt.com/create
        c) Set up your trigger.
            1. Click "this".
            2. Select "Stocks" as your service.
            3. Under "Choose a Trigger", select “Today's price rises by percentage".
            4. In section "Complete Trigger Fields", enter your ticker symbol and desired percentage,
                for instance:

                Ticker symbol: HOG
                Percentage increase: 1

            5. Click “Create Trigger".

        d) Set up your action.
            1. Click “that".
            2. Select “Maker Webhooks" to set it as your action channel. Connect to the Maker channel if prompted.
            3. Click “Make a web request" and fill out the fields as follows. Remember your publicly
                accessible URL from above (e.g., http://55e57164.ngrok.io) and use it in the URL field,
                followed by "/iftttStocks" as shown below:

                 URL: http://55e57164.ngrok.io/iftttStocks
                 Method: POST
                 Content Type: application/json
                 Body: {"PercentageChange":"{{PercentageChange}}","StockName":"{{StockName}}"}

            5. Click “Create Action" then “Finish".

    3) Test your applet.
        a) Run this script at the command line: ./ifttt_stocks.py
        b) On ifttt.com, on your applet page, click “Check now”. See that IFTTT confirms that the applet
            was checked.
        c) Wait for your stock to increase and see Cozmo react! Cozmo should roll off the charger, raise
            and lower his lift, announce the stock increase, and then show a stock market image on his face.

import asyncio
import sys


try:
    from aiohttp import web
except ImportError:
    sys.exit("Cannot import from aiohttp. Do `pip3 install --user aiohttp` to install")

import cozmo

from common import IFTTTRobot


app = web.Application()


async def serve_stocks(request):
    '''Define an HTTP POST handler for receiving requests from If This Then That.

    Controls how Cozmo responds to stock notification. You may modify this method
    to change how Cozmo reacts to the stock price increasing.
    '''

    json_object = await request.json()

    # Extract the company name for the stock ticker symbol.
    stock_name = json_object["StockName"]

    # Extract the percentage increase.
    percentage = str(json_object["PercentageChange"])

    robot = request.app['robot']
    async def read_name():
        try:
            async with robot.perform_off_charger():
                '''If necessary, Move Cozmo's Head and Lift to make it easy to see Cozmo's face.'''
                await robot.get_in_position()

                # First, have Cozmo play an animation
                await robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeStartled).wait_for_completed()

                # Next, have Cozmo say that your stock is up by x percent.
                await robot.say_text(stock_name + " is up " + percentage + " percent").wait_for_completed()

                # Last, have Cozmo display a stock market image on his face.
                robot.display_image_file_on_face("../face_images/ifttt_stocks.png")

        except cozmo.RobotBusy:
            cozmo.logger.warning("Robot was busy so didn't read stock update: '"+ stock_name + " is up " + percentage + " percent'.")

    # Perform Cozmo's task in the background so the HTTP server responds immediately.
    asyncio.ensure_future(read_name())

    return web.Response(text="OK")

# Attach the function as an HTTP handler.
app.router.add_post('/iftttStocks', serve_stocks)


if __name__ == '__main__':
    cozmo.setup_basic_logging()
    cozmo.robot.Robot.drive_off_charger_on_connect = False

    # Use our custom robot class with extra helper methods
    cozmo.conn.CozmoConnection.robot_factory = IFTTTRobot

    try:
        app_loop = asyncio.get_event_loop()  
        sdk_conn = cozmo.connect_on_loop(app_loop)

        # Wait for the robot to become available and add it to the app object.
        app['robot'] = app_loop.run_until_complete(sdk_conn.wait_for_robot())
    except cozmo.ConnectionError as e:
        sys.exit("A connection error occurred: %s" % e)

    web.run_app(app)

Fin


 

相關文章