Arduino和Node.js的结合使我们可以做很多意外的事情。 在本文中,我将展示如何通过Arduino,Node.js和AppleScript为Mac创建一个远程控件。
如果您不熟悉Arduino和Node.js的结合使用,那么我之前已经介绍过打开LED灯并在LCD文本显示器上显示Web API数据 。
我们的Arduino遥控器将增加或减少Mac的音量,告诉Mac播放我们选择的iTunes播放列表,并将其设置为停止iTunes上正在播放的任何内容(很可能就是该播放列表!)。
请记住,此演示可直接在Mac上提供对命令的访问-如果您提供过多的访问权限,则有可能被滥用或损坏! 保留供个人使用,而不要用于大型公司项目。
设置我们的Arduino
确保您已经在自己的Arduino板上安装了StandardFirmata草图,因为我们将使用johnny-five库向Arduino发送指令。 仅在首先安装StandardFirmata的情况下,这才起作用:
我们为该演示设置的Arduino面包板如下所示:
我们的服务器代码
对于此演示,我们的Node.js服务器代码相对较短,也很不错:
var five = require('johnny-five'),
board = new five.Board(),
exec = require('child_process').exec,
btn1, btn2, btn3, btn4, btn5,
currentVolLevels = {};
board.on('ready', function() {
console.log('Arduino board is ready!');
btn1 = new five.Button(7);
btn2 = new five.Button(6);
btn3 = new five.Button(5);
btn4 = new five.Button(4);
btn5 = new five.Button(3);
btn1.on('down', function(value) {
askiTunes('play playlist \"Top 25 Most Played\"');
});
btn2.on('down', function(value) {
askiTunes('stop');
});
btn3.on('down', function(value) {
setVolumeLevel(currentVolLevels['output volume'] + 5);
});
btn4.on('down', function(value) {
setVolumeLevel(currentVolLevels['output volume'] - 5);
});
btn5.on('down', function(value) {
toggleMute();
});
getVolumeLevels();
});
function getVolumeLevels() {
exec("osascript -e 'get volume settings'", function(err, stdout, stderr) {
if (!err) {
var levels = stdout.split(', ');
levels.forEach(function(val,ind) {
var vals = val.split(':');
if (vals[1].indexOf('true') > -1) currentVolLevels[vals[0]] = true;
else if (vals[1].indexOf('false') > -1) currentVolLevels[vals[0]] = false;
else currentVolLevels[vals[0]] = parseInt(vals[1]);
});
console.log(currentVolLevels);
}
});
}
function setVolumeLevel(level) {
console.log('Setting volume level to ' + level);
exec("osascript -e 'set volume output volume " + level + "'",
function() {
getVolumeLevels();
});
}
function toggleMute() {
var muteRequest = currentVolLevels['output muted'] ? 'without' : 'with';
console.log('Toggling mute to ' + muteRequest + ' muted');
exec("osascript -e 'set volume " + muteRequest + " output muted'", function() {
getVolumeLevels();
});
}
function askiTunes(event, callback) {
exec("osascript -e 'tell application \"iTunes\" to "+event+"'", function(err, stdout, stderr) {
console.log('iTunes was just asked to ' + event + '.');
});
}
该守则解释
现在,本文的所有重要部分–所有这些代码意味着什么! 让我们回顾一下如何将所有东西融合在一起。
为了与Arduino开发板接口,我们使用johnny-five。 我们首先通过它来设置我们的johnny-five模块和Arduino开发板。 然后,我们定义变量以存储五个按钮。
var five = require('johnny-five'),
board = new five.Board(),
btn1, btn2, btn3, btn4, btn5,
我们还设置了exec()
函数,该函数使我们能够从Node.js运行AppleScript命令。
exec = require('child_process').exec,
当johnny-five 5让我们知道我们的电路板可以使用时,我们运行一个快速console.log
并定义我们的五个按钮以及它们连接到的Arduino引脚(7、6、5、4和3)。
board.on('ready', function() {
console.log('Arduino board is ready!');
btn1 = new five.Button(7);
btn2 = new five.Button(6);
btn3 = new five.Button(5);
btn4 = new five.Button(4);
btn5 = new five.Button(3);
在每个按钮的down
事件上,我们运行不同的功能。 在第一个按钮上,我们运行askiTunes()
函数,该函数向iTunes发送请求。 就我们而言,它正在请求我们的“播放次数排名前25位”播放列表。
btn1.on('down', function(value) {
askiTunes('play playlist \"Top 25 Most Played\"');
});
askiTunes()
函数使用exec()
函数执行AppleScript的第一部分。 我们所有的AppleScript命令都使用osascript
命令在Node.js中运行。
我们的askiTunes()
函数运行命令osascript -e 'tell application \"iTunes\" to "+event+"'
。 这给了我们一个通用的命令,告诉iTunes做某事。 我们可以通过event
变量来调整某些东西。
完成后,我们将运行console.log
,以便我们知道该事件已被识别。
function askiTunes(event, callback) {
exec("osascript -e 'tell application \"iTunes\" to "+event+"'", function(err, stdout, stderr) {
console.log('iTunes was just asked to ' + event + '.');
});
}
我们的第二个按钮运行相同askiTunes()
函数,但我们通过它的活动stop
,以停止任何当前播放。
btn2.on('down', function(value) {
askiTunes('stop');
});
如果我们有更多的按钮可以玩,我们可以添加按钮来pause
和一个通用的play
事件,该事件将恢复当前队列中的内容。
我们的第三个和第四个按钮通过一个称为setVolumeLevel()
的函数来提高和降低Mac的音量。
btn3.on('down', function(value) {
setVolumeLevel(currentVolLevels['output volume'] + 5);
});
btn4.on('down', function(value) {
setVolumeLevel(currentVolLevels['output volume'] - 5);
});
setVolumeLevel()
使用我们在代码开头定义的对象currentVolLevels
。 该对象存储AppleScript从我们的Mac返回的四个不同值。 此数据的示例如下所示:
{
'output volume': 5,
'input volume': 83,
'alert volume': 100,
'output muted': false
}
如您所见,在该JSON对象中有一个名为'output volume'
。 我们在第三个按钮的音量级别上增加五个(增大),在第四个按钮的音量级别上减小五个(减小),然后将该值传递到函数中以进行更改。
我们的setVolumeLevel()
函数使用AppleScript命令来set volume output volume
以将Mac的音量更改为我们通过的音量。 我们还运行控制台日志,只是为了跟踪音量级别的请求。
function setVolumeLevel(level) {
console.log('Setting volume level to ' + level);
exec("osascript -e 'set volume output volume " + level + "'", function() {
getVolumeLevels();
});
}
运行AppleScript代码后,我们将调用getVolumeLevels()
,这是设置所有currentVolLevels
值并跟踪Mac音量的函数。 在介绍完最后一个按钮之后,我将详细解释。
前面提到的最后一个按钮运行toggleMute()
函数,该函数toggleMute()
我们的Mac静音或取消静音。
btn5.on('down', function(value) {
toggleMute();
});
我们的toggleMute()
函数查看currentVolLevels['output muted']
并使用osascript -e 'set volume without output muted'
来关闭静音,或使用osascript -e 'set volume with output muted'
来关闭osascript -e 'set volume with output muted'
。 如果currentVolLevels['output muted']
为true
,则将关键字设置为'without'
以取消静音。 如果为false
,我们将关键字设置为'with'
以启用静音。
function toggleMute() {
var muteRequest = currentVolLevels['output muted'] ? 'without' : 'with';
console.log('Toggling mute to ' + muteRequest + ' muted');
exec("osascript -e 'set volume " + muteRequest + " output muted'", function() {
getVolumeLevels();
});
}
完成后,此AppleScript调用还将运行getVolumeLevels()
函数。 在此功能中,我们运行osascript -e 'get volume settings'
以获取Mac的当前音量。 它以以下格式返回这些值:
"output volume:5, input volume:83, alert volume:100, output muted:false"
在我们的getVolumeLevels()
我们使用stdout
变量中返回的值,并使用如下代码将其格式化为存储在currentVolLevels
的JSON对象:
function getVolumeLevels() {
exec("osascript -e 'get volume settings'", function(err, stdout, stderr) {
if (!err) {
var levels = stdout.split(', ');
levels.forEach(function(val,ind) {
var vals = val.split(':');
if (vals[1].indexOf('true') > -1) currentVolLevels[vals[0]] = true;
else if (vals[1].indexOf('false') > -1) currentVolLevels[vals[0]] = false;
else currentVolLevels[vals[0]] = parseInt(vals[1]);
});
console.log(currentVolLevels);
}
});
}
JSON转换专门针对我们上面收到的字符串量身定制。 首先,我们通过将每个键/值对在每个逗号之间进行拆分以将其拆分为一个称为levels
的数组来创建一个数组,如下所示:
['output volume:5', 'input volume:83', 'alert volume:100', 'output muted:false']
然后,我们遍历数组中的每个字符串,将其整齐地重新排列到我们的currentVolLevels
JSON对象中。 为此,我们使用:
字符作为拆分器,将每个键/值对拆分为一个名为vals
的数组。 vals[0]
将是每个键,例如output volume
,而vals[1]
包含实际的音量级别值。 我们使用vals[0]
作为JSON对象键,例如currentVolLevels[vals[0]] = something
。
我们需要牢记一个因素,并考虑返回的音量水平。 这些值之一是true / false值(我们的静音/未静音状态),其余的是数字。 所有这些都表示为字符串,需要进行转换。 我们将通过一个简单的if语句查看vals[1]
的值来完成此操作。 我们检查字符串"true"
和字符串"false"
。 如果找到其中一个,则将currentVolLevels
内的相关值设置为匹配的布尔值。 如果都不是,则将字符串解析为一个整数,该整数将表示数字音量级别,并将其存储在currentVolLevels
。
最终结果如下所示:
{
'output volume': 5,
'input volume': 83,
'alert volume': 100,
'output muted': false
}
我们的Package.json文件
在这种情况下,我们的package.json
文件非常简单,主要需要确保已安装了johnny-five和serialport npm模块。
{
"name": "nodemaccontroller",
"version": "1.0.0",
"description": "Code to control your Mac via Node",
"main": "index.js",
"dependencies": {
"johnny-five": "^0.8.76",
"serialport": "^1.7.1"
},
"author": "Patrick Catanzariti"
}
我们的遥控器在行动
使用npm install
上述所有依赖项,确保您的Arduino已连接并运行StandardFirmata草图,然后运行node index.js
。 运行它后,按几个按钮,您应该能够控制Mac! 它正在运行时,在控制台中将如下所示:
其他可能性
如果您不喜欢音乐,或者不使用Mac来播放音乐,则可以将Node.js服务器连接到许多其他AppleScript快捷方式。 这里有一些想法。
启动应用程序
function openCalculator() {
exec("osascript -e 'tell application \"Calculator\" to launch'");
}
打开一个新的查找器窗口
function openFinderWindow() {
exec("osascript -e 'tell app \"Finder\" to make new Finder window'");
}
让您的Mac说话!
function tellMacToSpeak() {
exec("osascript -e 'say \"I am completely operational, and all my circuits are functioning perfectly.\"'");
}
结论
现在,您已经有了制作自己的个人Mac外设的巧妙方法! 如果您想使其作为便携式设备工作,则可以设置websockets,socket.io或基本的HTTP服务器,提供Arduino Wi-Fi或其他远程访问Node.js服务器的方式(或使用其他方式)像“ 粒子光子”或“粒子电子”微控制器 ,然后根据远程命令进行这些exec()
调用(尽管要小心,但是exec()
可能会被误用!)这里有很多机会来执行一些非常有趣的项目!如果您做的很整洁,请在评论中留言或在Twitter( @thatpatrickguy )上与我联系,我很乐意查看!
From: https://www.sitepoint.com/remote-control-mac-node-js-arduino/