使用Node.js和Arduino远程控制Mac

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上安装标准固件

我们为该演示设置的Arduino面包板如下所示:

我们的Arduino Mac遥控器的草图

我们的服务器代码

对于此演示,我们的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! 它正在运行时,在控制台中将如下所示:

我们的Arduino遥控器在行动

我们的Arduino遥控器在行动

其他可能性

如果您不喜欢音乐,或者不使用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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值