- 投稿日:2021-01-18T20:16:41+09:00
Node.jsでAzure IoT Hubにテレメトリを送信するサンプルコードを動かすメモ
はじめに
デバイスから IoT ハブに利用統計情報を送信してバックエンド アプリケーションで読み取るを参考にサンプルコードを動かしてみます。
接続文字列はAzure CLIを使わずに、コンソールから取得します。Azure IoTについてはこちらを参照。
準備
IoTデバイスを登録する
Azure IoT Hubコンソール > サイドバー > IoTデバイス > 新規
からデバイスを追加する。追加できたら、追加したデバイスを選択して
プライマリ接続文字列
をコピーしておく。データを送信する
ダウンロードしたサンプルコードから、
SimulatedDevice.js
を開き、17行目あたりのconnectionString
に先程コピーしたプライマリ接続文字列
を貼り付ける。コードはこんな感じになる。
var connectionString = '{Your device connection string here}'; // ←ここに`プライマリ接続文字列`を貼り付ける。 var Mqtt = require('azure-iot-device-mqtt').Mqtt; var DeviceClient = require('azure-iot-device').Client var Message = require('azure-iot-device').Message; var client = DeviceClient.fromConnectionString(connectionString, Mqtt); setInterval(function(){ // 送信するデータを生成する。(本当はセンサーで測定した値を入れるがシミュレーションのため乱数を使用) var temperature = 20 + (Math.random() * 15); var message = new Message(JSON.stringify({ temperature: temperature, humidity: 60 + (Math.random() * 20) })); message.properties.add('temperatureAlert', (temperature > 30) ? 'true' : 'false'); console.log('Sending message: ' + message.getData()); // イベントを送信する client.sendEvent(message, function (err) { if (err) { console.error('send error: ' + err.toString()); } else { console.log('message sent'); } }); }, 1000);以下のコマンドをターミナルで実行する。
$ node SimulatedDevice.jsデータが送信されている。
送信したデータを受信する
ダウンロードしたサンプルコードから、
ReadDeviceToCloudMessages.js
を開き、38行目あたりのconnectionString
にAzure IoT Hubコンソール > サイドバー > 組み込みのエンドポイント > イベントハブ五感エンドポイント
の値を貼り付ける。
(26行目あたりにeventHubsCompatibleEndpoint
などの変数が用意されていますが、無視します。)コードはこんな感じになる。
const connectionString = `Endpoint=**********************;SharedAccessKeyName=*****************;EntityPath=********************`; var printError = function (err) { console.log(err.message); }; var printMessages = function (messages) { for (const message of messages) { console.log("Telemetry received: "); console.log(JSON.stringify(message.body)); console.log("Properties (set by device): "); console.log(JSON.stringify(message.properties)); console.log("System properties (set by IoT Hub): "); console.log(JSON.stringify(message.systemProperties)); console.log(""); } }; async function main() { console.log("IoT Hub Quickstarts - Read device to cloud messages."); const clientOptions = { // webSocketOptions: { // webSocket: WebSocket, // webSocketConstructorOptions: {} // } }; const consumerClient = new EventHubConsumerClient("$Default", connectionString, clientOptions); // イベントハブのストリームからデータを取得する consumerClient.subscribe({ processEvents: printMessages, processError: printError, }); } main().catch((error) => { console.error("Error running sample:", error); });実行する。
$ node ReadDeviceToCloudMessages.js
受信できた。
まとめ
公式のデバイスから IoT ハブに利用統計情報を送信してバックエンド アプリケーションで読み取るを動かしました。
また、Azure CLIを使わずにコンソールから接続文字列を取得しました。Azure IoT Hubの
S1
スケールは月に2~3000円ほどかかるので、試し終わったら忘れずに止めておきましょう。次回は、M5系のデバイスからデータを送信してみます。
- 投稿日:2021-01-18T19:48:08+09:00
JavaScriptフレームワークのプロジェクト作成コマンドを列挙した
はじめに
JavaScript のフレームワークには npm や Yarn などのパッケージマネージャーを使い簡単に依存関係を解決し、プロジェクトの雛形を作成してくれるコマンドが用意されていることが多いです。
スクラッチでの作成もできますが、コマンドラインツールによって簡単にプロジェクトの自動作成、開発サーバーでの実行ができ便利だと感じたため、有名な JavaScript フレームワークの雛形作成コマンドを備忘録として挙げてみます。各コマンドの
<project-name>
の部分が作成されるディレクトリ名、デフォルトのプロジェクト名になります。作成するプロジェクトに応じて適宜置き換えてください。公式のドキュメントに沿って基本となるコマンドをまとめています。プロジェクト作成時に対話形式で設定可能な項目については記事内で扱いません。項目の説明や、利用できるオプションについては公式のドキュメントを参照のうえ実行をお願いします。
前提条件
- node.js がインストールされていること(バージョン 8 以降、最新の LTS バージョンを推奨)
- npm もしくは Yarn が利用可能であること(npm は node.js にデフォルトで搭載)
Vue
npm
npm install -g @vue/cli vue create <project-name> cd <project-name> npm run serveYarn
yarn global add @vue/cli vue create <project-name> cd <project-name> npm run serve
http://localhost:8080 で開発サーバが立ち上がります。
Nuxt.js
npm
npm init nuxt-app <project-name> cd <project-name> npm run dev (yarn dev)npx
npx create-nuxt-app <project-name> cd <project-name> npm run dev
Yarn
yarn create nuxt-app <project-name> cd <project-name> yarn dev
http://localhost:3000 で開発サーバーが立ち上がります。
React
npm
npm init react-app <project-name> cd <project-name> npm start
npx
npx create-react-app <project-name> cd <project-name> npm start
Yarn
yarn create react-app <project-name> cd <project-name> yarn start
npm、npx でインストールする場合は Yarn がインストールされているとデフォルトで Yarn が使用されます。
http://localhost:3000 で開発サーバーが立ち上がります。
Next.js
npm
npx create-next-app <project-name> cd <project-name> npm run dev
Yarn
yarn create next-app <project-name> cd <project-name> yarn dev
React と同じく npm、npx でインストールする場合は Yarn がインストールされているとデフォルトで Yarn が使用されます。
http://localhost:3000 で開発サーバーが立ち上がります。
Angular
npm
npm install -g @angular/cli ng new <project-name> cd <project-name> ng serve --openYarn
npm install -g @angular/cli ng config -g cli.packageManager yarn ng new <project-name> cd <project-name> ng serve --open
ng serve --open
とすることでデフォルトのブラウザで起動します。
http://localhost:4200 で開発サーバーが立ち上がります。Svelte
公式で公開されているテンプレートから新規プロジェクトを作る。
npx
npx degit sveltejs/template <project-name> cd <project-name> npm install npm run devhttp://localhost:5000 で開発サーバーが立ち上がります。
おわりに
有名な JavaScript フレームワークの雛形プロジェクト作成コマンドを公式ドキュメントをもとに列挙してみました。簡単なコマンド 1 つですぐに開発を始める環境が作成できるのはとても便利です。フレームワークがここまで発展し、多くの人に選ばれる理由わかった気がします。
公式ドキュメントを見ながら記事を執筆する中で得た気づきが多くあるため、今後 JavaScript フレームワークについて更に理解を深めていきたいです。
以上、ここまで読んでいただきありがとうございました。
参考ドキュメント
Creating a Project | Vue CLI
インストール - NuxtJS
新しい React アプリを作る - React
facebook/create-react-app: Set up a modern web app by running one command.
Create Next App | Next.js
Angular 日本語ドキュメンテーション - ローカル環境とワークスペースのセットアップ
【2019 年 5 月】yarn で @angular/cli
The easiest way to get started with Svelte
sveltejs / template Template for building basic applications with Svelte
- 投稿日:2021-01-18T13:27:27+09:00
Repl.itでBotの機能を開発しまくったお話
まずは皆様にご挨拶
皆様、初めまして!!
Repl.itでDiscordBotを開発している『姉だぁぁぁぁ
』と申します。
私は、まだプログラミングを始めたばかりの学生で、このサイトを利用して投稿したりするのは本当に初めてですが、
良い記事の発行や、Botのプログラミング能力を高めたらと思い、このアカウントを作りました。よろしくお願いします。では、本編に参りまっす!
JSで覚醒した沢山の機能を作ってみる
リアクションを使って、ページネーションを作成する。
ページネーションを早く、簡単に作成したい場合は下記のリンクを参照してください。
(InkoHXさん、ありがとうございます!)↑このパッケージを使用することによって、Botのメッセージをリアクションのリアクションで、簡単にページネーションを作成する事ができます。
しかし、私は『できれば自分でページネーションを作成したい』と思ったので、数か月前にダウンロードしたソースコードを利用して、ようやくページネーションを作成することができました。
▽▽▽そのソースコードは以下の通りです。▽▽▽//ページネーションを作成 client.on('message',async message => { if (message.author.bot) { return; } if (message.content ===('!help')) { const pages = { //埋め込みでページネーションを作る時に形式を[Java]にしました。 1: new discord.MessageEmbed() .setTitle('(1/2)Title') .setDescription("Helpコマンドっす") .setAuthor(message.author.tag + 'が実行したな!!', message.author.avatarURL()) .setColor(16719653) .setTimestamp(), 2: new discord.MessageEmbed() .setTitle('(2/2)Title') .setDescription("EMBEDを作るのも https://leovoel.github.io/embed-visualizer/ を参照するといいと思う(多分)") .setAuthor(message.author.tag + 'が実行したな!!', message.author.avatarURL()) .setColor(16719653) .setTimestamp() }; const options = { limit: 15 * 1000, min: 1, max: 2, page: 1, pages: pages, }; const awaitReactions = async (msg, m, options, filter) => { await m .awaitReactions(filter, { max: 1, time: 360000, errors: ["time"] }) .then(async (collected) => { //各リアクションをクリックした時の処理を作る↓↓↓ const reaction = collected.first(); if (reaction.emoji.name === "◀") { await removeReaction(m, msg, "◀"); if (options.page != options.min) { options.page = options.page - 1; await m.edit(options.pages[options.page]); } await awaitReactions(msg, m, options, filter); } else if (reaction.emoji.name === "▶") { await removeReaction(m, msg, "▶"); if (options.page != options.max) { options.page = options.page + 1; await m.edit(options.pages[options.page]); } await awaitReactions(msg, m, options, filter); } else { await awaitReactions(msg, m, options, filter); } }) .catch((e) => console.log(e)); }; const removeReaction = async (m, msg, emoji) => { try { await m.reactions.cache .find((r) => r.emoji.name == emoji) .users.remove(msg.author.id); } catch (err) { console.log(err); } }; //メッセージを送信↓↓↓ const m = await message.channel.send(options.pages[options.page]); //リアクションの並び順を作る↓↓↓ await m.react("◀"); await m.react("▶"); //送信したメッセージにリアクション追加↓↓↓ const filter = (reaction, user) => ["◀", "▶"].includes(reaction.emoji.name) && user.id == message.author.id; await awaitReactions(message, m, options, filter); } }); //ここまで結構長いソースコードです…。
ですが、このソースコードを利用して任意のチャンネルにコマンドを実行すると、ちゃんと動いているんですよね…そんな感じですかね…
このソースコードを色んな風に使うと、様々な埋め込みをシンプルっぽくデザインすることができまっす。
リアクションが追加されない場合は、Botの権限の『リアクションの追加』をONにして下さい。
YouTube検索機能を作成する。
!youtube [検索ワード]
でYouTubeにある動画を検索できるソースコードは、以下の通りです。//ようつべ検索 const yts = require('yt-search');//npmをインストール client.on('message', async message => { if (message.content.startsWith("!youtube")) { if (message.author.bot) { return; } const AKB = message.content.split(" ").slice(1).join(" ") //調べたい用語を入れなかった時のメッセージ↓↓↓ if (!AKB) return message.channel.send({embed: { color: 16719653, description: '**調べたい用語を入れてね!**\n```使用例 : !youtube Discord```' } }) //YouTubeで検索中の時のメッセージ↓↓↓ const msg = await message.channel.send({embed: { color: 16719653, author: { name: "Youtube内で検索中なんだ!!ちょっとまてよぉぉ!!", }, } }); yts(AKB, function(err, r) { const videos = r.videos const playlists = r.playlists || r.lists const channels = r.channels || r.accounts //メッセージを編集して動画URLをうp↓↓↓ msg.edit('✅動画が見つかったよぉぉぉ!!!', { embed: { color: 16719653, timestamp: new Date(), author: { name: message.author.tag + 'が実行したな!!', icon_url: message.author.avatarURL(), }, title: videos[0].title,//動画のタイトル description: '**動画URL**\n> ' + videos[0].url + '\n\n** そうかそういう動画か**' } }) }) } }); //ここまでそんな感じですね。
埋め込みで動画URLとかを貼り付けるので、おしゃれにできるはずです。
わざわざYoutube.comに飛んで検索しなくて済むから、便利と言えば便利かも知れないね…
※yt-search
は必ずインストールしないと、このソースコードは使えません!
確認画面有りのKickコマンドを作る。
私が、Bot作る中で一番苦労したのは『確認画面が有るKickコマンド』を作る事でしたね…。
良いコマンドにしたくて色んなソースコードを組み合わせたものの、Runボタンを押したら…沢山の所からエラー吐いて来たので始末することにかなり時間が掛かりました。()
▽▽▽そのソースコードは以下の通りです。▽▽▽//Kickコマンド client.on('message', async message => { if (message.author.bot) { return; } if (message.content.startsWith('!kick') && message.guild) { //コマンドを実行したユーザーの権限を確認↓↓↓ if (!message.member.hasPermission('KICK_MEMBERS')) { //Kickする権限が無ければメッセージを↓↓↓ return message.channel.send({embed: { color: 16719653, description: '**Kickする権限ないよ!!**', } }) } const user = message.mentions.users.first(); if (user) { const member = message.guild.member(user); //権限を持っている人がKickコマンドを実行したら確認画面を↓↓↓ const msg = await message.channel.send({ embed: { color: 16719653, timestamp: new Date(), author: { name: message.author.tag + 'が実行したな!!', icon_url: message.author.avatarURL(), }, description: '**本当にこれでいいのかよ!?**\n```diff\n+ [ok],[no]のどれかを送信してクレメンス\n+ ok → mentionしたメンバーをKick。\n+ no → mentionしたメンバーをKickせず、処理を停止するぜ。```' } }); //回答による処理を作る↓↓↓ const filter = msg => msg.author.id === message.author.id const collected = await message.channel.awaitMessages(filter, { max: 1, time: 300000 }) const response = collected.first() if (!response) return message.channel.send('> **応答はやくしてよぉぉぉ!!!**') if (!['ok', 'no'].includes(response.content)) { return; } //noを送信したら↓↓↓ if (response.content === 'no') return msg.edit({embed: { color: 16719653, author: { name: 'Kickの処理を止めたよ!!', }, } }); //okを送信したらKick!!↓↓↓ if (response.content === 'ok') { if (member) { member .kick('監査ログに出されるやつ') .then(() => { msg.edit({embed: { color: 16719653, timestamp: new Date(), author: { name: message.author.tag + 'が実行したな!!', icon_url: message.author.avatarURL(), }, description: '**キィィィィック!!!**\n**' + `${user.tag}` + '**をKickしたよ!!', } }) }) //エラーメッセージ↓↓↓ .catch(err => { msg.edit({embed: { color: 16719653, description: 'Kickできなかったよ!!権限確認してよぉぉ!!' } }); console.error(err); }); } else { //メンションされたユーザーがサーバーにいない時↓↓↓ message.channel.send({embed: { color: 16719653, description: 'そいつここのサーバーにいないよぉぉ!!' } }) }; } } else { //対象を指定していない時↓↓↓ message.channel.send({embed: { color: 16719653, description: '**Kickしたいメンバーをメンションしてね!!**```使用例 : !#kick [@mention]```' } }); } } }); //ここまでそんな感じですね。
これで、確認画面有りのKickコマンドが作れます。
確認画面の下の方のこれ↓↓↓const filter = msg => msg.author.id === message.author.id const collected = await message.channel.awaitMessages(filter, { max: 1, time: 300000 }) const response = collected.first() if (!response) return message.channel.send('> **応答はやくしてよぉぉぉ!!!**') if (!['ok', 'no'].includes(response.content)) { return; } if (response.content === 'no') return messsage.channel.send('なんでnoだにゃーん'); if (response.content === 'ok') { message.channel.send('んにゃ')}結構色んなコマンドの所で使えるので、是非試してみて下さい!
ステータスを変える方法
Botのステータス(カスタムステータス含む)を変えるには、下記のリンクを参照にするといいです。
(作成者様、ありがとうございます!)カスタムステータスの所のソースコードは、以下の通りです。
client.on('ready', message => { console.log('準備完了っす!'); client.user.setActivity('にゃーん', { type: "PLAYING" }); /* typeの値: https://discord.js.org/#/docs/main/stable/class/ClientUser?scrollTo=setActivity 'PLAYING': 〇〇 をプレイ中 'STREAMING': 〇〇 を配信中 'WATCHING': 〇〇 を視聴中 'LISTENING': 〇〇 を再生中 */ });カスタムステータスの所はこの通りに簡単に変えることができますが、『じゃあ、退席中等のステータスの所は?』と言いますと…それは、
status値
を使って変える事ができます。status: "online" /* 'online': オンライン 'idle': 退席中 'dnd': 邪魔しないで下さい 'offline': オフライン ただしスマホステータスにしたい場合は別になる。 */これを入れればできると思います。
スマホステータスに変えたい場合は、クライアントを作るところをいじればできるはず。
ソースコードは以下の通りです。const client = new discord.Client({ ws: { properties: { $browser: "Discord iOS" } } });これでしばらくすると、ステータスがスマホマークになります。
最後に
結構沢山の所のねたばらしみたいな感じになってしまいましたが…私は、まだDiscord.jsのことをまだ完全に理解しているという訳ではないのでできれば大目に見てくれると幸いです。
そして、こんなjsのソースコードだらけの記事を最後まで見て下さり、誠にありがとうございました。もし、最後まで見て「あれ?」と思う事がございましたら、この記事にコメントをするか、
Discordの[姉だぁぁぁぁ#1985
]にDMを下さい。
できる限りの事はお答えします!
ありがとうございました。
- 投稿日:2021-01-18T03:03:59+09:00
FirebaseのFunctionsで取り敢えずAPIを作ろう1
FirebaseのFunctionsでAPIを作ろう その1
GoogleのFirebaseってめちゃ便利ですよね,PHP派の私もいい加減あれこれ触ってます.
最近はNuxt使ってSSRアプリをHosting+Functionsにデプロイしたりしてますが
いい加減実用的なものを作るべき段になりました.
備忘録もかねて作業内容をつらつらします.*今回はAPIまで行きません
*随所に偏見が入ってますが見逃してください.~エミュレータの設定編
取り敢えずエミュレータの設定まで記事にします.
API的に動くところが一応見えます.目的
APIの定義は非常に広いと思いますが,ここでは取り敢えずDBに接続してデータを入れたり貰ったりするサーバ側のなんかと定義します.
で,いい加減PHP以外でサーバレスで何とかしたいということで,FirebaseのFunctions使っていきます.
DBはGCPのCloud SQLのMySQL8系です.
今回はあんまり関係ないです.
そこまで進んだら続編出すなり続き書くなりします.環境
OS:Windows10
エディタ(IDE):PHP Storm
因みにnpm派です.現代は一周回ってnpmです(偏見).yarnは捨てます.前提
基本的に以下に沿って行きます.
https://firebase.google.com/docs/functions/get-started?hl=jaFirebaseの設定
Firebaseのプロジェクトの作成とかです.
この辺は割愛します.
サイトからでもプロジェクトからでもいいです.
手順に沿って行くとFirestoreも使用するのでFunctionsとFirestoreも設定しておいてください.ディレクトリ構成
取り敢えずプロジェクトのディレクトリを作ります.
できたら中に入ってnpm install -g firebase-tools特にpackage.jsonとか無いので見た目変化ないですがいいです.
で,firebase loginこの辺も経験ある人はいつも通り.
ログイン済みの人はいりません.firebase init firestoreと
firebase init functions因みに言語は「JavaScript」を選択.
申し訳ないけど「TypeScript」はめんどくさいだけです(偏見2).
複数人で開発するなら考えます.デプロイファイル
デプロイする,つまり実際にアップロード?して使用するファイルは「functions」ディレクトリの下になります.
基本的には「functions/index.js」です.
こいつを手順に沿って書いていきます.
以下のようになります.functions/index.js
const functions = require("firebase-functions"); // The Firebase Admin SDK to access Cloud Firestore. const admin = require('firebase-admin'); admin.initializeApp(); // このHTTPエンドポイントに渡されたテキストパラメーターを取得し、パス/ messages /:documentId / originalの下のCloudFirestoreに挿入します exports.addMessage = functions.https.onRequest(async (req, res) => { // テキストパラメータを取得します。 const original = req.query.text; // Firebase Admin SDKを使用して、新しいメッセージをCloudFirestoreにプッシュします。 const writeResult = await admin.firestore().collection('messages').add({original: original}); // メッセージの書き込みに成功したというメッセージを送り返します res.json({result: `Message with ID: ${writeResult.id} added.`}); }); // / messages /:documentId / originalに追加された新しいメッセージをリッスンし、メッセージの大文字バージョンを/ messages /:documentId / uppercaseに作成します exports.makeUppercase = functions.firestore.document('/messages/{documentId}') .onCreate((snap, context) => { // CloudFirestoreに書き込まれた内容の現在の値を取得します。 const original = snap.data().original; // `context.params`を使用してパラメータ` {documentId} `にアクセスします functions.logger.log('Uppercasing', context.params.documentId, original); const uppercase = original.toUpperCase(); // Cloud Firestoreへの書き込みなど、関数内で非同期タスクを実行する場合は、Promiseを返す必要があります。 // Cloud Firestoreドキュメントに「大文字」フィールドを設定すると、Promiseが返されます。 return snap.ref.set({uppercase}, {merge: true}); });ざっと解説すると以下の二つの関数があります
・addMessage:多分HTTP GETして取得した値をFirestoreに突っ込みます
・makeUppercase:多分firestoreに突っ込まれた値をアッパーケースにしてFirestoreに突っ込みます実行テストその1
さて,ローカル環境でテスト実行します.
firebase emulators:startか
firebase emulators:start --only functions
いろんなサービスが入っている場合「--only functions」してあげないと他のサービスもエミュレートしようとして失敗して怒られます.
functions/に移動して
npm run serveでもいいです.
「firebase emulators:start --only functions」が入ってます.後,多分
http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme
こんな感じでアクセスできます.
Firebaseのコンソールで確認するとFirestoreのmessagesに”uppercaseme”が入っているのが確認できます.めでたしめでたし,と思っていたのか?
「addMessage」関数は動いてますが「makeUppercase」は動いていません.
https://firebase.google.com/docs/rules/emulator-setup
https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=jaこの辺に書いてあります.
エミュレータの設定がいります.
で,Javaです.,,,Java?Javaナンデ?
なんで今どきJavaなんですか私はJavaを許しません(偏見3).まあ,仕方なくJavaを入れます.
因みにこの段階でデプロイしてもちゃんと動くと思います.
でもテストせずにデプロイとか現実的にはあり得ないので,ちゃんと環境作ります.
個人的には自分のPCにJavaが入ってなくてびっくりです.
もうそういう時代っすよ.Javaのインストールわからない方は以下のページを発見いたしましたのでご参照ください.
初学者の鬼門環境変数の何とやらです
https://masalib.hatenablog.com/entry/2020/11/28/131550#java%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%ABエミュレータのインストール
firebase init emulatorsこれでインストール.
後で増やせばいいので一応FunctionsとFirestoreに絞るのが無難です.再び以下にアクセス
http://localhost:5001/nexstimemanagementapi/us-central1/addMessage?text=uppercasemeで,ちゃんと動いているかの確認ですが,
ちゃんとエミュレータが起動した後は本番のFirebaseには変化がありません.http://localhost:4000
とかにローカルのエミュレータが起動しますのでそちらで確認してください.めでたしめでたし
ちょと古いですが以下の記事なぞ参考になると思います.
https://qiita.com/HALU5071/items/e43729ac5b06b0506fbe