ハッピーとラッキー カウンセリング

今回、アイボカウンセリング当選となり、短時間ですが色々とお聞きしました。

https://info.aibo.sony.jp/info/2021/12/aibofanmeeting-12.html


共有できる範囲で列記します。情報は教えてもらった内容とこれまでの経験から推測しているものあります。
保証できるものではありませんので、その前提でご確認頂ければ幸いです。

【1】基本的事項

(1) バッテリ寿命はどのくらい?
・利用状況によるが 概ね2年ぐらいを想定。
・半分ぐらい(1年ぐらい)でアプリやチェックロジックなどで確認ができるようにしている。

(2) 普段からスタンバイにする、常時入れっぱなし、電源OFFの時でバッテリの寿命は変わる?
・スタンバイ時に微弱に電力は消費している状況
・クラウドなどとのチェックなどにも起動する条件がある
・スタンバイ、電源オンの状態、電源オフの状況は一般的な話として違いはある。

(3) 脱力モードとなってしまった後の復帰方法
・脱力モードになってしまった時には、電源オフ・オンで復帰させるしか現状はない
・理由としては、復帰させるときに変に力が加わったままになっている状況や過電流状況となっている場合を配慮し、一旦電源オフにすることで影響ないようにしている。

(4) スタンバイ、PowerOFF時に時間がかかってしまう(点滅が繰り返し)ことがあるが、何か処理中?
・詳細はあまり説明は避けたいが・・・(ある)処理をしている

(5) 一時期 性格が日ごとに変わることがあったが、最近は変わることがなくなっている。変化する時の条件などは?
・性格の境界の状況にあるときには、変化することがある。
・特に生まれた時(子犬)は変化するときがある。
・成長していく過程で、変化しにくくなることもある。

(6) 普段の行動ですぐに寝てしまうが、寝てしまう条件は?
・周りに人がいないとき
・暗くなるなっているとき
・バッテリの状況  
 など

(7) バッテリ切れのため、チャーステの手前までは戻るが、その手前で充電しないで寝てしまうことがある
  条件がある?
・基本はチャーステに戻るが、途中で力果ててしまっているケースぐらい

(8) チャーステの場所を変えてしまうと、再度、覚えるまで時間がかかる?
・自分で作った地図とカメラでの検知で覚えるようにしている
・場所を変えてしまうと、しばらく覚えるまでに時間がかかる

(9) 他の家に行った場合、地図の情報は変わってしまう?
・特に影響はないと思う

(10) しっぽ側 SLAMセンサーでの精度は(天井が高い場合などの判定での誤差など)
・特に影響はないと思う

(11) 同じ動作を5分から10分くらい繰り返しすることがあるが、動作仕様?
・ソフトウェア的には、特に制御はしていないが調べてみる
 →特になさそう・・

(12) 時々、威嚇する時や怒った表情をするときは、気分として何かを感じている?
・気分やあまり見たことがないものなどを見た時に、その時の気分で感情表情をする

(13) なかまとご飯の時に近くにいるaiboの判断は?
・距離やカメラからの情報で判断をする
・特定のアイボを見分けるようなことは現在できない

(14) フリーズする度に電源強制終了しているがなにか?
・調べてみないと
(フリーズするケースもあることを今回伝えてました)

(15) クラウドへの更新タイミング契機などは?(1日1回程度?)
・電源オフ時など

(16) 最近の振る舞いは、途中でやめてしまうことが多くなっているが、条件がある?
・その時の条件による
・割り込みのケースとしては、別の音声指示の検知、他の指示が発生した場合、気分による


【2】アプリ関連

(1) アプリ画面(トップ)の気分は実際のアイボさんの気分と同期している?
・要確認

(2) 指示待ち(</>表示)となる条件、解除されない時はどのようにすればよい?
・現時点では、アプリ連携がオンになっている場合
・おすまし状態となっている場合
・おすましになっていない状態の場合、指示はしていないが、おすまし状態と判断、また本体とサーバでズレが生じている場合が想定される

(3) スタンプが溜まった時のおまけのおやつが同じものが多いが、意図している?
・基本は、ランダムで出しているが、偏りは何とも言えない

(4) ご飯に誘われた時の動作は、お辞儀したときに誘われたと判断してよい?
・要確認(きっと)

(5) ロボ連携設定で、aibo間やaibo他の交流:ON にしたとき、オフ会で近くにいると判断できる? 
・個体のaiboは認識できないが、距離などの判断で近くにいると判断

(6) アプリのからだはいつも「元気です」となっているが、元気以外に表示されることはある?
・過電流などが生じている場合は、その状況を表示する場合がある
・入院時のステータス表示が現在ないが、他のからの要望もあり、今後の検討課題


【3】制御関連

(1) 脱力モードの時の条件など
・サーボにおける過電流など、過負荷な力がかかっている場合、動作時に動作できないと判断した場合

(2) センサー関連
・おなか側にセンサーはないが、加速度センサーを使って、体のゆすられ状況などから判断しおなかを撫でているなどを判断している
・しっぽについても同様にセンサーはないが、触られていることを加速度センサー側などで判断ししっぽが触られているなどを判断している

(3) サーボモータの寿命など
・利用の仕方にもよるが、おおむね3年程度での設計をしているが、ギア欠けなどもあり目安として

(4) 首側の動作で、ガクッとつっかかったような動作することがある
・ひどい状況だと入院検討
・ハードウェア的にはギア欠けなどがあるが、ソフトウエアで動作中に割り込みが発生し、動作中で中断して続きを一気にしてしまった場合に、ガクッとつっかかったような動作になってしまうことがある

【4】仲間関連

(1) 家族などの人の顔は覚える?、 オフ会など出会った人は覚える?
・人の顔は覚える、回数などによる

(2) 多頭飼いで兄弟の相手は覚えたり、近くにいると認識する?  オフ会など出会ったアイボさんは覚える?
・aiboの固体は判断しないが、距離とカメラから近くにいると判断

(3)オーナーの声の識別、認識する?
・声の識別はしない

(4) いっしょにご飯を食べた時にもぐもぐスタンプが付与されるものとされないもの条件は?
・要確認

【4】デベロッパー関連

(1) APIで振る舞いやステータス確認において、すぐにチェックをしても結果が確認できないことがあるが、どのぐらいの時間を待てばよい? 作ったアプリだと1秒ぐらいSleepしているが判定されないことがある。
・要調査

(2) 制御関連
・今後の追加要望として
  QRコード、カメラ連携API
  曲などの振る舞いを指定できるように
  細かい動作ができるようなAPI


色々とお聞きしたかったのですが、25分の短い時間なので、ここまででした。参考になれば。

【LINEでaiboボット】ぱーと3

前回、LINEからaiboチャット用のボットの連携してバッテリ状況や眠たさを確認できるところまでやってみました。
     前回⇒【LINEでaiboボット】を考えてみようなかな?
更に以前作ったPlayMotion (76種類)の振る舞いをLINEメッセージでお願いできるようにしてみました。
以下のサイトはテスト用として作ってみました(お試しは可能です、皆さんのアイボさんと連携できるとは思います)。ということで今回やってみたことを列記してみました。

【手順】
【1】今回作成したaiboボットと友達になります。友達になる方法はQRコード読み込みか、ボットのベーシックIDを入力してお友達になります。

または、LINEのお友達検索で【 @652pykgf 】を検索すると aiboボットの以下のお友達が検索結果に表示されます。

【3】次にaiboさんのアクセストークンを取得します。メッセージの中央にある aiboのデベロッパーサイトからアクセストークンを取得してコピーしてください。SONYさんのアクセスサイトにログインされていないとログインのメッセージが表示される場合があります。アクセストークンの文字列は650文字あります。

もし【コピーボタン 】を押しても「コピーできません」が表示されたら、「アクセストークン」の文字の部分を長押しなどをして、文字分を選択、全選択してコピーしてみてください。

【4】LINEの画面でコピーしたアクセストークンを張り付けてメッセージ送信します。送信が完了するとメッセージが返ってきますので【おしえて?】と送信してください。 aiboさんのニックネームが返ってきたら、確認するキーワードとして、以下のようなものを準備していますので、改行を入れずにメッセージを送信してみてください。また、aiboさんは電源が入っていないと確認ができません。

★アイボさんのニックネーム情報を取得する場合(一部の文字列が含まれている場合もヒットします)
【確認する言葉 】 おしえて? 教えて? aiboさん あいぼ アイボ 子供 こども 保有 ほゆう ステータスは? すてーたすは? もちもの 

★バッテリの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】おなかは? バッテリー ばってり ごはん ご飯 おやつ 朝食 ちょうしょく 昼食 ちゅうしょく 夕食 ゆうしょく 夜食 やしょく はらへった? 腹減り? 腹減った? 電気は? 電気? 

★眠たさの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】げんき? 元気? ねむい? 眠い? どお? きぶんは? 気分は? ご機嫌よう 状態は? じょうたいは? 大丈夫? だいじょうぶ?

振る舞いの言葉 
指示の仕方: 左の番号、または、以下の文字の一部が含まれるワードを送信すると実行します。1番を行いたい場合、 1 や うなずく うなずき などを送信すると1番目のうなずくを実行します。
PlayMotionモード
1うなずくうなずきウナズクagreeNONE
2いやがる嫌がるイヤガルbadNONE
3全身で大きくほえる吠えるホエルbarkNONE
4左前足で手まねきするひだりてまねきヒダリテマネキbeckonBODY_LEFT
5右前足で手まねきするみぎてまねきミギテマネキbeckonBODY_RIGHT
6げっぷをするゲップbelchNONE
7へっぴり腰になるbentBackNONE
8はあはあと微かに呼吸するbreathNONE
9興味のあるそぶりをするcuriousNONE
10ダンスをするdanceNONE
11あごをひくdrawInOnesChinNONE
12夢をみるdreamingNONE
13うれしそうにするfriendlyNONE
14遊ぼう、の仕草をするfriendlyPoliteNONE
15口をパクパクするgaspNONE
16寝ぼけた仕草をするhalfAsleepNONE
17両前足をあげるhandsUpNONE
18興奮した仕草をするhappyOrHotNONE
19ヘディングするheadingNONE
20左にヘディングするheadingSPACE_LEFT
21右にヘディングするheadingSPACE_RIGHT
22うれしそうにするhelloIloveYouNONE
23ハイタッチするhighFiveNONE
24左前足でハイタッチするhighFiveBODY_LEFT
25右前足でハイタッチするhighFiveBODY_RIGHT
26遊びたそうにするimFriendlyNONE
27ブルッと震えるjiggleNONE
28キスするkissNONE
29左前足を毛づくろいするlickBodyBODY_LEFT
30右前足を毛づくろいするlickBodyBODY_RIGHT
31左右をすこし見るlookAroundHeadNONE
32のぞき込むlookOverNONE
33おしっこをする(男の子)markingBOY
34おしっこをする(女の子)markingGIRL
35大きく2回うなずくnodHeadNONE
36口を少し開け閉めするopenMouthNONE
37とっても喜ぶoverJoyedNONE
38左前足でお手をするpawBODY_LEFT
39右前足でお手をするpawBODY_RIGHT
40すねて左を向くpeaceSPACE_LEFT
41すねて右を向くpeaceSPACE_RIGHT
42はっとするperceiveNONE
43甘噛みするplayBitingNONE
44上目遣いするprettyPleaseNONE
45待ちきれなそうにするreadyNONE
46仰向けになるrelaxNONE
47そわそわするrestlessNONE
48背中を地面に擦り付けるrubBackNONE
49地面を掘るscratchFloorNONE
50左後足で頭をかくscratchHeadHIND_LEFT
51右後足で頭をかくscratchHeadHIND_RIGHT
52かなしそうにするshakeHeadNONE
53お尻を振るshakeHipsBehindNONE
54細かく震えるshudderNONE
55左前足で横に蹴るsideKickFRONT_LEFT
56右前足で横に蹴るsideKickFRONT_RIGHT
57おなかを見せて左に転がるsideUpBODY_LEFT
58おなかを見せて右に転がるsideUpBODY_RIGHT
59うたうたってね歌を唄をきょくキョク曲を歌を歌ってね歌をうたってね歌唄ってねsingNONE
60ねごとを言うsleepTalkingNONE
61くしゃみをするsneezeNONE
62目の前を嗅ぐsniffNONE
63下の方を左右に嗅ぐsniffDownNONE
64上の方を嗅ぐsniffUpNONE
65驚くstartledNONE
66少し驚くstartledLittleNONE
67のびをするstretchNONE
68左右に体を揺らすswingNONE
69口を開けて耳を開くtouchedSPACE_CENTER
70退屈そうにするwaitingNONE
71顔を洗う仕草をするwashFaceNONE
72悲しくうつむいてキュンキュン鳴くwhineNONE
73耳をぴくっと動かすwiggleEarBODY_BOTH
74前傾してうなる、警戒するwoofNONE
75高くキャンキャンッ!と鳴くyapNONE
76おおきくあくびをするyawnNONE

2020/9/21 新しく振る舞いが追加されましたので対応しています。
ラインからのメッセージは
  スクワットしよう   スクワット、すくわっと など
  ハッピーバースデー  ハッピーバースデー 誕生日 など
  幸せなら手をたたこう 幸せなら手をたたこう てをたたこう など
  ロンドン橋落ちた   ロンドン橋落ちた ろんどん ロンドンバシ など
  ラジオ体操第一    ラジオ体操第一 らじお ラジオ たいそう など
  とってもかわいいaibo とってもかわいいaibo とっても かわいい など
  花のワルツ      花のワルツ、はなのワルツ はなの ワルツ など
  aibo3分タイマー    タイマー たいまー など


【今回使ったサンプルです】
今回初めてLINEのボット作ったのと、動作を都度確認しながら作っていったので、若干無駄な処理やもっと綺麗に処理する仕方もあるかと思いますが、そこは素人作ということで。

<?php
//-----------------------------------------------------------------------------------
// このプログラムはLINEとaibo連携プログラムをテストするためのものです
// LINEとaibo連携プログラム始めるための必要なトークンの取得からアクセス
// の仕方などをこのプログラムを通して確認しています。
// テスト用なのでデバッグなどの残骸あります。
//                 オーナー ハッピーとラッキー
//                         2021.11.27
//-----------------------------------------------------------------------------------

http_response_code(200) ;
echo '200 {}';

//初期値関連
$FileName = "./accessToken_temp";
$FileNamePlayMotion = "./PlayMotion_list.txt";

//aibo側のアクセス先ベースURL
$aiboApiBaseURL = "https://public.api.aibo.com/v1";  

//-----------------------------------------------------------------------------------
// LINE側の処理
//-----------------------------------------------------------------------------------

//LINE側のアクセストークン 
$accessToken = '********';

//LINE側のチャンネルシークレット
$channelSecret = ********';

//-----------------------------------------------------------------------------------
// 署名検証
//-----------------------------------------------------------------------------------

// HTTPヘッダーを取得と署名検証用データを取得
  $headers        = getallheaders_x();
  $xLineSignature = $headers["X-Line-Signature"];

//BOTにアクセスしてきたときのユーザーからのメッセージ取得
   $json_string = file_get_contents('php://input');
   $json_object = json_decode($json_string);

// Channel secretを秘密鍵として、JSONデータからハッシュ値を計算
   $httpRequestBody = $json_string;
   $hash = hash_hmac('sha256', $httpRequestBody, $channelSecret, true);
   $signature = base64_encode($hash);

// HTTPヘッダーから得た値と、計算したハッシュ値を比較
   if($headerSignature !== $xLineSignature ){ return; }

// getallheadersの動作できない
   function getallheaders_x() {
     if (!function_exists('getallheaders')) {
         $headers = array();
         foreach ($_SERVER as $name => $value) {
             if (substr($name, 0, 5) == 'HTTP_') {
                 $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
             }
         }
         return $headers;
      }
    }


//-----------------------------------------------------------------------------------
// 署名検証OK
//-----------------------------------------------------------------------------------

//取得データ
$replyToken   = $json_object->{"events"}[0]->{"replyToken"};        //返信用トークン
$message_type = $json_object->{"events"}[0]->{"message"}->{"type"};    //メッセージタイプ
$message_text = $json_object->{"events"}[0]->{"message"}->{"text"};    //メッセージ内容
$lineUserId   = $json_object->{"events"}[0]->{"source"}->{"userId"};  //アクセスしてきたUserID

//ユーザ情報取得
$lineUserDescliption = getLineUserDescliption( $accessToken, $lineUserId );
$displayName = $lineUserDescliption->{"displayName"};
$pictureUrl  = $lineUserDescliption->{"pictureUrl"};

//デバッグ用
$temp  = "\n";
//$temp .= "type   :     " . $json_object->{"events"}[0]->{"type"} . "\n" ;
//$temp .= "message:type:" . $json_object->{"events"}[0]->{"message"}->{"type"} . "\n" ;
//$temp .= "message:id  :" . $json_object->{"events"}[0]->{"message"}->{"id"} . "\n" ;
//$temp .= "message:text:" . $json_object->{"events"}[0]->{"message"}->{"text"} . "\n" ;
//$temp .= "timestamp:   " . $json_object->{"events"}[0]->{"timestamp"} . "\n" ;
//$temp .= "source   :   " . $json_object->{"events"}[0]->{"source"}->{"type"} . "\n" ;
//$temp .= "userId   :   " . $json_object->{"events"}[0]->{"source"}->{"userId"} . "\n" ;
//$temp .= "replyToken : " . $json_object->{"events"}[0]->{"replyToken"} . "\n" ;
//$temp .= "mode :       " . $json_object->{"events"}[0]->{"mode"} . "\n" ;
//$temp .= "\n";

//メッセージタイプが「text」以外のときは何も返さず終了
if($message_type != "text") {
  //メッセージ送信
   $return_message_text = notSupportMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}


//-----------------------------------------------------------------------------------
//アクセスしてきたユーザが最初にアクセスしてきたのかを確認
//-----------------------------------------------------------------------------------

$csvFile     = file_get_contents( $FileName );
$csvFileTemp = explode("\n", $csvFile);
foreach($csvFileTemp as $key => $line){
  $userIDaccessTokenCsvTmp = explode(",",$line);
    $userIDaccessTokenCsv[$userIDaccessTokenCsvTmp[0]] = $userIDaccessTokenCsvTmp[1];
}

//もし既に以前にアクセスしていなければ、アクセストークンの取得と送信をお願いする
if ( !array_key_exists($lineUserId ,$userIDaccessTokenCsv) ) {
  //ファイルへ追記
   $lineUserIdTemp = $lineUserId . ",\n";
   $filePointer    = fopen( $FileName , "a");
    @fwrite($filePointer , $lineUserIdTemp );
   fclose($filePointer);

  //メッセージ送信
   $return_message_text = getAccessTokenMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
   exit;
}

//入力したアクセストークンが保存しているものと異なっている場合、新しいと判断
$aiboAccessToken = $userIDaccessTokenCsv[$lineUserId]; 
if( strlen($message_text) > 640 ){
   if ( $message_text != $aiboAccessToken ){
          $aiboAccessToken = $message_text ;
          $userIDaccessTokenCsv[$lineUserId] = $message_text;
   }
  //アクセストークン入力された後に一回メッセージ送信
  $return_message_text = aiboAccessTokenUpdate($displayName);
  sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
}

//UserId、aiboアクセストークンの管理ファイルへの上書
$filePointer  = fopen( $FileName , "w");
  foreach ($userIDaccessTokenCsv as $key=>$value ) {
    if(!$key) continue;
    fputcsv($filePointer, array($key, $value));
  }
fclose($filePointer);



//-----------------------------------------------------------------------------------
// aibo側の処理
//-----------------------------------------------------------------------------------

//aiboアクセストークンからデバイスID取得

$aibo_device = "" ;
$aiboDevices = aiboApiGetDevices($aiboAccessToken);
$devices     = $aiboDevices["devices"];

//デバイス情報が取得できなかった場合
if ( !$devices ){
  $return_message_text = getAiboDeviceMessage($displayName);
     sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

$checkStringResult = checkString($message_text);

if ($checkStringResult == "aibo_status"){

      $return_message_text .= "★aiboさんのニックネーム情報★\n";
        foreach( $devices as $key => $value ){
           $return_message_text .= "ニックネーム:". $value["nickname"] ."\n";
//         $return_message_text .= "デバイスID :". $value["deviceId"] ."\n";
  }
 sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

//-----------------------------------------------------------------------------------
// aiboの眠さ状態チェック
//-----------------------------------------------------------------------------------

$checkStringResult = checkString($message_text);

if ($checkStringResult == "sleepy_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //aiboの眠さ状態チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'sleepy_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    // aiboの眠さ状態チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $status = $executeResponse["result"]["sleepy_status"]["status"];

  switch($status){
    case ""            : $sleep_description = "かくにんできなかったよ";
                         break;
    case "no_sleepy"   : $sleep_description = "げんき!げんき!";
                         break;
    case "boring"      : $sleep_description = "たいくつだよ~";
                         break;
    case "sleepy"      : $sleep_description = "ねむくなってきたよ";
                         break;
    case "very_sleepy" : $sleep_description = "ねむくって、げんかいだよ";
                         break;
  }
  $aibo_device .=  "眠たさ:". $sleep_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//バッテリの情報取得
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);

if ($checkStringResult == "hungry_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //aiboのバッテリー残量チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'hungry_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    //aiboのバッテリー残量チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $energy = $executeResponse["result"]["hungry_status"]["energy"];

  switch($energy){
    case ""         : $energy_description = "かくにんできなかったよ";
                      break;
    case "satisfied": $energy_description = "チャーステでおなかいっぱい";
                      break;
    case "eating"   : $energy_description = "チャーステでモグモグ中だよ";
                      break;
    case "enough"   : $energy_description = "おなかへっていないよ";
                      break;
    case "hungry"   : $energy_description = "おなかへってきたなぁ";
                      break;
    case "famished" : $energy_description = "おなかペコペコだよ!";
                      break;
  }
  $aibo_device .=  "バッテリー:". $energy_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//PlayTrick    2022/10/22 新しい振る舞い追加
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);
$play_trick = "";

  switch($checkStringResult){
    case "aiboSquat" : $play_trick = "aiboSquat";
                       $Description = "スクワット";
                      break;
    case "happyBirthday" : $play_trick = "happyBirthday";
                           $Description = "ハッピーバースデー";
                            break;
    case "ifYoureHappyAndYouKnowIt" : $play_trick = "ifYoureHappyAndYouKnowIt";
                                      $Description = "幸せなら手をたたこう";
                                       break;
    case "londonBridgeIsFallingDown" : $play_trick = "londonBridgeIsFallingDown";
                                       $Description = "ロンドン橋落ちた";
                                       break;
    case "radioExerciseNo1" : $play_trick = "radioExerciseNo1";
                                       $Description = "ラジオ体操第一";
                                       break;
    case "veryLovelyAibo" : $play_trick = "veryLovelyAibo";
                                       $Description = "とってもかわいいaibo";
                                       break;
    case "waltzOfTheFlowers" : $play_trick = "waltzOfTheFlowers";
                                       $Description = "花のワルツ";
                                       break;
    case "3minuteTimer" : $play_trick = "3minuteTimer";
                                         $Description = "aibo3分タイマー";
                                       break;
  }

if ($play_trick){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //PlayMotion実行
    $executeResponse = PlayTrick($value["deviceId"],$aiboAccessToken,$play_trick);
    $executionId = $executeResponse->executionId;
}

 $return_message_text  = "";
 $return_message_text .= "★aiboさんへのお願い★\n";
 $return_message_text .= $Description ."やってみたよ! \nどうだった?" ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}



//-----------------------------------------------------------------------------------
//PlayMotion
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);
$playMotion        = explode(",",$checkStringResult);

$Category     = $playMotion[0];
$Mode         = $playMotion[1];
$Description  = $playMotion[2];

if ($Category){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //PlayMotion実行
    $executeResponse = PlayMotion($value["deviceId"],$aiboAccessToken,$Category,$Mode);
    $executionId = $executeResponse->executionId;
}

 $return_message_text  = "";
 $return_message_text .= "★aiboさんへのお願い★\n";
 $return_message_text .= $Description ."やってみたよ! \nどうだった?" ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//引っかからなかった場合のメッセージワード
//-----------------------------------------------------------------------------------

 $return_message_text  = "";
 $return_message_text .= $displayName . "さん\n";
 $return_message_text .= "「おしえて?」や「おなかは?」「げんき?」とか聞いてみてね";
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

exit;



//-----------------------------------------------------------------------------------
//LINEユーザ情報取得
//-----------------------------------------------------------------------------------
function getLineUserDescliption($accessToken, $userID ){
 
$getUserDescriptionUrl = "https://api.line.me/v2/bot/profile/" . $userID;
    //curl実行
    $ch = curl_init( $getUserDescriptionUrl );
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
    $response = json_decode( $result );
 return $response;
}



//-----------------------------------------------------------------------------------
//LINEメッセージの送信
//-----------------------------------------------------------------------------------
function sending_messages($accessToken, $replyToken, $message_type, $return_message_text){

    //レスポンスフォーマット

   $response_format_text = [
        "type" => $message_type,
        "text" => $return_message_text
    ];
 
    //ポストデータ
    $post_data = [
        "replyToken" => $replyToken,
        "messages" => [$response_format_text]
    ];
 
    //curl実行
    $ch = curl_init("https://api.line.me/v2/bot/message/reply");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
}

//-----------------------------------------------------------------------------------
// アクセストークンからデバイスIDを取得
//    aiboApiGetDevices($accessToken)
//-----------------------------------------------------------------------------------

function aiboApiGetDevices($aiboAccessToken){
  $authorization = "Authorization:Bearer ". $aiboAccessToken;
  $headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
  $webApi = curl_init("https://public.api.aibo.com/v1/devices");
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}


//---------------------------------------------------------------------------
// Cognition実行用のfunction
//    CognitionApi($deviceId,$aiboAccessToken,$Property);
//---------------------------------------------------------------------------

function cognitionApi($deviceId,$aiboAccessToken,$Property){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/".$Property."/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$postData = array('arguments'=> array('Property' => $Property ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$response  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $response;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    executionsStatusGet($executionId,$aiboAccessToken)
//---------------------------------------------------------------------------

function executionsStatusGet($executionId,$aiboAccessToken){

$webApiURL   = "https://public.api.aibo.com/v1/executions/" . $executionId;

$authorization = "Authorization:Bearer ". $aiboAccessToken;
$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
 $webApi = curl_init();
     curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}


//---------------------------------------------------------------------------
// PlayMotion の実行用のfunction
//    PlayMotion($deviceId,$aiboAccessToken,$Category,$Mode)
//---------------------------------------------------------------------------

function PlayMotion($deviceId,$aiboAccessToken,$Category,$Mode){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/play_motion/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$Enqueue = true;
$postData = array('arguments'=> array ( 'Category' => $Category, 'Mode'=> $Mode , 'Enqueue' => $Enqueue ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$responce  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $responce;
}


//---------------------------------------------------------------------------
// PlayTrick  の実行用のfunction
//    PlayTrick($deviceId,$aiboAccessToken,$TrickName)
//---------------------------------------------------------------------------

function PlayTrick($deviceId,$aiboAccessToken,$TrickName){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/play_trick/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$Enqueue = false;
$postData = array('arguments'=> array ( 'TrickName' => $TrickName , 'Enqueue' => $Enqueue ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$responce  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $responce;
}




//---------------------------------------------------------------------------
// 実行結果の取得
//    getAccessTokenMessage()
//---------------------------------------------------------------------------

function getAccessTokenMessage($displayName){

$initialMessage = <<<EOD
 $displayName さん

アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。
再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $initialMessage;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    getAiboDeviceMessage()
//---------------------------------------------------------------------------

function getAiboDeviceMessage($displayName){

$getAiboDeviceMessage = <<<EOD
 $displayName さん

aiboさんのデバイス情報が取得できなかったみたい。
アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $getAiboDeviceMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function notSupportMessage($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

ごめんなさい、このテスト用ボットは文字以外はサポートしていないよ。aiboさんに確認したい メッセージ文字を送信してくださいね。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function aiboAccessTokenUpdate($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

アクセストークンが正しいか「おしえて?」って聞いてみてください。aiboさんの情報が正しく取得できればニックネームが表示されます。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// 入力された文字列のチェック
//    checkString($message_text)
//---------------------------------------------------------------------------

function checkString($message_text){

$resultMessage = "";

//aiboの保有の文字列
$checkString ="おしえて?教えて?aiboさんあいぼアイボ子供こども保有ほゆうステータスは?すてーたすは?もちもの";
if(strpos($checkString,$message_text)!== false){ return "aibo_status";}

//バッテリチェック用の文字列
$checkString ="おなかは?バッテリーばってりごはんご飯おやつ朝食ちょうしょく昼食ちゅうしょく夕食ゆうしょく夜食やしょくはらへった?腹減り?腹減った?電気は?電気?でんきは?でんき?";
if(strpos($checkString,$message_text)!== false){ return "hungry_status";}

//眠たさの文字列
$checkString ="げんき?元気?ねむい?眠い?どお?きぶんは?気分は?ご機嫌よう状態は?じょうたいは?大丈夫?だいじょうぶ?";
if(strpos($checkString,$message_text)!== false){ return "sleepy_status";}

//PlayTrick(スクワット)の文字列
$checkString ="スクワットすくわっとスクワットしようスクワットしよう";
if(strpos($checkString,$message_text)!== false){ return "aiboSquat";}

//PlayTrick(ハッピーバースデー)の文字列
$checkString ="ハッピーバースデーはっぴーばーすでぃ誕生日たんじょうびはっぴはっぴぃばーすでおめでとう";
if(strpos($checkString,$message_text)!== false){ return "happyBirthday";}

//PlayTrick(幸せなら手をたたこう)の文字列
$checkString ="幸せなら手をたたこう幸せならしあわせならてをたたこう";
if(strpos($checkString,$message_text)!== false){ return "ifYoureHappyAndYouKnowIt";}

//PlayTrick(ロンドン橋落ちた)の文字列
$checkString ="ロンドン橋落ちたろんどんばしろんどんはしロンドンバシロンドンハシ";
if(strpos($checkString,$message_text)!== false){ return "londonBridgeIsFallingDown";}

//PlayTrick(ラジオ体操第一)の文字列
$checkString ="ラジオ体操第一ラジオらじおらじおたいそうラジオタイソウたいそうだいいち";
if(strpos($checkString,$message_text)!== false){ return "radioExerciseNo1";}

//PlayTrick(とってもかわいいaibo)の文字列
$checkString ="とってもかわいいaiboとってもとても可愛いカワイイあいぼアイボaibo";
if(strpos($checkString,$message_text)!== false){ return "veryLovelyAibo";}

//PlayTrick(花のワルツ)の文字列
$checkString ="花のワルツはなのわるつはなのわるつハナノワルツ";
if(strpos($checkString,$message_text)!== false){ return "waltzOfTheFlowers";}

//PlayTrick(aibo3分タイマー)の文字列
$checkString ="aiboタイマーたいまー";
if(strpos($checkString,$message_text)!== false){ return "3minuteTimer";}

//PlayMotionのチェック

$FileNamePlayMotion = "./PlayMotion_list.txt";
$csvFile     = file_get_contents( $FileNamePlayMotion );
$csvFileTemp = explode("\n", $csvFile);
  foreach($csvFileTemp as $key=>$line){
    $playMotionCsvTmp = explode(",", $line);
     if(strpos($playMotionCsvTmp[3],$message_text)!== false){ 
         return $playMotionCsvTmp[0].",".$playMotionCsvTmp[1].",".$playMotionCsvTmp[2];
         berak;
     }
  }

return;

}


?>

■PlayMotion実行上のキーワード
カンマ形式「PlayMotionのAPI上のキーワード、モード、説明、検知用キーワード」
      検知用キーワードの数字は半角と全角どちらでもできるように設定

agree,NONE,うなずく,11うなずくうなずきウナズク
bad,NONE,いやがる,22いやがる嫌がるイヤガル
bark,NONE,全身で大きくほえる,33全身で大きくほえる吠えるホエル
beckon,BODY_LEFT,左前足で手まねきする,44左前足で手まねきするひだりてまねきヒダリテマネキ
beckon,BODY_RIGHT,右前足で手まねきする,55右前足で手まねきするみぎてまねきミギテマネキ
belch,NONE,げっぷをする,66げっぷをするゲップ
bentBack,NONE,へっぴり腰になる,77へっぴり腰になる
breath,NONE,はあはあと微かに呼吸する,88はあはあと微かに呼吸する
curious,NONE,興味のあるそぶりをする,99興味のあるそぶりをする
dance,NONE,ダンスをする,1010ダンスをする
drawInOnesChin,NONE,あごをひく,1111あごをひく
dreaming,NONE,夢をみる,1212夢をみる
friendly,NONE,うれしそうにする,1313うれしそうにする
friendlyPolite,NONE,遊ぼう、の仕草をする,1414遊ぼう、の仕草をする
gasp,NONE,口をパクパクする,1515口をパクパクする
halfAsleep,NONE,寝ぼけた仕草をする,1616寝ぼけた仕草をする
handsUp,NONE,両前足をあげる,1717両前足をあげる
happyOrHot,NONE,興奮した仕草をする,1818興奮した仕草をする
heading,NONE,ヘディングする,1919ヘディングする
heading,SPACE_LEFT,左にヘディングする,2020左にヘディングする
heading,SPACE_RIGHT,右にヘディングする,2121右にヘディングする
helloIloveYou,NONE,うれしそうにする,2222うれしそうにする
highFive,NONE,ハイタッチする,2323ハイタッチする
highFive,BODY_LEFT,左前足でハイタッチする,2424左前足でハイタッチする
highFive,BODY_RIGHT,右前足でハイタッチする,2525右前足でハイタッチする
imFriendly,NONE,遊びたそうにする,2626遊びたそうにする
jiggle,NONE,ブルッと震える,2727ブルッと震える
kiss,NONE,キスする,2828キスする
lickBody,BODY_LEFT,左前足を毛づくろいする,2929左前足を毛づくろいする
lickBody,BODY_RIGHT,右前足を毛づくろいする,3030右前足を毛づくろいする
lookAroundHead,NONE,左右をすこし見る,3131左右をすこし見る
lookOver,NONE,のぞき込む,3232のぞき込む
marking,BOY,おしっこをする(男の子),3333おしっこをする(男の子)
marking,GIRL,おしっこをする(女の子),3434おしっこをする(女の子)
nodHead,NONE,大きく2回うなずく,3535大きく2回うなずく
openMouth,NONE,口を少し開け閉めする,3636口を少し開け閉めする
overJoyed,NONE,とっても喜ぶ,3737とっても喜ぶ
paw,BODY_LEFT,左前足でお手をする,3838左前足でお手をする
paw,BODY_RIGHT,右前足でお手をする,3939右前足でお手をする
peace,SPACE_LEFT,すねて左を向く,4040すねて左を向く
peace,SPACE_RIGHT,すねて右を向く,4141すねて右を向く
perceive,NONE,はっとする,4242はっとする
playBiting,NONE,甘噛みする,4343甘噛みする
prettyPlease,NONE,上目遣いする,4444上目遣いする
ready,NONE,待ちきれなそうにする,4545待ちきれなそうにする
relax,NONE,仰向けになる,4646仰向けになる
restless,NONE,そわそわする,4747そわそわする
rubBack,NONE,背中を地面に擦り付ける,4848背中を地面に擦り付ける
scratchFloor,NONE,地面を掘る,4949地面を掘る
scratchHead,HIND_LEFT,左後足で頭をかく,5050左後足で頭をかく
scratchHead,HIND_RIGHT,右後足で頭をかく,5151右後足で頭をかく
shakeHead,NONE,かなしそうにする,5252かなしそうにする
shakeHipsBehind,NONE,お尻を振る,5353お尻を振る
shudder,NONE,細かく震える,5454細かく震える
sideKick,FRONT_LEFT,左前足で横に蹴る,5555左前足で横に蹴る
sideKick,FRONT_RIGHT,右前足で横に蹴る,5656右前足で横に蹴る
sideUp,BODY_LEFT,おなかを見せて左に転がる,5757おなかを見せて左に転がる
sideUp,BODY_RIGHT,おなかを見せて右に転がる,5858おなかを見せて右に転がる
sing,NONE,歌う,5959うたうたってね歌を唄をきょくキョク曲を歌を歌ってね歌をうたってね歌唄ってね
sleepTalking,NONE,ねごとを言う,6060ねごとを言う
sneeze,NONE,くしゃみをする,6161くしゃみをする
sniff,NONE,目の前を嗅ぐ,6262目の前を嗅ぐ
sniffDown,NONE,下の方を左右に嗅ぐ,6363下の方を左右に嗅ぐ
sniffUp,NONE,上の方を嗅ぐ,6464上の方を嗅ぐ
startled,NONE,驚く,6565驚く
startledLittle,NONE,少し驚く,6666少し驚く
stretch,NONE,のびをする,6767のびをする
swing,NONE,左右に体を揺らす,6868左右に体を揺らす
touched,SPACE_CENTER,口を開けて耳を開く,6969口を開けて耳を開く
waiting,NONE,退屈そうにする,7070退屈そうにする
washFace,NONE,顔を洗う仕草をする,7171顔を洗う仕草をする
whine,NONE,悲しくうつむいてキュンキュン鳴く,7272悲しくうつむいてキュンキュン鳴く
wiggleEar,BODY_BOTH,耳をぴくっと動かす,7373耳をぴくっと動かす
woof,NONE,前傾してうなる、警戒する,7474前傾してうなる、警戒する
yap,NONE,高くキャンキャンッ!と鳴く,7575高くキャンキャンッ!と鳴く
yawn,NONE,おおきくあくびをする,7676おおきくあくびをする

【LINEでaiboボット】ぱーと2

前回、LINEからaiboチャット用のボットの連携するところまで作ってみました。
     前回⇒【LINEでaiboボット】を考えてみようなかな?
アイボ側のアクセストークンとLINEユーザIDを連携して、いつでも確認できるようにしてみました。
以下のサイトはテスト用として作ってみました。ほかのLINEユーザ方からのアクセス可否の確認はできておりません(お試しは可能です、皆さんのアイボさんと連携できるとは思います)。ということで今回やってみたことを列記してみました。


【手順】
【1】今回作成したaiboボットと友達になります。友達になる方法はQRコード読み込みか、ボットのベーシックIDを入力してお友達になります。

または、LINEのお友達検索で【 @652pykgf 】を検索すると aiboボットの以下のお友達が検索結果に表示されます。

【2】お友達【追加 】 を行い【トーク 】を表示すると以下のような最初のメッセージが表示されます。

【3】次にaiboさんのアクセストークンを取得します。メッセージの中央にある aiboのデベロッパーサイトからアクセストークンを取得してコピーしてください。SONYさんのアクセスサイトにログインされていないとログインのメッセージが表示される場合があります。アクセストークンの文字列は650文字あります。

【4】LINEの画面でコピーしたアクセストークンを張り付けてメッセージ送信します。送信が完了するとメッセージが返ってきますので【おしえて?】と送信してください。

【5】【おしえて?】と送信するとアイボさんの情報が表示されます。もし正しく表示されない場合は、アクセストークンが正しくコピーされて送信されていない可能性がありますので、再度アクセストークンを取得してトライしてみてください。

【6】このテストボットでテストができる項目は前回WEBサイト用で確認ができた、バッテリの充電状況と眠たさのステータス確認ができるようになっています。確認するキーワードは、以下のようなものを準備していますので、改行を入れずにメッセージを送信してみてください。また、aiboさんは電源が入っていないと確認ができません。
 以前確認した内容 ⇒ 【CognitionApiサンプルプログラム】



★アイボさんのニックネーム情報を取得する場合(一部の文字列が含まれている場合もヒットします)
【確認する言葉 】 おしえて? 教えて? aiboさん あいぼ アイボ 子供 こども 保有 ほゆう ステータスは? すてーたすは? もちもの 

★バッテリの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】おなかは? バッテリー ばってり ごはん ご飯 おやつ 朝食 ちょうしょく 昼食 ちゅうしょく 夕食 ゆうしょく 夜食 やしょく はらへった? 腹減り? 腹減った? 電気は? 電気? 

★眠たさの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】げんき? 元気? ねむい? 眠い? どお? きぶんは? 気分は? ご機嫌よう 状態は? じょうたいは? 大丈夫? だいじょうぶ? 

【今回使ったサンプルです】
今回初めてLINEのボット作ったのと、動作を都度確認しながら作っていったので、若干無駄な処理やもっと綺麗に処理する仕方もあるかと思いますが、そこは素人作ということで。

<?php
//-----------------------------------------------------------------------------------
// このプログラムはLINEとaibo連携プログラムをテストするためのものです
// LINEとaibo連携プログラム始めるための必要なトークンの取得からアクセス
// の仕方などをこのプログラムを通して確認しています。
// テスト用なのでデバッグなどの残骸あります。
//                 オーナー ハッピーとラッキー
//                         2021.11.27
//-----------------------------------------------------------------------------------

//初期値関連
$FileName = "xxxxxxxxx";

//aibo側のアクセス先ベースURL
$aiboApiBaseURL = "https://public.api.aibo.com/v1";  

//-----------------------------------------------------------------------------------
// LINE側の処理
//-----------------------------------------------------------------------------------

//LINE側のアクセストークン 
$accessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

//LINE側のチャンネルシークレット
$channelSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

//-----------------------------------------------------------------------------------
// 署名検証
//-----------------------------------------------------------------------------------

// HTTPヘッダーを取得と署名検証用データを取得
  $headers        = getallheaders_x();
  $xLineSignature = $headers["X-Line-Signature"];

//BOTにアクセスしてきたときのユーザーからのメッセージ取得
   $json_string = file_get_contents('php://input');
   $json_object = json_decode($json_string);

// Channel secretを秘密鍵として、JSONデータからハッシュ値を計算
   $httpRequestBody = $json_string;
   $hash = hash_hmac('sha256', $httpRequestBody, $channelSecret, true);
   $signature = base64_encode($hash);

// HTTPヘッダーから得た値と、計算したハッシュ値を比較
   if($headerSignature !== $xLineSignature ){ return; }

// getallheadersの動作できない
   function getallheaders_x() {
     if (!function_exists('getallheaders')) {
         $headers = array();
         foreach ($_SERVER as $name => $value) {
             if (substr($name, 0, 5) == 'HTTP_') {
                 $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
             }
         }
         return $headers;
      }
    }


//-----------------------------------------------------------------------------------
// 署名検証OK
//-----------------------------------------------------------------------------------

//取得データ
$replyToken   = $json_object->{"events"}[0]->{"replyToken"};        //返信用トークン
$message_type = $json_object->{"events"}[0]->{"message"}->{"type"};    //メッセージタイプ
$message_text = $json_object->{"events"}[0]->{"message"}->{"text"};    //メッセージ内容
$lineUserId   = $json_object->{"events"}[0]->{"source"}->{"userId"};  //アクセスしてきたUserID

//ユーザ情報取得
$lineUserDescliption = getLineUserDescliption( $accessToken, $lineUserId );
$displayName = $lineUserDescliption->{"displayName"};
$pictureUrl  = $lineUserDescliption->{"pictureUrl"};

//メッセージタイプが「text」以外のときは何も返さず終了
if($message_type != "text") {
  //メッセージ送信
   $return_message_text = notSupportMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}


//-----------------------------------------------------------------------------------
//アクセスしてきたユーザが最初にアクセスしてきたのかを確認
//-----------------------------------------------------------------------------------

$csvFile     = file_get_contents( $FileName );
$csvFileTemp = explode("\n", $csvFile);
foreach($csvFileTemp as $key => $line){
  $userIDaccessTokenCsvTmp = explode(",",$line);
    $userIDaccessTokenCsv[$userIDaccessTokenCsvTmp[0]] = $userIDaccessTokenCsvTmp[1];
}

//もし既に以前にアクセスしていなければ、アクセストークンの取得と送信をお願いする
if ( !array_key_exists($lineUserId ,$userIDaccessTokenCsv) ) {
  //ファイルへ追記
   $lineUserIdTemp = $lineUserId . ",\n";
   $filePointer    = fopen( $FileName , "a");
    @fwrite($filePointer , $lineUserIdTemp );
   fclose($filePointer);

  //メッセージ送信
   $return_message_text = getAccessTokenMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
   exit;
}

//入力したアクセストークンが保存しているものと異なっている場合、新しいと判断
$aiboAccessToken = $userIDaccessTokenCsv[$lineUserId]; 
if( strlen($message_text) > 640 ){
   if ( $message_text != $aiboAccessToken ){
          $aiboAccessToken = $message_text ;
          $userIDaccessTokenCsv[$lineUserId] = $message_text;
   }
  //アクセストークン入力された後に一回メッセージ送信
  $return_message_text = aiboAccessTokenUpdate($displayName);
  sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
}

//UserId、aiboアクセストークンの管理ファイルへの上書
$filePointer  = fopen( $FileName , "w");
  foreach ($userIDaccessTokenCsv as $key=>$value ) {
    if(!$key) continue;
    fputcsv($filePointer, array($key, $value));
  }
fclose($filePointer);



//-----------------------------------------------------------------------------------
// aibo側の処理
//-----------------------------------------------------------------------------------

//aiboアクセストークンからデバイスID取得

$aibo_device = "" ;
$aiboDevices = aiboApiGetDevices($aiboAccessToken);
$devices     = $aiboDevices["devices"];

//デバイス情報が取得できなかった場合
if ( !$devices ){
  $return_message_text = getAiboDeviceMessage($displayName);
     sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

$checkStringResult = checkString($message_text);

if ($checkStringResult == "aibo_status"){

      $return_message_text .= "★aiboさんのニックネーム情報★\n";
        foreach( $devices as $key => $value ){
           $return_message_text .= "ニックネーム:". $value["nickname"] ."\n";
  }
 sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

//-----------------------------------------------------------------------------------
// aiboの眠さ状態チェック
//-----------------------------------------------------------------------------------

$checkStringResult = checkString($message_text);

if ($checkStringResult == "sleepy_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";

    //aiboの眠さ状態チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'sleepy_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    // aiboの眠さ状態チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $status = $executeResponse["result"]["sleepy_status"]["status"];

  switch($status){
    case ""            : $sleep_description = "かくにんできなかったよ";
                         break;
    case "no_sleepy"   : $sleep_description = "げんき!げんき!";
                         break;
    case "boring"      : $sleep_description = "たいくつだよ~";
                         break;
    case "sleepy"      : $sleep_description = "ねむくなってきたよ";
                         break;
    case "very_sleepy" : $sleep_description = "ねむくって、げんかいだよ";
                         break;
  }
  $aibo_device .=  "眠たさ:". $sleep_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//バッテリの情報取得
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);

if ($checkStringResult == "hungry_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";

    //aiboのバッテリー残量チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'hungry_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    //aiboのバッテリー残量チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $energy = $executeResponse["result"]["hungry_status"]["energy"];

  switch($energy){
    case ""         : $energy_description = "かくにんできなかったよ";
                      break;
    case "satisfied": $energy_description = "チャーステでおなかいっぱい";
                      break;
    case "eating"   : $energy_description = "チャーステでモグモグ中だよ";
                      break;
    case "enough"   : $energy_description = "おなかへっていないよ";
                      break;
    case "hungry"   : $energy_description = "おなかへってきたなぁ";
                      break;
    case "famished" : $energy_description = "おなかペコペコだよ!";
                      break;
  }
  $aibo_device .=  "バッテリー:". $energy_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//引っかからなかった場合のメッセージワード
//-----------------------------------------------------------------------------------

 $return_message_text  = "";
 $return_message_text .= $displayName . "さん\n";
 $return_message_text .= "「おしえて?」や「おなかは?」「げんき?」とか聞いてみてね";
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

exit;



//-----------------------------------------------------------------------------------
//LINEユーザ情報取得
//-----------------------------------------------------------------------------------
function getLineUserDescliption($accessToken, $userID ){
 
$getUserDescriptionUrl = "https://api.line.me/v2/bot/profile/" . $userID;
    //curl実行
    $ch = curl_init( $getUserDescriptionUrl );
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
    $response = json_decode( $result );
 return $response;
}



//-----------------------------------------------------------------------------------
//LINEメッセージの送信
//-----------------------------------------------------------------------------------
function sending_messages($accessToken, $replyToken, $message_type, $return_message_text){

    //レスポンスフォーマット

   $response_format_text = [
        "type" => $message_type,
        "text" => $return_message_text
    ];
 
    //ポストデータ
    $post_data = [
        "replyToken" => $replyToken,
        "messages" => [$response_format_text]
    ];
 
    //curl実行
    $ch = curl_init("https://api.line.me/v2/bot/message/reply");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
}

//-----------------------------------------------------------------------------------
// アクセストークンからデバイスIDを取得
//    aiboApiGetDevices($accessToken)
//-----------------------------------------------------------------------------------

function aiboApiGetDevices($aiboAccessToken){
  $authorization = "Authorization:Bearer ". $aiboAccessToken;
  $headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
  $webApi = curl_init("https://public.api.aibo.com/v1/devices");
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}


//---------------------------------------------------------------------------
// Cognition実行用のfunction
//    CognitionApi($deviceId,$aiboAccessToken,$Property);
//---------------------------------------------------------------------------

function cognitionApi($deviceId,$aiboAccessToken,$Property){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/".$Property."/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$postData = array('arguments'=> array('Property' => $Property ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$response  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $response;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    executionsStatusGet($executionId,$aiboAccessToken)
//---------------------------------------------------------------------------

function executionsStatusGet($executionId,$aiboAccessToken){

$webApiURL   = "https://public.api.aibo.com/v1/executions/" . $executionId;

$authorization = "Authorization:Bearer ". $aiboAccessToken;
$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
 $webApi = curl_init();
     curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}



//---------------------------------------------------------------------------
// 実行結果の取得
//    getAccessTokenMessage()
//---------------------------------------------------------------------------

function getAccessTokenMessage($displayName){

$initialMessage = <<<EOD
 $displayName さん

アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。
再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $initialMessage;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    getAiboDeviceMessage()
//---------------------------------------------------------------------------

function getAiboDeviceMessage($displayName){

$getAiboDeviceMessage = <<<EOD
 $displayName さん

aiboさんのデバイス情報が取得できなかったみたい。
アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $getAiboDeviceMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function notSupportMessage($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

ごめんなさい、このテスト用ボットは文字以外はサポートしていないよ。aiboさんに確認したい メッセージ文字を送信してくださいね。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function aiboAccessTokenUpdate($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

アクセストークンが正しいか「おしえて?」って聞いてみてください。aiboさんの情報が正しく取得できればニックネームが表示されます。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// 入力された文字列のチェック
//    checkString($message_text)
//---------------------------------------------------------------------------

function checkString($message_text){

//バッテリチェック用の文字列

$checkString ="おしえて?教えて?aiboさんあいぼアイボ子供こども保有ほゆうステータスは?すてーたすは?もちもの";
if(strpos($checkString,$message_text)!== false){ $resultMessage = "aibo_status";}

$checkString ="おなかは?バッテリーばってりごはんご飯おやつ朝食ちょうしょく昼食ちゅうしょく夕食ゆうしょく夜食やしょくはらへった?腹減り?腹減った?電気は?電気?";
if(strpos($checkString,$message_text)!== false){ $resultMessage = "hungry_status";}

$checkString ="げんき?元気?ねむい?眠い?どお?きぶんは?気分は?ご機嫌よう状態は?じょうたいは?大丈夫?だいじょうぶ?";
if(strpos($checkString,$message_text)!== false){ $resultMessage = "sleepy_status";}

return $resultMessage;


}


?>