車のQOLが爆上がりして優勝できるやつつくった。
M5Stackを買いました。
これはArduino+ボタン+液晶+SDカードリーダーを1つにまとめたもの
ブレッドボードなしに色々できるので電子工作のハードルを一気に下げてくれるすぐれものです。
こちらで画像のようなものを作りました。
http://pic.twitter.com/6MBtczmH2wpic.twitter.com
仕組みはM5Stackをブルートゥースキーボードとして動かしてキーを送信しているだけです。
Bluetoothキーボードはこちらのライブラリをインクルードして使いました。
あとはこのような画像を用意して
以下のようなコードを作るだけです。
#include <BleConnectionStatus.h> #include <BleKeyboard.h> #include <KeyboardOutputCallbacks.h> #include <M5Stack.h> BleKeyboard bleKeyboard("Spotify Controller"); void setup() { M5.begin(); M5.Lcd.drawJpgFile(SD,"/spotify.jpg"); bleKeyboard.begin(); } void loop() { M5.update(); if(bleKeyboard.isConnected()){ //Backword if(M5.BtnA.wasPressed()){ bleKeyboard.write(KEY_MEDIA_PREVIOUS_TRACK); } //Play, Pause if(M5.BtnB.wasPressed()){ bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE); } //FastForword if(M5.BtnC.wasPressed()){ bleKeyboard.write(KEY_MEDIA_NEXT_TRACK); } //wait delay(100); }
Arduinoだと起動が早いので車との相性が抜群だと思いました。
お風呂に温度異状があった場合にスマートライトの色を変える。GAS版
tuya Smart Life がIFTTTと連携しなくなるということでびっくりした話。
同時にこういった記事も見つけた。
こちらの記事ではnode.jsからtuya apiにアクセスしていたが、サーバーを用意するのもまだるっこしいので
GASで書いてみた。
必要なもの
- おんどとりの温度計
データロガー おんどとり | SMART VALVE | T&D Corporation
- スマートLED(私は2つで3,000円のこちらを購入した)
この辺は先程挙げた記事の中にやり方は書いてあります。
これで以下のようなGASを書いて5分ごとに実行すればOKです。
//TUYA API 設定 環境に応じて書き換えて下さい。 const clientId = "[CLIENTID]"; const clientSecret = "CLIENTSECRET"; const device_id = ["DEVICE_A", "DEVICE_B"]; //おんどとりweb storage API 設定 //環境に応じて書き換えて下さい。 const api_key = "API_KEY"; const login_id = "LOGIN_ID"; const password = "PASSWORD"; //>>>>【重要】最後にtemps関数内の風呂温度の内容を書き換えてください。<<<<< // //温度を配列で返す関数 function temps() { const ondotori_url = "https://api.webstorage.jp/v1/devices/current"; const furo_temp = () => { var paylord = { "api-key": api_key, "login-id": login_id, "login-pass": password, }; var headers = { "X-HTTP-Method-Override": "GET", "Content-Type": "application/json", }; var options = { method: "post", payload: JSON.stringify(paylord), headers: headers, muteHttpExceptions: true, }; return UrlFetchApp.fetch(ondotori_url, options); }; return JSON.parse(furo_temp()); } //ここまで関数 //ここから本文 function myfunction() { //温度のJSONを取得する var tmprs = temps(); //デバッグ用 女子風呂の温度 //Logger.log("女子:" + tmprs["devices"][1]["channel"][0].value) //↓↓↓男子風呂の温度 環境に応じて切り替えて下さい var danshi = tmprs["devices"][2]["channel"][0].value; //↓↓↓女子風呂の温度 環境に応じて切り替えて下さい var joshi = tmprs["devices"][1]["channel"][0].value; if (Math.max(danshi, joshi) > 43) { Logger.log(`熱い:男子:${danshi} 女子:${joshi}`); setColour(colour.red); } else if (Math.min(danshi, joshi) < 40) { Logger.log(`冷たい:男子:${danshi} 女子:${joshi}`); setColour(colour.blue); } else { Logger.log(`普通:男子:${danshi} 女子:${joshi}`); setColour(colour.green); } //if (Math.min(danshi,joshi)<38 && Math.max(danshi,joshi)>44){ // Logger.log("なんか変") // status = "somethingwrong" //} } //ここまで本文 //以降はTUYA API用スクリプト //setColour(colour.red or colour.blue or colour.green)以外はエラーとなります。 //単純に動かないだけ。 var url = "https://openapi.tuyaus.com/v1.0/token?grant_type=1"; var command_url = `https://openapi.tuyaus.com/v1.0/devices/${device_id}/commands`; var command_urls = device_id.map( (key) => `https://openapi.tuyaus.com/v1.0/devices/${key}/commands` ); var colour = { blue: { h: 240, s: 255, v: 255 }, red: { h: 360, s: 255, v: 255 }, green: { h: 120, s: 255, v: 100 }, }; function setColour(colors) { var timeStamp = getTime().toString(); var token = retreiveAccessToken(clientId, clientSecret, timeStamp, url); var sign = calcSignWithToken(clientId, token, clientSecret, timeStamp); var headers = { client_id: clientId, access_token: token, t: timeStamp, sign: sign, sign_method: "HMAC-SHA256", "Content-Type": "application/json", }; var options = { method: "POST", headers: headers, payload: JSON.stringify({ commands: [ { code: "switch_led", value: true }, { code: "colour_data", value: colors }, ], }), }; // Logger.log(`access_token: ${token}`); // Logger.log(`sign :${sign}`); // Logger.log(`timestamp:${timeStamp}`); res = command_urls.map((key) => UrlFetchApp.fetch(key, options)); Logger.log(res); } function retreiveAccessToken(clientId, clientSecret, timeStamp, url) { var easy_sign = calcSign(clientId, clientSecret, timeStamp); var headers = { client_id: clientId, sign: easy_sign, t: timeStamp, sign_method: "HMAC-SHA256", // Authorization: `Bearer $clientSecret`, }; var options = { method: "GET", headers: headers, payload: {}, }; res = UrlFetchApp.fetch(url, options); return JSON.parse(res).result.access_token; } function getTime() { var now = new Date().getTime(); return now; } function calcSign(clientId, clientSecret, timeStamp) { var str = clientId + timeStamp; var hash = Utilities.computeHmacSha256Signature(str, clientSecret); var signature = hash.reduce(function (str, chr) { chr = (chr < 0 ? chr + 256 : chr).toString(16); return str + (chr.length == 1 ? "0" : "") + chr; }, ""); return signature.toUpperCase(); } function calcSignWithToken(clientId, accessToken, clientSecret, timeStamp) { var str = clientId + accessToken + timeStamp; var hash = Utilities.computeHmacSha256Signature(str, clientSecret); var signature = hash.reduce(function (str, chr) { chr = (chr < 0 ? chr + 256 : chr).toString(16); return str + (chr.length == 1 ? "0" : "") + chr; }, ""); return signature.toUpperCase(); }
ログインにめっちゃ苦労したけどなんとか出来た。よかったよかった。
iot.tuya.comのドキュメントの中にPOSTMANの使い方のなかにSHA256形式で暗号化してログインするというスクリプトが合ったのでそれをGASに合わせて書き換えるのが苦労した。
お風呂に温度異状があった場合にスマートライトの色を変える。
前回まででGASで異状検知した。
次はセルが更新された場合に電球の色を変える。
つかったのはこちら。
大体いっこ1,500円くらい
あとはこれらをiftttでつなぐ。
IFTTTのつなぎ方は
SpreadsheetとSmartLife(スマートLEDのアプリ)をIFTTTに登録し、
Sheetsが更新されたらSmart Lifeで色を変えるというアクションを作る。
今回は3つの場合(熱い・冷たい・普通)で赤・青・緑に変更されるようにした。
最後にGASをトリガー登録(時間主導)で10分ごとに登録する。
おしまい。
本日作ったばかりなので制限等はよくわからないが、そこそこいけるのではないかと考えている。
GASでおんどとりのAPIを叩く②
ここから次は異状があったときに特定のセルを更新するまで
//環境に応じて書き換えるものはapi_key , login_id , password , 温度のところ(danshi , joshiのところ)です。 // //温度を配列で返す関数 function temps(){ // api_key login_id password は書き直して下さい。 const url = "https://api.webstorage.jp/v1/devices/current" const api_key = "" const login_id ="" const password = "" const furo_temp = () => { var paylord = {'api-key':api_key,"login-id":login_id,'login-pass':password} var headers = { "X-HTTP-Method-Override":'GET', "Content-Type" : "application/json",} var options = { "method" : "post", "payload" : JSON.stringify(paylord), "headers" : headers, "muteHttpExceptions":true } return UrlFetchApp.fetch(url,options); } return JSON.parse(furo_temp()) } //ここまで関数 //ここから本文 //温度のJSONを取得する var tmprs = temps() //デバッグ用 女子風呂の温度 //Logger.log("女子:" + tmprs["devices"][1]["channel"][0].value) //男子風呂の温度 環境に応じて切り替えて下さい var danshi = tmprs["devices"][2]["channel"][0].value //女子風呂の温度 環境に応じて切り替えて下さい var joshi = tmprs["devices"][1]["channel"][0].value var nowtime = new Date() var status var sht = SpreadsheetApp.getActiveSheet() if (Math.max(danshi,joshi)>44) { Logger.log("熱い") //デバッグ用 sht.getRange("B1").setValue(nowtime) status = "hot" } if (Math.min(danshi,joshi)<38){ Logger.log("冷たい") //デバッグ用 sht.getRange("B3").setValue(nowtime) status = "cold" } if (Math.min(danshi,joshi)<38 && Math.max(danshi,joshi)>44){ Logger.log("なんか変") status = "somethingwrong" } //最後のswitch文 switch(status){ case "hot": sht.getRange("D5").setValue(nowtime) break case "cold": sht.getRange("F5").setValue(nowtime) break case "somethingwrong": sht.getRange("E5").setValue(nowtime) break default: sht.getRange("G5").setValue(nowtime) break }
GASでおんどとりWeb Storage APIを利用する。
Python版はこちら
こんどはGASでおんどとりWEB STORAGE APIを利用してみた。
function temps(){ const url = "https://api.webstorage.jp/v1/devices/current" const api_key = "【API_KEY】" const login_id ="【ID】" const password = "【PASSWORD】" const furo_temp = () => { var paylord = {'api-key':api_key,"login-id":login_id,'login-pass':password} var headers = { "X-HTTP-Method-Override":'GET', "Content-Type" : "application/json",} var options = { "method" : "post", "payload" : JSON.stringify(paylord), "headers" : headers, "muteHttpExceptions":true } return UrlFetchApp.fetch(url,options); } return JSON.parse(furo_temp()) } Logger.log(temps())
後はお好きにすると良いと思います。
家で一番簡単にSpotifyをブロードキャストする方法
以前はChromecast Audioという物があったのですが、現在は販売停止になっていて結構高くなっちゃってたので。
必要なもの
1.Chromecast (5,000円くらい)
2.HDMI分離器 (2,500円くらい)
この2個があれば後はGoogle Homeでオーディオグループを作成するだけ。
意外と簡単に行けたのでオススメ
AsteriskとOG410Xaをつなぐ
長かった・・・
結論からいうと
ID:10(内線番号)
Pass:なし
でsip.confに書くだけっぽい。
これでOG410Xaがよしなにやってくれるみたいだった。
あとはExtensions.confに外線発信用のコンテクストを書くだけ、だと思う。
ということで
【OG410Xa側】
ここはid:admin Pass:akisky-HARUSKY48
これで管理画面にログインし、
『電話設定』→『着信番号設定』を
以上のようにする。
するとIP Phone2に着信が飛ぶようになる。
OG側の設定はこれくらい。あとはDHCP除外設定でAsteriskサーバーのIPアドレスを固定にしておくと後で何かと楽にはなる。
【Asterisk側】
sip.conf
[general] maxexpirey=3600 defaultexpirey=3600 context=default bindport=5060 bindaddr=0.0.0.0 srvlookup=yes disallow=all allow=ulaw allow=alaw allow=gsm language=ja canreinvite = no match_auth_username=yes defaultexpiery=3600 maxexpiery=3600 register => 11:pass@192.168.1.1/800 [asterisk] type=friend username=1000 canreinvite=no context=front insecure=port,invite host=【AsteriskのIPアドレス】 dtmfmode=auto allowsubscribe=no
192.168.1.1は デフォルトゲートウェイのIPアドレス。
register =>11:pass@~/800
というところだがこれで内線電話としてAsteriskが登録される。800は登録されたOG410から着信があった場合の着信番号を記述する
extensions.confも普通に
[inandout] exten => 800,1,Dial(SIP/100,30,tT) exten => 800,n,Hangup() exten => _0.,1,Set(CALLERID(num)=${MYNUMBER}) exten => _0.,n,Set(CALLERID(name)=${MYNUMBER}) exten => _0.,n,Dial(SIP/${EXTEN}@asterisk,120,T)
こんな感じでコンテキストをDefaultとかに追記するくらいでOK。
このままだと無限に外線が取れるのでsip.confに
[example] type = friend username= 【username】 secret = 【password】 host=dynamic dtmfmode=auto context = front nat=force_rport,comedia call-limit = 1
と call-limitの表記をつけて1つ以上取れないようにすればOK。ただしgeneralに表記せず、各sipアカウントの中に入れて記述しないと反映されない。