Google智能机顶盒Volume trait报错求助及示例代码需求
问题:Set-top Box添加Volume trait时同步报错
我已依据Google官方文档为Set-top Box实现了Smart Home Actions,尝试添加action.devices.traits.Volume trait时出现报错:

以下是我的云函数代码,恳请提供action.devices.types.SETTOP的完整示例代码,我查阅大量资料仍无法解决该问题。
'use strict'; const functions = require('firebase-functions'); const {smarthome} = require('actions-on-google'); const {google} = require('googleapis'); const util = require('util'); const admin = require('firebase-admin'); // Initialize Firebase admin.initializeApp(); const firebaseRef = admin.database().ref('/'); // Initialize Homegraph const auth = new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/homegraph'], }); const homegraph = google.homegraph({ version: 'v1', auth: auth, }); // Hardcoded user ID const USER_ID = '123'; exports.login = functions.https.onRequest((request, response) => { if (request.method === 'GET') { functions.logger.log('Requesting login page'); response.send(` <!DOCTYPE html> <html> <head> <title>Page Title</title> </head> <body> <h1>Account Linking</h1> <form action="/login" method="post"> <input type="hidden" name="responseurl" value="${request.query.responseurl}" /> <button type="submit" style="background-color: #4CAF50; /* Green */ border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px;"> Clik to link your device </button> </form> </body> </html> `); } else if (request.method === 'POST') { // Here, you should validate the user account. // In this sample, we do not do that. const responseurl = decodeURIComponent(request.body.responseurl); functions.logger.log(`Redirect to ${responseurl}`); return response.redirect(responseurl); } else { // Unsupported method response.send(405, 'Method Not Allowed'); } }); exports.fakeauth = functions.https.onRequest((request, response) => { const responseurl = util.format('%s?code=%s&state=%s', decodeURIComponent(request.query.redirect_uri), 'xxxxxx', request.query.state); functions.logger.log(`Set redirect as ${responseurl}`); return response.redirect( `/login?responseurl=${encodeURIComponent(responseurl)}`); }); exports.faketoken = functions.https.onRequest((request, response) => { const grantType = request.query.grant_type ? request.query.grant_type : request.body.grant_type; const secondsInDay = 86400; // 60 * 60 * 24 const HTTP_STATUS_OK = 200; functions.logger.log(`Grant type ${grantType}`); let obj; if (grantType === 'authorization_code') { obj = { token_type: 'bearer', access_token: '123access', refresh_token: '123refresh', expires_in: secondsInDay, }; } else if (grantType === 'refresh_token') { obj = { token_type: 'bearer', access_token: '123access', expires_in: secondsInDay, }; } response.status(HTTP_STATUS_OK) .json(obj); }); const app = smarthome(); const boxDetails = [{ id: 'washer', type: 'action.devices.types.SETTOP', traits: [ 'action.devices.traits.OnOff', 'action.devices.traits.Volume', ], name: { defaultNames: ['Test TV'], name: 'Test TV', nicknames: ['Test TV'], }, deviceInfo: { manufacturer: 'Test', model: 'Test', hwVersion: '1.0', swVersion: '1.0.1', }, willReportState: true, attributes: { pausable: true, }, }] app.onSync((body) => { return { requestId: body.requestId, payload: { agentUserId: USER_ID, devices: boxDetails, }, }; }); const queryFirebase = async (deviceId) => { const snapshot = await firebaseRef.child(deviceId).once('value'); const snapshotVal = snapshot.val(); return { on: snapshotVal.OnOff.on, volumeLevel: 20 }; }; const queryDevice = async (deviceId) => { const data = await queryFirebase(deviceId); return { on: data.on, currentVolume : 20, }; }; app.onQuery(async (body) => { const {requestId} = body; const payload = { devices: {}, }; const queryPromises = []; const intent = body.inputs[0]; for (const device of intent.payload.devices) { const deviceId = device.id; queryPromises.push(queryDevice(deviceId) .then((data) => { payload.devices[deviceId] = data; }, )); } await Promise.all(queryPromises); return { requestId: requestId, payload: payload, }; }); const updateDevice = async (execution, deviceId) => { functions.logger.info(`deviceId ${deviceId}`); const {params, command} = execution; let state; let ref; switch (command) { case 'action.devices.commands.OnOff': state = {on: params.on}; ref = firebaseRef.child(deviceId).child('OnOff'); break; case 'action.devices.commands.setVolume': state = {currentVolume: params.volumeLevel}; ref = firebaseRef.child(deviceId).child('Volume'); break; } return ref.update(state) .then(() => state); }; app.onExecute(async (body) => { const {requestId} = body; const result = { ids: [], status: 'SUCCESS', states: { online: true, }, }; const executePromises = []; const intent = body.inputs[0]; for (const command of intent.payload.commands) { for (const device of command.devices) { for (const execution of command.execution) { executePromises.push( updateDevice(execution, device.id) .then((data) => { result.ids.push(device.id); Object.assign(result.states, data); }) .catch(() => functions.logger.error('EXECUTE', device.id)), ); } } } await Promise.all(executePromises); return { requestId: requestId, payload: { commands: [result], }, }; }); app.onDisconnect((body, headers) => { functions.logger.log('User account unlinked from Google Assistant'); return {}; }); exports.smarthome = functions.https.onRequest(app); exports.requestsync = functions.https.onRequest(async (request, response) => { response.set('Access-Control-Allow-Origin', '*'); functions.logger.info(`Request SYNC for user ${USER_ID}`); try { const res = await homegraph.devices.requestSync({ requestBody: { agentUserId: USER_ID, }, }); functions.logger.info('Request sync response:', res.status, res.data); response.json(res.data); } catch (err) { functions.logger.error(err); response.status(500).send(`Error requesting sync: ${err}`); } }); exports.reportstate = functions.database.ref('{deviceId}').onWrite( async (change, context) => { functions.logger.info('Firebase write event triggered Report State'); const snapshot = change.after.val(); const requestBody = { requestId: 'ff36a3cc', agentUserId: USER_ID, payload: { devices: { states: { [context.params.deviceId]: { on: snapshot.OnOff.on, volumeLevel : 40, }, }, }, }, }; const res = await homegraph.devices.reportStateAndNotification({ requestBody, }); functions.logger.info('Report state response:', res.status, res.data); }); exports.updatestate = functions.https.onRequest((request, response) => { firebaseRef.child('set-to-box').update({ OnOff: { on: request.body.on, }, Volume:{ volumeLevel :40, } }); return response.status(200).end(); });
内容的提问来源于stack exchange,提问作者Ramesh S
相关产品推荐
相关产品推荐

