ããã«ã¡ã¯ãå æ°ã§ãï¼
ç§ã¯æ¥æ¬èªã©ããã好ãã§æ¯æ¥èãã¦ãã¾ãã
ã©ãããè´ãã¦ã¦ä¸çªæ¥½ããã¨æãã¨ãã¯ãã¾ãé»ï¼ããï¼ãèããã¨ãã§ããã
è¯ãé»ã¯ä½åå¹´ãé ã«æ®ããã®ã§ãã
ãKick the verseï¼æè©è¹´ã£é£ã°ãï¼ ã¾ãã§ã¹ãã¬ã¹é£ã°ãã¸ã§ãããã¹ï¼ã
ãï¼
åç´ã«é»ãèãããèãããããã®ã楽ããã®ã§ãèªåã®å·¥å¦åéã®ç¨èªã§
é»ãèããããããã®ã§ããã声ã§é»ãæãã¦ãããã·ã¹ãã ããã£ããé¢ç½ãã¨æã£ã¦ã
ä»åã¯Google Homeã«é ¼ãã¨èªåã§webãµã¤ãããé»ãæ¢ãã¦è¸ãã§ãããIoTã·ã¹ãã ãä½ãã¾ããã
ããããé»ï¼ããï¼ã£ã¦ãªã«ï¼
é»ï¼ãã,ã©ã¤ã ï¼ã¨ã¯ç°¡åã«è¨ãã¨ãåãæ¯é³ã§å¥ã®è¨èãç¹°ãè¿ããã¨ãã§ãã
è¦ããã«ä¸ã®è¡¨ã®æ¨ªåã®è¨èã使ãã¾ãã
ä¾ã¨ãã¦ç§ãåãã¨æã£ãé»ãç´¹ä»ãã¾ãã
ãä¸ç¶²æå°½ REMIX (SHING02, MEISO, CANDLE, SPIN MASTER A-1) - é»è¸åçµåãMEISOãããã¼ã ãã
ãI Got The 天ç¶ã¯ã¤ãã¯ã«ã¯ã¤ãã¼ãMEISOã¯ã«ãã½ãªSchickäºæåï¼ã·ãã¯ã«ã¾ãã°ï¼ãä¼æãã«æ¥ãé¦æ¯ãå¿«æã
é»ãããã¼ï¼ãªãºã ã®åãæ¹ãé³ç¨ï¼ãã¤ããï¼
ã·ã¹ãã ã®ç´¹ä»
ç§ã温ã¾ã£ã¦ããã¨ããã§ä½ã£ãIoTã·ã¹ãã ã®ç´¹ä»åç»ã§ãã
è¨è¨ç¾å ´ã§ä½¿ããé»ã®ãã¤ã¸ã§ã¹ãä»ãã§ãã æã¡åãããªã©ã§ç©æ¥µçã«ä½¿ã£ã¦ããã¾ãããã
ãããã§ä½¿ããªãã©ãã«ãã©ãé
延ãé
·ãã¦æ
å ±æ ¼å·®ãä¸ä»£äº¤ä»£iCouplerããããæ£ããéçºã ãYeah...ã
ããã¯ä¾¿å©ã§ããããªããªãå®ç¨æ§ã®ããã·ã¹ãã ã«ãªã£ãæãããã¾ãã
æåã§æ¤ç´¢ããå ´åã¨æ¯ã¹ãã¡ãªããã¯ãé³å£°å
¥åãªã®ã§æåå
¥åä¸è¦ã¨ãããã¨ã
声ã§å
¥åãçµæã声ã§èããã¨ã§é³ã®ã¤ã¡ã¼ã¸ãæ£ç¢ºã«ææ¡ã§ãããã¨ã§ããã
ãã¡ãªããã¯ãå¢è³è©è©ããªã©ã®è¤éãªåèªã¯é³ãèããã ãã§ã¯ç解ã§ããªããã¨ã§ããã
ä¸å¿ãraspberry Piã«SSHã§æ¥ç¶ããã°ä»¥ä¸ã®ããã«çµæãã¢ãã¿ã¼ããäºãåºæ¥ã¾ãã
(声ã®åçããå
ã«çµæãã§ã¾ã)
ããããæ¯æèµ·ãæãã«ä½¿ã£ã¦é»ã®ã¬ãã¼ããªã¼ãå¢ããã¦ããããã§ããã
æè¡è§£èª¬
åç»å ã«ããã£ãæ¦è¦å³ã§ãã
ãâ ãGoogle Homeã声ãèªèãé»åå·¥ä½ãã¸æåå¤æãIFTTTã«éä¿¡ã
ãâ¡ãIFTTTã¯æåãWeb hooksã§Azureã¸POST転é
ãâ¢ãAzureã¯webãµã¼ãã¼ã¨ãã¦ãã¯ã©ã¤ã¢ã³ãï¼RaspberryPiï¼ã«æåæ
å ±ãé»åå·¥ä½ãã転é
ãâ£ãRaspberry Piã¯æåæ
å ±ãé»ãã¼ãã«éä¿¡ãã¦çµæãæåæ
å ±ã§åãåãã
ãâ¤ãåãåã£ãå
¥åã¨é»ãGoogle Homeã«éä¿¡ãåã£ã¦ãããã
æ¬ã·ã¹ãã ã§ã¯webãµã¼ãã¹ãé»ãã¼ããã§é»ãæ¤ç´¢ãã¦ãã¾ãã
é»ãã¼ãã§ã¯å½¢æ
ç´ è§£æãwebã¯ã¼ãã®èªååæã«ãããé«ã精度ã¨ææ°ã®èªå½ã§é»ãè¸ãã§ãããã¨ã®ãã¨ã§ãã
æåã¨é³ã¨ã®ç¸äºå¤æã¨ããç¹ã§ãé»ãã¼ãã¨Google Homeã¯ããªãé«åº¦ãªè§£æããã¦ãã¾ãã
â ã§ã¯é³å£°ã®ãã§ãããããããããé»åå·¥ä½ãã«å¤æãâ£ã®é»ãã¼ãå
é¨ã§ã¯ãé»åå·¥ä½ãããã§ãããããããã«æ»ãã¦é³ã解æãé»ãæ¤ç´¢ãã¦ã¾ããé»ãã¼ãããæ¼¢åã®çµæãåãåããâ¤ã§Google Homeã¯ãã¦ããã¨ã ãããã¨ããé³ã«ã¾ãå¤æãã¦çºå£°ãã¦ãã¾ãã
æè¡ã®é²æ©ã¯åãã§ããã»ã»ã»
ã¡ãªã¿ã«é»ãã¼ãã¯ã²ãããªã®çµæãè¿ãã¦ãããã®ã§ãããæ¼¢åã®æ¹ãã¢ã¯ã»ã³ããªã©ãæ£ç¢ºã«ãªãã¨èãã¦Google Homeã«ã¯æ¼¢åã§éã£ã¦ãã¾ããï¼å¢è³è©è©ã¨è¿è¤æ¥èãã¡ããã¨èªãããã¨ã¯é©ãã¾ããï¼
ããããAzureã®ã¯ã©ã¦ãwebãµã¼ãã¼ãéã«ç½®ãã¦ããã®ã¯ã
ç§ã®ä½å¦ã¯éåä½å®
ã§ã»ãã¥ãªãã£ããã¼ãè¨å®ã®åé¡ãããããã
RaspberryPiãwebãµã¼ãã¼ã¨ãã¦å
¬éããããªãã£ãããã§ãã
ã½ã¼ã¹ã³ã¼ãã¨è§£èª¬
IFTTT
IF : Google Assistant
THEN : Webhooks
Tokenãæã¤POSTã ãå¾æ®µã§åãä»ãããã¾ãã
ãªããã®Tokenã¯ç¾å¨ç¡å¹ã§ãã
Azureã®webãµã¼ãã¼
ãµã¼ãã¼ãµã¤ãã®å
¨ã³ã¼ãã§ãã説æã¯ã³ã¡ã³ããã覧ãã ããã
ååã®ãã¢ã¤ã¢ã¤æ©è½ãã®èªè¨¼ãå
¥ã£ã¦ãã¾ãã
// ãã®ããã°ã©ã ã¯IFTTTããæ¥ããã¼ã¿ãSocketIOãéãã¦æ©è½ãã¨ã«å²ãå½ã¦ãããã¯ã©ã¤ã¢ã³ãã«éä¿¡ããã // IFTTTã¯ãã¼ã¯ã³ããã¼ã¿ã¨å ±ã«éä»ãã¦èªè¨¼ããã // ã¯ã©ã¤ã¢ã³ãã¯ã¾ãPOSTã¡ã½ããã§èªè¨¼ç¨ãã¼ã¯ã³ãéãããµã¼ãã¼ãèªè¨¼ãæ©è½ç¨ãã¼ã¯ã³(JWT)ãè¿ãã // ã¯ã©ã¤ã¢ã³ãã¯ãã®æ©è½ç¨ãã¼ã¯ã³ãç¨ãã¦socketIOãæ¥ç¶ããã var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var bodyParser = require('body-parser'); var jwt = require("jsonwebtoken"); // èªè¨¼ç¨ãã¼ã¯ã³ãIFTTTåã³ã¯ã©ã¤ã¢ã³ãããåããã¼ã¯ã³ãéããã¦æ¥ãå ´åã®ã¿æ¬ããã°ã©ã ã¯åä½ãã const authToken = "D462253D54FB3C4BE77AE1992341A279"; const jwtKey = authToken; const funcs = { aiai: "aiai", getRyme: "getRyme" }; // setting body pearser app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); //Azureã«ã¢ãããã¼ãããã¨ãã¯PORTãç°å¢å¤æ°ã§æ±ºãããããå¿ ãä¸è¨ãå¿ è¦ã«ãªãã var port = process.env.PORT || 8080; //IFTTTããã®ãã¼ã¿åä¿¡ app.post(`/ifttt`, (req, res) => { console.log('IFTTT posted!' + req); //check token (authenticated User) if (req.body.token == authToken) { const func = req.body.func; //ã¢ã¤ã¢ã¤æ©è½ if (func == funcs.aiai) { req.body.name = req.body.name.trim(); var check = req.body.name; var sendData; // verify word from IFTTT(google home) if (check == "II" || check == "ii" || check == "Iæ" || check == "I æ" || check == "iæ") { sendData = "ã¢ã¤ã¢ã¤"; } else { sendData = req.body.name; } } //ã©ã¤ã ãå¾ãæ©è½ else if (func == funcs.getRyme) { sendData = req.body.origin.replace(/\s+/g, "");; } // send to raspberry pi to specific socket.IO rooom io.to(func).emit('ifttt', sendData); } }); //ã¯ã©ã¤ã¢ã³ãããã®functionãã¼ã¯ã³åå¾ä¾é ¼ãå¦ç app.post(`/aiai`, (req, res) => { processToken(funcs.aiai, req, res) }); app.post(`/getRyme`, (req, res) => { processToken(funcs.getRyme, req, res) }); //èªè¨¼ã¨é¢æ°ç¨ãã¼ã¯ã³ã®çºè¡ï¼ãã¼ã¯ã³ã®funcã§socket.ioã®ã«ã¼ã å²ãå½ã¦ã決ã¾ãï¼ function processToken(func, req, res) { //send token if (req.body.authToken == authToken) { //ãã¼ã¯ã³ã«ã¯æ©è½ã¨ã¦ã¼ã¶ã¼åï¼æªä½¿ç¨ï¼ãå«ããã var funcToken = jwt.sign({func:func, user:req.body.user}, jwtKey, { expiresIn: '24h' }); res.send(funcToken); } else { res.send("err"); } } //æ¥ç¶å æãã¯ã©ã¤ã¢ã³ãã®ãã¼ã¯ã³ã確èªãã¦å¯¾å¿ããã«ã¼ã ã«joinãããã io.sockets.on('connection', (socket) => { jwt.verify(socket.handshake.query.token, jwtKey, (err, decoded) => { if (err) { //ã¨ã©ã¼ã¡ãã»ã¼ã¸ãè¿ã socket.emit('join', { data: "error" }); console.log('connection error:' + err); } else { //æ£è¦ã®ãã¼ã¯ã³ãåä¿¡ socket.join(decoded.func); socket.emit('join', { data: "welcome function:" + decoded.func }); console.log('room joined! func:' + decoded.func); } }); }); //start server http.listen(port, function () { console.log('listening on *:' + port); });
ã¯ã©ã¤ã¢ã³ãï¼RaspberryPiï¼
ã¯ã©ã¤ã¢ã³ããµã¤ãã®ã½ã¼ã¹å
¨æã§ãã
ä»åã¯ã¢ã¤ã¢ã¤ã®æã¨éã£ã¦ãé»ãã¼ãã«RestAPIããªãããã
puppeteerã¨ããwebãã©ã¦ã¶ãã³ã³ããã¼ã«ãã
ã©ã¤ãã©ãªã使ã£ã¦ãã©ã¦ã¶æä½ãã¨ãã¥ã¬ã¼ããã¦é»ã®æ¤ç´¢çµæãå¾ã¾ããã
ã¾ããpuppeteerãRaspberry Piã§æ±ãä¸ã§ãããããã¤ã³ãã¯å¥ã®è¨äºã«ã¾ã¨ãã¦ãã¾ãã
(ãªããçµæã®å¿çã10ç§ç¨åº¦ã¨é·ãã£ã主è¦å ã¯puppeteerã®å¦çãRaspberryPiã«ã¨ã£ã¦éãã£ãããã§ããã¾ãé»ãäºæ³ãã¦æ¥½ããæéã ã¨æãã°è¯ãã§ãã)
// ãã®ããã°ã©ã ã¯webãµã¼ãã¼ã«POSTã§èªè¨¼ãã¼ã¯ã³ãéä¿¡ããæ©è½ãã¼ã¯ã³ãåãåãã // æ©è½ãã¼ã¯ã³ãSocketIOã§æ¸¡ãããµã¼ãã¼ã¨æ¥ç¶ããã // æ¥ç¶ãããµã¼ãã¼ãããªãªã¸ãã«ã®æåãåãåããpuppeteerã§é»ãã¼ãã¸éä¿¡ãçµæãåãåã // google-home-notifierã§Google Homeã¸éä¿¡ããã // google home settings var googlehome = require('google-home-notifier'); var language = 'ja'; googlehome.ip('192.168.123.45'); googlehome.device('Google Home', language); // server settings const BaseUrl = 'https://iotwebappraiot.azurewebsites.net/'; const aiaiUrl = BaseUrl + 'getRyme/'; const authQuery = { authToken: "D462253D54FB3C4BE77AE1992341A279", user: "nullo" } // InNote setting const addressOfInNote = 'http://in-note.com/'; // serverããæ©è½ãã¼ã¯ã³ãå¾ã const axios = require('axios'); axios.post(aiaiUrl, authQuery) .then((res) => { if (res.data != "err") { //ãµã¼ãã¼èªè¨¼ç¨ã¯ã¨ãªã«æ©è½ãã¼ã¯ã³ãè¨å® let funcQuery = { query: { token: res.data } }; //ã½ã±ããéä¿¡éå§ startSocket(funcQuery); } else { console.log('auth error:', err); } }) .catch(err => { console.log('err:', err); }); // socket.IOéä¿¡ã®éå§ã¨ã¤ãã³ãç»é² function startSocket(funcQuery) { // socket IOãæ¥ç¶å ï¼Azureãµã¼ãã¼ï¼æå®ã§èªã¿è¾¼ã const io = require('socket.io-client'); let socket = io(BaseUrl, funcQuery); // æ©è½ãã¼ã¯ã³ã®èªè¨¼çµæããµã¼ãã¼ããè¿ã£ã¦ãã socket.on('join', (result) => { console.log("join:" + result.data); }); socket.on('ifttt', (origin) => { console.log("\nI received original word:\n" + origin + "\n"); // ãµã¼ãããåãåã£ãèªå¥ãwebãµã¼ãã¹ã®é»ãã¼ãã«éããé»ãåãåã (async () => { const say = await getAndModifyRyme(origin) .catch(() => 'ããããé»ãè¦ã¤ãããªãã£ãã'); sayGoogleHome(say); })(); }); } //sayã®å 容ãgoogle homeã¸éä¿¡ãããï¼è©±ãããï¼ function sayGoogleHome(say) { try { googlehome.notify(say, (res) => { console.log(res); }); //error } catch (err) { console.log(err); } } // é»ãã¼ãã«originããé»ãå¾ã¦ãçºè©±å 容ã«å å·¥ããã async function getAndModifyRyme(origin) { label = "exec" console.time(label); getRyme = new ScrapeRymeInNote(); let data = await getRyme.scrapeRhyme(origin, addressOfInNote); let say = origin + "\n"; for (let i = 0; i < data.length; i++) { say += (i + 1) + ": " + data[i] + "ã(" + data[i] + ")\n"; } console.log(say); console.timeEnd(label); return say; } //ãé»ãã¼ãããã¹ã¯ã¬ã¤ãã³ã°ããã¯ã©ã¹ class ScrapeRymeInNote { //ãã¢ã¯ã»ã¹ async _initPuppeteer(puppeteer, address) { const browser = await puppeteer.launch({ headless: true, executablePath: '/usr/bin/chromium-browser', args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); await page.goto(address, { waitUntil: "domcontentloaded" }); return { page: page, browser: browser }; } //ããã¼ã¿å ¥æ async _getRhyme(origin, page) { await page.type("body > div.main > div.main-search > div > input", origin);//ãããã¹ãå ¥å //æ¤ç´¢ãã¿ã³ã¯ãªã㯠await page.evaluate(() => { document.querySelector("body > div.main > div.main-search > div > button").click(); }); await page.waitFor('span[class="word-main"]', { timeout: 10000 });// ç»é¢é·ç§»ãå¾ ã¤ // çµæã®ããã¹ããå ¥æ let data = await page.$$eval('span.word-main', items => { // å¾ãè¤æ°ã®çµæãé ååãã¦è¿ã const resultNumber = 4; let texts = []; for (let i = 0; i < resultNumber; i++) { if (items[i]) { texts.push(items[i].textContent); } } return texts; }); return data; } //originãã¼ã¯ã¼ãããé»ãå ¥æããå ¬éé¢æ° async scrapeRhyme(origin, address) { const puppeteer = require('puppeteer'); const pupp = await this._initPuppeteer(puppeteer, address); let data = await this._getRhyme(origin, pupp.page); await pupp.browser.close(); return data; } }
ã¾ã¨ã
- é³å£°æä½ã§é»ãé³å£°ã§è¿ãã¦ãããIoTã·ã¹ãã ãä½ã£ãã
- é»ããã®ç¹°ãè¿ãã¯ããã°ã©ãã³ã°ã人çã«éãããã®ãããã
- ããããèªåã®é»ã®ã¬ãã¼ããªã¼ãå¢ããã¦ããããã
質åãªã©æãã°ã³ã¡ã³ãé ããã°ã¨åãã¾ãã
ããã§ã¯ï¼