-
Notifications
You must be signed in to change notification settings - Fork 16
Initial Commit for Wake On Lan #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tmrobert8
wants to merge
1
commit into
NEEOInc:master
Choose a base branch
from
tmrobert8:NEEO-WOL
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| 'use strict'; | ||
|
|
||
| const debug = require('debug'); | ||
| const BluePromise = require('bluebird'); | ||
| const fs = require('fs') | ||
| const readline = require('readline') | ||
| const os = require('os'); | ||
| const net = require('net'); | ||
| const dgram = require('dgram'); | ||
|
|
||
| const PORT_NUMBER = 9; | ||
| const DEFAULT_IPADDRESS = '255.255.255.255'; | ||
|
|
||
| let wolMap = "wol.map"; | ||
|
|
||
| /** | ||
| * Sets the path to the 'wol.map' file | ||
| */ | ||
| module.exports.setMapPath = (mapPath) => { | ||
| wolMap = mapPath; | ||
| } | ||
|
|
||
| /** | ||
| * Handles button presses for WOL | ||
| */ | ||
| module.exports.onButtonPressed = (deviceid, name) => { | ||
| console.log(`WOL button pressed for ${name}`); | ||
|
|
||
| const addr = parseAddr(name); | ||
| const macAddr = getMacBuffer(addr.macAddress); | ||
|
|
||
| if (macAddr) { | ||
| let magic = Buffer.alloc(102, 0xff); | ||
| for (let i = 6; i < magic.length; i+=6) { | ||
| macAddr.copy(magic, i, 0); | ||
| } | ||
|
|
||
| debug("Sending WOL packet"); | ||
| sendPacket(addr.ipAddress, magic) | ||
| .catch((err) => { | ||
| console.error("Error occurred writing WOL packet. ", err || err.message); | ||
| }); | ||
|
|
||
| } else { | ||
| debug('MAC address was invalid and is ignored - %s', addr.macAddress); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Returns a promise to send the magic packet to the specified IP address | ||
| * @param {any} ipAddress the ipaddress to send to | ||
| * @param {any} magic the magic packet to send | ||
| */ | ||
| function sendPacket(ipAddress, magic) { | ||
| return new BluePromise((resolve, reject) => { | ||
| const socket = dgram.createSocket(net.isIPv6(ipAddress) ? 'udp6' : 'udp4') | ||
| .on('error', (err) => { | ||
| socket.close(); | ||
| reject(err); | ||
| }) | ||
| .once('listening', () => { | ||
| socket.setBroadcast(true); | ||
| }); | ||
|
|
||
| socket.send(magic, 0, magic.length, PORT_NUMBER, ipAddress, (err, res) => { | ||
| socket.close(); | ||
| if (err) { | ||
| reject(new Error("Exception writing the magic packet: " + err)); | ||
| } else { | ||
| resolve(true); | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Discovers devices from the wolMap file. Please note that validation of the | ||
| * address field is not | ||
| */ | ||
| module.exports.discoverWolDevices = () => { | ||
| debug('WOL discovery using %s', wolMap); | ||
|
|
||
| return new BluePromise((resolve, reject) => { | ||
| const devices = []; | ||
|
|
||
| readline.createInterface({ input: fs.createReadStream(wolMap) }) | ||
| .on('line', (line) => { | ||
| const parsedLine = parseLine(line); | ||
| if (parsedLine) { | ||
| var parsedAddr = parseAddr(parsedLine.addr); | ||
| const macAddr = getMacBuffer(parsedAddr.macAddress); | ||
| if (macAddr) { | ||
| debug('WOL discovery call - found %s at %s', parsedLine.name, parsedLine.addr); | ||
| devices.push({ | ||
| id: parsedLine.addr, | ||
| name: parsedLine.name, | ||
| reachable: true | ||
| }); | ||
| } else { | ||
| debug("MAC address is invalid and will be ignored: %s", parsedAddr.macAddress); | ||
| } | ||
| } | ||
| }) | ||
| .on('error', (err) => { | ||
| reject(err); | ||
| }) | ||
| .on('close', () => { | ||
| resolve(devices); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Parses a line from the map file and returns undefined (if the line can't be parsed | ||
| * or an object containing a name and addr field. | ||
| * @param {any} line the line to parse | ||
| */ | ||
| function parseLine(line) { | ||
| if (!line.startsWith("#")) { | ||
| const idx = line.indexOf("="); | ||
| if (idx >= 0) { | ||
| return { | ||
| name : line.substring(0, idx).trim(), | ||
| addr : line.substring(idx + 1).trim().replace(/ /g, '/') | ||
| } | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Parses the string address (found in the wol.map file) to a macAddress/ipAddress | ||
| * @param {any} addr the address field to parse | ||
| */ | ||
| function parseAddr(addr) { | ||
| const idx = addr.indexOf("/"); | ||
| return { | ||
| macAddress: (idx < 0 ? addr : addr.substring(0, idx)).trim(), | ||
| ipAddress: (idx < 0 ? DEFAULT_IPADDRESS : addr.substring(idx + 1)).trim(), | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Parses the String (hex) MAC address to a byte array of integers | ||
| * @param {any} macAddress the max address | ||
| */ | ||
| function getMacBuffer(macAddress) { | ||
| const hexArray = macAddress.split(/[-:]+/); | ||
| if (hexArray.length === 6) { | ||
| const buffer = Buffer.alloc(6); | ||
| for (let i = 0; i < 6; i++) { | ||
| buffer[i] = parseInt(hexArray[i], 16); | ||
| } | ||
| return buffer; | ||
| } | ||
|
|
||
| return undefined; | ||
| } | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| 'use strict'; | ||
|
|
||
| const neeoapi = require('neeo-sdk'); | ||
|
|
||
| console.log('NEEO SDK Example "WakeOnLan"'); | ||
| console.log('------------------------------------------'); | ||
|
|
||
| const controller = require('./controller'); | ||
|
|
||
| /** | ||
| * Uncomment the following line to set the path to the wol map file | ||
| */ | ||
| //controller.setMapPath("device/WakeOnLan/wol.map"); | ||
|
|
||
| const wolDevice = neeoapi.buildDevice('WakeOnLan') | ||
| .setManufacturer('NEEO') | ||
| .addAdditionalSearchToken('WOL') | ||
| .setType('ACCESSOIRE') | ||
| .addButton({ name: 'wol', label: 'Wake Up' }) | ||
| .addButtonHander(controller.onButtonPressed) | ||
| .enableDiscovery({ | ||
| headerText: 'WOL Instructions', | ||
| description: 'Please make sure you add devices to wol.map' | ||
| }, controller.discoverWolDevices); | ||
|
|
||
| function startSdkExample(brain) { | ||
| console.log('- Start server'); | ||
| neeoapi.startServer({ | ||
| brain, | ||
| port: 6336, | ||
| name: 'wake-on-lan', | ||
| devices: [wolDevice] | ||
| }) | ||
| .then(() => { | ||
| console.log('# READY, use the mobile app to search for "WakeOnLan"'); | ||
| }) | ||
| .catch((error) => { | ||
| console.error('ERROR!', error.message); | ||
| process.exit(1); | ||
| }); | ||
| } | ||
|
|
||
| const brainIp = process.env.BRAINIP; | ||
| //const brainIp = '192.168.1.29'; | ||
| if (brainIp) { | ||
| console.log('- use NEEO Brain IP from env variable', brainIp); | ||
| startSdkExample(brainIp); | ||
| } else { | ||
| console.log('- discover one NEEO Brain...'); | ||
| neeoapi.discoverOneBrain() | ||
| .then((brain) => { | ||
| console.log('- Brain discovered:', brain.name); | ||
| startSdkExample(brain); | ||
| }); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| ##################################################################################### | ||
| # This file will provide mappings between devices and their MAC address/IP addresses | ||
| # | ||
| # The format of the file is | ||
| # Device Name=MACAddress[/IPAddress] | ||
| # | ||
| # 1) (Required) The device name will appear on the NEEO remote | ||
| # 2) (Required) The MAC address to send the WOL packet to | ||
| # 3) (Optional) Slash or space followed by the device IP address | ||
| # | ||
| # If IP Address is specified, the WOL packet is sent directly to it. If not | ||
| # specified, the WOL packet will be broadcast to the network | ||
| # | ||
| # Please note that if the MACAddress appears twice (or MAC Address/IP Address combo), | ||
| # the NEEO app will complain of a duplicate when trying to add a device. | ||
| ##################################################################################### | ||
|
|
||
| Example=01:02:03:04:05:06 | ||
| IP Example=01:02:03:04:05:06 192.168.1.111 | ||
| IP Example2=01:02:03:04:05:06/192.168.1.112 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
json example
{
"name": "devicename",
"mac": "macaddress",
"ip": "optional ip address"
}