Open13

obnizまとめハッカソン用

okinaka masayoshiokinaka masayoshi

事前にやる

npm init -y を実行し、Node.jsプロジェクトとして初期化
npm i obniz obnizパッケージのインストール

okinaka masayoshiokinaka masayoshi

間隔をあけて温度を表示 型番が上

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID');  // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    obniz.display.clear();
    obniz.display.print('Hello obniz!');

    // Javascript Example
    const tempsens = obniz.wired('LM60', { gnd: 0, output: 1, vcc: 2 });
    // setIntervalで間隔を作る
    setInterval(async function () {
        // 同期で取得
        const temp = await tempsens.getWait();
        // 温度をコンソールに表示
        console.log(temp);
        // displayに反映
        obniz.display.clear();
        obniz.display.print(temp + 'C');  // 英語が出力できる
    }, 1000); // 1000ミリ秒 = 1秒
}

JavaScriptでは、一定間隔での繰り返しを
setInterval(繰り返したい関数, ミリ秒間隔);
で行うことが非常に多いので覚えておきましょう。

// 実際には、繰り返したい関数をわざわざ定義するのも面倒なので
// 次のような「即時関数」がよく利用されます。
setInterval(
    function() {
        // この中に繰り返したい処理を書く
    }
, 1000); // 1000ms間隔で繰り返す
okinaka masayoshiokinaka masayoshi

スピーカー

altテキスト
https://obniz.io/ja/sdk/parts/Speaker/README.md

スイッチ押した時だけ音

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // スピーカーを利用
    const speaker = obniz.wired('Speaker', { signal: 0, gnd: 1 });

    // ディスプレイ表示
    obniz.display.clear();
    obniz.display.print('Speaker test');

    // スイッチの反応を常時監視
    // 「スイッチ状態が変化した瞬間に1回だけ実行される」ことに注意しましょう
    obniz.switch.onchange = function (state) {
        if (state === 'push') {
            // スイッチが押されている状態
            obniz.display.clear();
            obniz.display.print('beep!');
            // 1000Hz で音を鳴らす
            speaker.play(1000);
        } else if (state === 'none') {
            // スイッチが押されていない状態
            obniz.display.clear();
            obniz.display.print('silent');
            // 音を停止する
            speaker.stop();
        }
    }
}

時報

const Obniz = require('obniz');
const { exit } = require('process');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

// 任意の秒数待つことができる関数
// 参考: https://qiita.com/suin/items/99aa8641d06b5f819656
const sleep = (msec) => new Promise(res => setTimeout(res, msec));

// obnizが接続済み
obniz.onconnect = async function () {
    // スピーカーを利用
    const speaker = obniz.wired('Speaker', { signal: 0, gnd: 1 });

    // ポッ↓
    speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
    // ポッ↓
    speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
    // ポッ↓
    speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
    // ポ~~~ン↑
    speaker.play(1000); await sleep(1000); speaker.stop();
    // Ctrl+C を打たなくても自動で終了します
    exit();
}

半音ずつ音階を指定して音を鳴らす

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

// MIDIノート番号から実際の周波数に変換する
function getFrequency(note_number) {
    // http://www.asahi-net.or.jp/~HB9T-KTD/music/Japan/Research/DTM/freq_map.html
    return Math.round(440 * (2 ** ((note_number - 69) / 12)));
}

// obnizが接続済み
obniz.onconnect = async function () {
    // スピーカーを利用
    const speaker = obniz.wired('Speaker', { signal: 0, gnd: 1 });
    // MIDIノート番号
    let note_number = 72;
    // 現在の周波数
    let freq = 523;

    // ディスプレイ表示
    obniz.display.clear();
    obniz.display.print('Musical Scale');

    // スイッチの反応を常時監視
    obniz.switch.onchange = function (state) {
        // 画面クリア
        obniz.display.clear();

        if (state === 'push') {
            // スイッチが押されている状態
            speaker.play(freq); // 音を鳴らす
        } else if (state === 'right') {
            // 右にスイッチを倒したとき
            if (note_number < 127) note_number++; // ノート番号+1
            freq = getFrequency(note_number); // 周波数を再計算
        } else if (state === 'left') {
            // 左にスイッチを倒したとき
            if (note_number > 0) note_number--; // ノート番号-1
            freq = getFrequency(note_number); // 周波数を再計算
        } else {
            // スイッチが押されていない状態
            speaker.stop(); // 音を停止する
        }

        // 現在の周波数を表示
        obniz.display.print(freq);
    }
}

https://tomari.org/main/java/oto.html

okinaka masayoshiokinaka masayoshi

距離

altテキスト
https://obniz.io/ja/sdk/parts/HC-SR04/README.md

近すぎると警告 連続で数値が出る

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });

    // ディスプレイ
    obniz.display.clear(); // クリア
    obniz.display.print('あああ');
    //obniz.display.print('Hello obniz!'); // Hello obniz! と表示

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離(mm)をターミナルに表示
        console.log(distance + ' mm');
        // obnizディスプレイに表示
        // 一度消してから距離+mmの単位を表示
        obniz.display.clear();
        obniz.display.print(distance + ' mm');

        // 距離がある程度未満かどうかの判定
        if (distance < 50) { // 50mm = 5cm 以下の場合
            // obnizディスプレイに近接していることを表示
            obniz.display.clear();
            obniz.display.print('Too close!!');
        }

    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}
okinaka masayoshiokinaka masayoshi

サーボモータ 茶・赤・黄の順

altテキスト
https://obniz.com/ja/doc/guides/obniz-starter-guide/parts-library/servo-motor

スイッチで動かす

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // サーボモータを利用
    const servo = obniz.wired('ServoMotor', { signal: 2 });

    // 角度を保持する変数
    let degrees = 90.0;

    // ディスプレイ表示(初期画面)
    obniz.display.clear();
    obniz.display.print('Hello obniz!');

    // スイッチの反応を常時監視
    // 「スイッチ状態が変化した瞬間に1回だけ実行される」ことに注意しましょう
    obniz.switch.onchange = function (state) {
        // スイッチの状態で角度を決め、最後に動かします
        if (state === 'push') {
            // スイッチが押されている状態
            console.log('pushed');
            degrees = 45.0;
        } else if (state === 'right') {
            // 右にスイッチを倒したとき
            console.log('right');
            degrees = 0.0;
        } else if (state === 'left') {
            // 左にスイッチを倒したとき
            console.log('left');
            degrees = 180.0;
        } else {
            // スイッチが押されていない状態
            console.log('released');
            degrees = 90.0;
        }
        
        // ディスプレイに角度を表示
        obniz.display.clear();
        obniz.display.print(`Current: ${degrees} deg`);
        // サーボを指定の角度まで動かします
        servo.angle(degrees);
    }
}
okinaka masayoshiokinaka masayoshi

フルカラーLED 長いやつから順番 4ピン目不要

altテキスト
https://obniz.io/ja/sdk/parts/WS2811/README.md

押した時だけ赤

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 0, vcc: 1, din: 2 });

    // ディスプレイ表示(初期画面)
    obniz.display.clear();
    obniz.display.print('Hello obniz!');

    // スイッチの反応を常時監視
    obniz.switch.onchange = function (state) {
        if (state === 'push') {
            // 押されたとき
            console.log('pushed');
            // 赤: rgbled.rgb(255, 0, 0);
            // 緑: rgbled.rgb(0, 255, 0);
            // 青: rgbled.rgb(0, 0, 255);
            rgbled.rgb(255, 0, 0);
        } else if (state === 'none') {
            // none で押してないとき
            console.log('released');
            // LED OFF = RGBのいずれも点灯しない = すべて0
            rgbled.rgb(0, 0, 0);
        }
    }
}

ボタンでRGB

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 0, vcc: 1, din: 2 });

    // ディスプレイ表示(初期画面)
    obniz.display.clear();
    obniz.display.print('Hello obniz!'); 

    // スイッチの反応を常時監視
    obniz.switch.onchange = function (state) {
        if (state === 'push') {
            // 押されたとき
            console.log('pushed');
            rgbled.rgb(255, 0, 0);
        } else if (state === 'none') {
            // none で押してないとき
            console.log('released');
            // 消灯
            rgbled.rgb(0, 0, 0);
        } else if (state === 'right') {
            // 右にスイッチを倒したとき
            console.log('right');
            // 緑
            rgbled.rgb(0, 255, 0);
        } else if (state === 'left') {
            // 左にスイッチを倒したとき
            console.log('left');
            // 青
            rgbled.rgb(0, 0, 255);
        }
    }
}
okinaka masayoshiokinaka masayoshi

obniz×LINEbot①準備・基礎コード

npm i express obnizとの連携時に必要
npm i @line/bot-sdk express
ターミナルをもう1つ開き、サーバーを起動
ngrok http 3000

// ########################################
//          Expressによるサーバー部分
// ########################################
const express = require('express');
const app = express();
app.get('/obniz', (req, res) => {
    // obnizのディスプレイにmessageで指定された内容を表示
    obniz.display.clear();
    obniz.display.print(req.query.message);
    // ブラウザへの応答    
    res.send('Sended: ' + req.query.message);
});

app.listen('3000', () => {
    console.log('Application started');
});


// ########################################
//          obniz初期化部分
// ########################################
const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます
obniz.onconnect = async function () {
    // ディスプレイ
    obniz.display.clear();
    obniz.display.print('express meets obniz!'); // メッセージを表示
}

今回のngrokのアドレスをメモしつつ、ブラウザで以下のようにメッセージを送ってみましょう。
https://<今回のngrokのアドレス>/obniz?message=Hello(YourName)
すると、ブラウザでまず返答が返ってきます。➡文字は任意で変更可能

LINEbotで温度測定

altテキスト

// ########################################
//          obniz処理部分
//  Obniz_ID:自分のobniz ID(XXXX-XXXX)
// ########################################
const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID');
// obnizと接続確立したとき
obniz.onconnect = async () => {
    obniz.display.clear();
    obniz.display.print('obniz Ready');
}
// 温度センサから値を取得して返す
const getObnizTemp = async () => {
    // 温度センサの利用
    const tempsens = obniz.wired('LM60', { gnd: 0, output: 1, vcc: 2 });
    // 非同期で取得
    const temp = await tempsens.getWait();
    // ターミナル表示
    console.log('obniz temp:', temp);
    // obnizディスプレイ表示
    obniz.display.clear();
    obniz.display.print(temp + ' C');
    // 温度値を返す
    return temp;
}



// ########################################
//          LINEBot イベント処理部分
//  channelSecret:LINE Developers → チャネル基本設定 → チャネルシークレット
//  channelAccessToken:LINE Developers → Messaging API設定 → チャネルアクセストークン(長期)
//  ターミナルで `ngrok http 3000` 実行後、発行されたURLをWebhook URLとして設定するのを忘れずに
//  「検証」ボタンをクリックするとターミナルにエラーが出ますがここでは問題ありません(検証イベントのハンドリングをしていないため)
// ########################################
const config = {
    channelSecret: 'channelSecret',
    channelAccessToken: 'channelAccessToken'    
};
const line = require('@line/bot-sdk');
const client = new line.Client(config);
// ExpressからMessaging APIイベントを渡されて処理するところ
const handleEvent = async (event) => {
    // テキストメッセージ以外を受信したときは何も行わずresolveを返す
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // テキストメッセージを受信したとき
    if (event.message.text === '温度教えて') {
        // 待ってねというメッセージを「リプライ」で先に返す
        await client.replyMessage(event.replyToken, {
            type: 'text',
            text: '.oO(ちょっと調べてきますねー。)'
        });
        // obnizの温度センサから値をとってくる(ブロッキング・時間のかかる処理で一旦ここで止まる)
        const temp = await getObnizTemp();
        // tempが取得できたらそれを含めたメッセージを「プッシュ」で送信する
        client.pushMessage(event.source.userId, {
            type: 'text',
            text: '今の温度は' + temp + '度ですねー。',
        });
    } else {
        // メッセージの中身が「温度教えて」以外だったとき
        client.replyMessage(event.replyToken, {
            type: 'text',
            text: '「温度教えて」と話しかけてね!'
        });
    }
    // resolveを返す
    return Promise.resolve(null);
}



// ########################################
//          Expressサーバー部分
// ########################################
const express = require('express');
const PORT = process.env.PORT || 3000;
const app = express();
// 「(サーバーURL)/webhook」にアクセス(LINEサーバーからのWebhook)があったとき
app.post('/webhook', line.middleware(config), (req, res) => {
    // 受信したイベントをターミナルに表示
    console.log(req.body.events);
    // イベントをhandleEventに渡して1つずつ処理
    Promise.all(
        req.body.events.map(handleEvent)
    ).then(
        result => res.json(result)
    );
});
// PORT番号のポートでサーバーを開始
app.listen(PORT);
console.log('express runnning: PORT =', PORT);

近づいたら光るLED

altテキスト
altテキスト


const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID');

obniz.onconnect = async () => {
    // 超音波距離センサを利用
    // 基礎編で使ったときと向きが反転していることに注意
    const hcsr04 = obniz.wired('HC-SR04', {
        gnd: 3,
        echo: 2,
        trigger: 1,
        vcc: 0,
    });

    // LEDを利用
    const led = obniz.wired('LED', { anode: 10, cathode: 11 });

    // obnizディスプレイ(初期表示)
    obniz.display.clear();
    obniz.display.print('obniz Ready');

    // setIntervalで定期実行
    setInterval(async () => {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // 小数点以下がたくさんあるのでここでは整数にします
        distance = Math.floor(distance);
        // 距離をコンソールに表示
        console.log(distance + ' mm');
        // 距離をobnizディスプレイに表示
        obniz.display.clear();
        obniz.display.print(distance + ' mm');
        // 距離によって判定
        if (distance < 50.0) {
            // 50mm = 5cm 未満の場合 obnizディスプレイ表示
            obniz.display.clear();
            obniz.display.print('Too close!!');
            // LEDオン
            led.on();
        } else {
            // 50mmを超えるときは常にLEDオフ
            led.off();
        }
    }, 1000); // 1000ミリ秒 = 1秒ごとに実行
};
``
okinaka masayoshiokinaka masayoshi

obniz×LINEbot②ngrok axios

まず単純なLINEbot

'use strict';

const express = require('express');
const line = require('@line/bot-sdk');

const PORT = process.env.PORT || 3000;

// Messaging APIを利用するための鍵を設定します。
const config = {
  channelSecret: '作成したBOTのチャネルシークレット',
  channelAccessToken: '作成したBOTのチャネルアクセストークン'
};

const client = new line.Client(config);

async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }
  // ユーザーにリプライメッセージを送ります。
  return client.replyMessage(event.replyToken, {
    type: 'text', // テキストメッセージ
    text: event.message.text // ← ここに入れた言葉が実際に返信されます
    // event.message.text には、受信したメッセージが入っているので、それをそのまま返信しています
    // ここを 'テスト' のように書き換えると、何を受信しても「テスト」と返すようになります
  });
}

// ここ以降は理解しなくてOKです
const app = express();
app.get('/', (req, res) => res.send('Hello LINE BOT! (HTTP GET)'));
app.post('/webhook', line.middleware(config), (req, res) => {

  if (req.body.events.length === 0) {
    res.send('Hello LINE BOT! (HTTP POST)');
    console.log('検証イベントを受信しました!');
    return;
  } else {
    console.log('受信しました:', req.body.events);
  }

  Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});

app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

npm i express
ngrok http 3000
LINEwebhook設定 URLと/webhook

npm i axios

LINEbotサンプルコード基礎

'use strict';

// ########################################
//               初期設定など
// ########################################

// パッケージを使用します
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');

// ローカル(自分のPC)でサーバーを公開するときのポート番号です
const PORT = process.env.PORT || 3000;

// Messaging APIで利用するクレデンシャル(秘匿情報)です。
const config = {
    channelSecret: '作成したBotのチャネルシークレット',
    channelAccessToken: '作成したBotのチャネルアクセストークン'
};



// ########## ▼▼▼ サンプル関数 ▼▼▼ ##########
(この行をサンプル関数丸ごと全部と置き換えてね)
// ########## ▲▲▲ サンプル関数 ▲▲▲ ##########



// ########################################
//  LINEサーバーからのWebhookデータを処理する部分
// ########################################

// LINE SDKを初期化します
const client = new line.Client(config);

// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されます
async function handleEvent(event) {
    // 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視します
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    // サンプル関数を実行します
    return sampleFunction(event);
}



// ########################################
//          Expressによるサーバー部分
// ########################################

// expressを初期化します
const app = express();

// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {
  
  // 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
  if (req.body.events.length === 0) {
    res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します(なくてもよい)
    console.log('検証イベントを受信しました!'); // ターミナルに表示します
    return; // これより下は実行されません
  } else {
    // 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
    console.log('受信しました:', req.body.events);
  }

  // あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
  // 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
  Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});

// 最初に決めたポート番号でサーバーをPC内だけに公開します
// (環境によってはローカルネットワーク内にも公開されます)
app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

if文の使用例

const sampleFunction = async (event) => {
    let replyText = '';
    if (event.message.text === '契約') {
        replyText = 'とれました!';
    } else {
        replyText = 'とれません…';
    }
    return client.replyMessage(event.replyToken, {
        type: 'text',
        text: replyText
    });
};

完全一致 部分一致

const sampleFunction = async (event) => {
    const userText = event.message.text;
    let replyText = '';

    // 部分一致1(「遊」という文字が1ヶ所でも含まれていたら反応)
    if (userText.indexOf('遊') > -1) {
        replyText = 'ディズニーリゾートへ行きましょう!';
    }

    // 部分一致2(「アトラクション」という単語が1ヶ所でも含まれていたら反応)
    if (userText.indexOf('アトラクション') > -1) {
        replyText = 'アトラクションのことでしたら、ぜひ「おすすめは?」と聞いてみてください!';
    }

    // 完全一致したらランダムに返信
    if (userText === 'おすすめは?') {
        // アイスの配列
        const attractions = ['ビッグサンダー・マウンテン', 'センター・オブ・ジ・アース', 'スペース・マウンテン', 'エレクトリック・レールウェイ', 'スプラッシュマウンテン', 'インディ・ジョーンズ・アドベンチャー', 'カリブの海賊', 'スポンサーラウンジ'];
        // アイスの種類数
        const att_count = attractions.length;
        // 乱数(0以上1未満の小数)* 種類数 をして小数以下切り捨て
        const index = Math.floor(Math.random() * att_count);
        // インデックスを指定して特定のアイスを示す文字列を取り出す
        replyText = '「' + attractions[index] + '」がおすすめです🎢';
    }

    // この時点でどの条件にも引っかかってない(replyTextが空文字列のまま)なら相槌をうっておく
    if (replyText === '') {
        replyText = 'そうですね〜';
    }

    return client.replyMessage(event.replyToken, {
        type: 'text',
        text: replyText
    });
};
okinaka masayoshiokinaka masayoshi

obniz×LINEbot③API連携

Qiita記事

const getQiitaTag = async (userId, tag) => {
    let result = '';
    try {
        // axiosでQiitaのAPIを叩きます
        const res = await axios.get('https://qiita.com/api/v2/tags/' + encodeURIComponent(tag));
        const item = res.data;
        result = 'Qiitaのタグ「' + tag + '」の記事数は、' + item.items_count + '件です!';
        // ターミナルにも検索結果を出しておきます
        console.log(`${tag}」の検索結果:${item.items_count}`);
        // 正常に取得できればここで終了
    } catch (error) {
        // HTTPステータスコードが404ならタグが見つからない、それ以外は別のHTTPエラーです
        const { status, statusText } = error.response;
        if (status == 404) {
            result = 'Qiitaのタグ「' + tag + '」の記事はありませんでした';
        } else {
            result = `エラー: ${status} ${statusText}`;
        }
    }

    // リプライではなく「プッシュ」を送ります
    // Botからユーザーへ一方的に通知を送ることができる機能です
    await client.pushMessage(userId, {
        type: 'text',
        text: result,
    });
}

const sampleFunction = async (event) => {
    // ユーザーIDとメッセージ文字列を関数に渡します
    // メッセージ文字列でQiitaタグを検索し、結果をQiitaから受け取ったらユーザーIDに対して「プッシュ」送信します
    // 検索には少し時間がかかるので、これの結果は後でユーザーに送られます
    getQiitaTag(event.source.userId, event.message.text);

    // こちらが先に返事を返します
    // ユーザーからのメッセージに対する「リプライ」です
    // リプライは、受信したメッセージ1つにつき1回しか使えません
    return client.replyMessage(event.replyToken, {
        type: 'text',
        text: '検索しています……'
    });
};

日の出・日の入りAPI

const sampleFunction = async (event) => {
    // ユーザーメッセージが「日の出」か「日の入り」かどうか
    if (event.message.text !== '今日の日の出は?') {
        return client.replyMessage(event.replyToken, {
            type: 'text',
            text: '「今日の日の出は?」と話しかけてね'
        });
    } else {
        // 「リプライ」を使って先に返事しておきます
        await client.replyMessage(event.replyToken, {
            type: 'text',
            text: '調べています……'
        });
        
        let pushText = '';
        try {
            // axiosで日の出日の入り時刻のAPIを叩きます(少し時間がかかる・ブロッキングする)
            const res = await axios.get('https://api.sunrise-sunset.org/json?lat=34.6959484&lng=135.4927352');
            // 取得できるのはUTCなので日本時間(+9時間)になおす
            const utc_time = res.data.results.sunrise;
            // '時', '分', '秒 PM' に分割する
            const tm_split = utc_time.split(':');
            // '時' を9時間進めて12時間戻す(13時を過ぎないようにする)
            const jp_hour = Number(tm_split[0]) + 9 - 12;
            // '秒 PM' を '秒' だけにする
            const sec = tm_split[2].split(' ')[0];
            // 再構成する
            const time_string = `${jp_hour}${tm_split[1]}${sec}`;
            pushText = `今日の大阪市北区付近の日の出は${time_string}です!`;
        } catch (error) {
            pushText = '検索中にエラーが発生しました。ごめんね。';
            // APIからエラーが返ってきたらターミナルに表示する
            console.error(error);
        }

        // 「プッシュ」で後からユーザーに通知します
        return client.pushMessage(event.source.userId, {
            type: 'text',
            text: pushText,
        });
    }
};
okinaka masayoshiokinaka masayoshi

obniz 身長を測ってLINEで返す

'use strict';
const Obniz = require('obniz');
const obniz = new Obniz('****-****');

obniz.onconnect = async function () {
    obniz.display.clear();
    obniz.display.print("obniz meets LINE Bot!");
  }

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');

const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: '********',
    channelAccessToken: '********'
};


const sampleFunction = async (event) => {
    if (event.type !== 'message' || event.message.type !== 'text') {
      return Promise.resolve(null);
    }

    let mes = ''
    if(event.message.text === 'わたしおおきくなったかな・・・'){
      mes = 'はかってみるね!☻'; //処理するまでこちらを表示
      getkyori(event.source.userId);
    }else{
      mes = event.message.text;
    }

    return client.replyMessage(event.replyToken, {
      type: 'text',
      text: mes
    });
  }
  const getkyori = async (userId) => {
    // 距離センサーを呼び出す
    var hcsr04 = obniz.wired("HC-SR04", {gnd:8, echo:9, trigger:10, vcc:11});
    const distance = await hcsr04.measureWait();{{
    var height=((2242-distance)/10)
    //天井の高さから距離を引いて身長を割り出す
    }
      console.log("身長は" + height + " cm")
      }

    await client.pushMessage(userId, {
     type: 'text',
     text: "身長は" + height + " cm",
   })
  }
okinaka masayoshiokinaka masayoshi

マトリックスLED

const Obniz = require('obniz');
const obniz = new Obniz('****-****');

obniz.onconnect = async function () {

    const matrix = obniz.wired("MatrixLED_MAX7219", {
        vcc: 4,
        gnd: 3,
        din: 2,
        cs: 1,
        clk: 0
      });
      matrix.init(8 * 4, 8);
      matrix.brightness(7);

      const ctx = obniz.util.createCanvasContext(matrix.width, matrix.height);

      x = matrix.width;
      obniz.repeat(async function() {
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, matrix.width, matrix.height);
        ctx.fillStyle = "white";
        ctx.font = "9px sans-serif";
        ctx.fillText("おかあさんそだててくれてありがとう", x, 7);
        x--;

        matrix.draw(ctx);
      }, 1000 / 80);
    };
okinaka masayoshiokinaka masayoshi

音楽プラスサーボモータ


const Obniz = require('obniz');
const obniz = new Obniz('***-****');

obniz.onconnect = async function () {

var servo = obniz.wired("ServoMotor", {gnd:9, vcc:10, signal:11});

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(210); // 210msec
// LED 青
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(210); // 210msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(210); // 210msec

let count = 0;
// アンパンマンの角度
let angles = [10, 50, 10, 50, 10, 180, 10, 50, 10, 50, 10, 180, 10, 50, 10, 50, 10, 50, 10, 50, 10, 180, 10, 50, 10, 50, 10, 50, 10, 50, 10, 50, 10, 180, 10, 50, 10, 180, 10];
let timer = setInterval(() => {
    count++;
    servo.angle(angles[count]);
    //50回アンパンマンがダンスします
    if (count >= 50) {
     clearInterval(timer);
    let degrees = 90.0;
    }
}, 500);//500msecの感覚でダンス

//JOY 
var speaker = obniz.wired("Speaker", {signal:0, gnd:1});

obniz.display.clear();
obniz.display.print('YUKI live');

speaker.play(3520); //ラ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(300);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(150);//スタッカート
speaker.stop();

await obniz.wait(50);//間の拍 半拍

speaker.play(3520); //ラ
await obniz.wait(300);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(150);
speaker.stop();

await obniz.wait(50);//間の拍 半拍


speaker.play(3951.066); //シ
await obniz.wait(150);
speaker.stop();

await obniz.wait(300);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(300);
speaker.stop();

await obniz.wait(500);//間の拍

//ライト再定義2

var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();
led.endBlink();

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(105); // 210msec
// LED 青
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(105); // 210msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(105); // 210msec


//2小説目

speaker.play(3520); //ラ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(300);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(150);//スタッカート
speaker.stop();

await obniz.wait(50);//間の拍 半拍

speaker.play(3520); //ラ
await obniz.wait(300);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(150);
speaker.stop();

await obniz.wait(50);//間の拍 半拍


speaker.play(3951.066); //シ
await obniz.wait(150);
speaker.stop();

await obniz.wait(300);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(300);
speaker.stop();

await obniz.wait(500);//間の拍

//ライト再定義2

var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();
led.endBlink();

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(420); // 420msec
// LED 青
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(420); // 420msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(420); // 420msec

//3小説目 死ぬまでわくわく~

speaker.play(2959.955); //ファ#
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(2959.955); //ファ#
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();



//ライト再定義3

var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();
led.endBlink();

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(210); // 210msec
// LED 青
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(210); // 210msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(210); // 210msec

//ここまでライト

await obniz.wait(100);//間の拍
speaker.play(3520); //ラ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3951.066); //シ
await obniz.wait(700);//長い
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(700);//長い
speaker.stop();

await obniz.wait(600);//間の拍

//ライト再定義3

var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();
led.endBlink();

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(105); // 105msec
// LED 青
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(210); // 210msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(420); // 420msec

//4小説目

speaker.play(2959.955); //ファ#
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(2959.955); //ファ#
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

//ライト切り替え
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();
led.endBlink();

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(105); // 105 msec
// LED 青 
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(105); // 105msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(420); // 420msec

//ここまでライト

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3520); //ラ
await obniz.wait(350);
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(350);
speaker.stop();

//ライト切り替え
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();
led.endBlink();

// LED 赤
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(105); // 105msec
// LED 青
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink(105); // 105msec
// LED 黄
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink(105); // 105msec

//ここまでライト

await obniz.wait(100);//間の拍

speaker.play(3951.066); //シ
await obniz.wait(700);//長い
speaker.stop();

await obniz.wait(100);//間の拍

speaker.play(3135.963); //ソ
await obniz.wait(700);//長い
speaker.stop();

await obniz.wait(500);//間の拍

//ライト終了
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:4, cathode:5});
led.blink();
led.endBlink();
var led = obniz.wired("LED", {anode:6, cathode:7});
led.blink();

led.endBlink();
speaker.stop();
servo.stop();

}