Amazon Echo의 쇼핑 목록과 Google 캘린더를 연계시켜 일용품 쇼핑을 효율화에 도전해 보았다.

계기



우리는 공동 작업으로 휴가는 그다지 일치하지 않습니다. 어느 날, 나는 휴가에서 아내가 일하고, 아내가 밤늦게 약국에 들러 쇼핑하고 돌아왔다. 아내에게 「나 휴일이니까 말해 주면 쇼핑 갔는데」라고 말하면 「다른 것 사고 오면 싫고 정확하게 전하는 것도 번거롭고」라고 말해졌습니다. 거기서
  • 쉽게 사용할 수 있습니다.
  • 또한 정확한 정보를 공유할 수 있다.

  • 구조를 만들려고 생각했습니다.

    현재의 문제점


  • 나에게 쇼핑을 시키면 다른 것을 사 오는 일이 있다(같은 브랜드의 다른 향기의 유연제라든지).
  • 그렇다고 정확하게 전하는 것은 좀처럼 귀찮다.

  • 생각한 해결책


  • Amazon Echo의 쇼핑 목록에 등록 ("Alexa, X를 쇼핑 목록에 등록하십시오.").
  • IFTTT를 사용하여 Beebotte에서 메시지(예: 쇼핑 목록에 등록된 X)를 전송합니다.
  • node-red로 Beebotte로부터의 메시지를 받는다.
  • node-red로 X에 대응한 정식 명칭, 및 제품의 URL(이번은 Amazon의 상품 페이지를 이용)을 호출한다.
  • 방금 호출한 정식 명칭, URL, 일정을 Google 캘린더에 등록.

  • 준비


  • Beebotte에 등록
  • IFTTT에 등록
  • Echo, IFTTT, Beebotte의 협력. 여기 을 참고하여 트리거에 "Amazon Alexa"의 "Item added to your Shopping List"를 선택하고 액션에 "Webhooks"의 "Make a web request"를 선택합니다.
  • node-red에 node-red-contrib-iconv , node-red-node-google 을 추가합니다.
  • Google API 사용. 여기 이전의 'node-red-node-google'에 대한 설명을 참조하여 Google API를 사용 설정합니다. 덧붙여 이번에는 Google 캘린더의 기능 밖에 사용하지 않습니다만, 「Google Calendar API」 「Directions API」 「Google+ API」의 3개를 모두 유효화하지 않으면 잘 동작하지 않았습니다.

  • 구현



    node-red에서 다음과 같이 구현해 보았습니다.

    [
        {
            "id": "f5b1471d.ab6498",
            "type": "tab",
            "label": "Alexa To Googleカレンダー",
            "disabled": false,
            "info": ""
        },
        {
            "id": "60b27da2.1831bc",
            "type": "mqtt in",
            "z": "f5b1471d.ab6498",
            "name": "",
            "topic": "To_GoogleCalandar/Voice",
            "qos": "2",
            "broker": "7f824df3.706b1c",
            "x": 115,
            "y": 25.5,
            "wires": [
                [
                    "d8645898.23e9a8"
                ]
            ]
        },
        {
            "id": "9d00040c.9916c",
            "type": "converter",
            "z": "f5b1471d.ab6498",
            "name": "ISO to UTF-8",
            "from": "UTF-8",
            "x": 376,
            "y": 26.5,
            "wires": [
                [
                    "32fec42b.9a34a4"
                ]
            ]
        },
        {
            "id": "34a60097.c3ae4",
            "type": "google calendar out",
            "z": "f5b1471d.ab6498",
            "google": "",
            "name": "買い物リスト",
            "calendar": "買い物リスト",
            "x": 564,
            "y": 229,
            "wires": [],
            "inputLabels": [
                "msg.payload"
            ]
        },
        {
            "id": "479ec6e9.0666f8",
            "type": "function",
            "z": "f5b1471d.ab6498",
            "name": "Googleカレンダー登録下処理",
            "func": "//カレンダーへ流し込むためのデータの準備\nvar csv_data = flow.get('csv_data');\nvar itmB;\nitmB = msg.payload.data.slice(1);\n//console.log(itmB);\nvar summary = csv_data[itmB][0];\nvar hiduke = new Date();\n\n//getDayは曜日、日はgetDateを使う。\nvar sy = hiduke.getFullYear();\nvar sm = hiduke.getMonth()+1;\nvar sd = hiduke.getDate();\n\n//期間は1週間(7日後)に設定する。\nhiduke.setDate(hiduke.getDate()+7);\nvar ey = hiduke.getFullYear();\nvar em = hiduke.getMonth()+1;\nvar ed = hiduke.getDate();\n\n//カレンダー登録用のJSON作成\nvar event = {\n    'summary' : summary + 'を買う。',\n    'start' : {\n        'date': sy +'-'+ sm +'-'+ sd,\n    },\n    'end' : {\n        'date' : ey + '-' + em + '-' + ed,\n    },\n    'description' : csv_data[itmB][0] + '\\n' + csv_data[itmB][1],\n}\nmsg.payload = event ;\nreturn msg;",
            "outputs": 1,
            "noerr": 0,
            "x": 427,
            "y": 162.5,
            "wires": [
                [
                    "34a60097.c3ae4"
                ]
            ]
        },
        {
            "id": "ec6fd5ba.a52ce",
            "type": "file in",
            "z": "f5b1471d.ab6498",
            "name": "買い物リスト",
            "filename": "/home/mkim/List.csv",
            "format": "lines",
            "chunk": false,
            "sendError": true,
            "x": 145,
            "y": 229.5,
            "wires": [
                [
                    "7d22551c.1d8bd4"
                ]
            ],
            "inputLabels": [
                "List.csv"
            ]
        },
        {
            "id": "d8645898.23e9a8",
            "type": "function",
            "z": "f5b1471d.ab6498",
            "name": "Data_Convert",
            "func": "//ConvertノードはBuffer型のみ受け付けるため、変換を行う。\nvar buf1 = new Buffer(msg.payload,'ascii');\nmsg.payload = buf1;\nreturn msg;",
            "outputs": 1,
            "noerr": 0,
            "x": 236,
            "y": 87.5,
            "wires": [
                [
                    "9d00040c.9916c"
                ]
            ]
        },
        {
            "id": "a18760fd.d061a",
            "type": "inject",
            "z": "f5b1471d.ab6498",
            "name": "",
            "topic": "",
            "payload": "",
            "payloadType": "date",
            "repeat": "",
            "crontab": "",
            "once": true,
            "onceDelay": "1",
            "x": 125,
            "y": 154.5,
            "wires": [
                [
                    "ec6fd5ba.a52ce"
                ]
            ]
        },
        {
            "id": "7d22551c.1d8bd4",
            "type": "function",
            "z": "f5b1471d.ab6498",
            "name": "Data_Set",
            "func": "var csv_data = flow.get('csv_data')||{};\nvar strBUY = [];\nvar strSrc = msg.payload;\nstrBUY = strSrc.split(',');\ncsv_data[strBUY[0]] = [strBUY[1],strBUY[2]];\nflow.set('csv_data',csv_data);\nreturn msg;",
            "outputs": 1,
            "noerr": 0,
            "x": 330,
            "y": 237.5,
            "wires": [
                []
            ]
        },
        {
            "id": "32fec42b.9a34a4",
            "type": "json",
            "z": "f5b1471d.ab6498",
            "name": "",
            "property": "payload",
            "action": "",
            "pretty": false,
            "x": 454,
            "y": 89.5,
            "wires": [
                [
                    "479ec6e9.0666f8"
                ]
            ]
        },
        {
            "id": "d34e8227.82dfa",
            "type": "comment",
            "z": "f5b1471d.ab6498",
            "name": "デプロイしたらInjectionをクリックし、データ更新",
            "info": "",
            "x": 225,
            "y": 295.5,
            "wires": []
        },
        {
            "id": "7f824df3.706b1c",
            "type": "mqtt-broker",
            "z": "",
            "name": "Beebotte For Google Calendar",
            "broker": "mqtt.beebotte.com",
            "port": "8883",
            "tls": "",
            "clientid": "",
            "usetls": true,
            "compatmode": false,
            "keepalive": "60",
            "cleansession": true,
            "willTopic": "",
            "willQos": "0",
            "willPayload": "",
            "birthTopic": "",
            "birthQos": "0",
            "birthPayload": ""
        }
    ]
    

    이것으로 어떻게든 움직여 주었습니다 (아마).

    힘든 곳


  • IFTTT를 사용하면 바로 할 수 있다고 생각했습니다만, 세세한 설정을 할 수 없는 데다 일본어가 깨져 버리기 때문에 힘들었습니다. 대책으로 node-red-contrib-iconv를 추가하여 문자 코드를 변환하여 무사히 표시할 수 있게 되었습니다.
  • node-red, node.js 오히려 javascript도 거의 만진 적이 없었기 때문에 처음부터 공부가 되어 힘들었습니다. 특히 형태의 개념에 대해서, javascript는 형태의 개념이 없다고 하는 잘못된 인식에 포착되어 있었으므로 문자 코드의 변환이 잘 되지 않고 고생했습니다.

  • 효과



    아직 방금 만든 아내에게는 피로하고 있지 않습니다. 어쩌면 편리하게 될 것입니다. 되면 좋다. 기뻐해 주면 좋겠다.

    마지막으로



    거의 처음부터 공부하는 것이 힘들었지만 매우 즐거웠습니다. 옛날에 비하면 편리한 것이나 정보가 많이 있어서 매우 좋은 시대가 되었다고 생각합니다.
    자신도 여러가지 곳에서 정보를 받아 몹시 신세를 졌으므로 이번의 경험이 다른 사람의 참고에 조금이라도 된다고 생각해, 잡으면서도 이 기사를 써 보았습니다.
    만약 이상한 곳이 있으면 지적해 주시면 감사하겠습니다.

    좋은 웹페이지 즐겨찾기