Skip to content

Commit

Permalink
Improved hub discovery
Browse files Browse the repository at this point in the history
Supporting multiple hubs when scanning in configuration node
  • Loading branch information
Aietes committed Aug 23, 2018
1 parent fcc399b commit 45147a7
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 219 deletions.
65 changes: 49 additions & 16 deletions harmony/harmony-server.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
<input type="text" id="node-config-input-name" />
</div>
<div class="form-row">
<label for="node-config-input-ip"><i class="fa fa-server"></i> IP</label>
<input type="text" id="node-config-input-ip" style="width: 60%;"/>
<a id="node-config-input-scan" class="editor-button"><i class="fa fa-search"></i></a>
<label for="node-config-input-ip-select"><i class="fa fa-server"></i> Hubs</label>
<select id="node-config-input-ip-select" style="width: 60%;"></select>
<a id="node-config-input-select-trigger" class="editor-button"><i class="fa fa-search"></i></a>
</div>
<div class="form-row">
<label for="node-config-input-ip"><i class="fa fa-server"></i> IP</label>
<input type="text" id="node-config-input-ip" style="width: 60%;"/>
</div>
</script>

Expand All @@ -21,18 +25,47 @@
return this.name ? this.name : "Harmony Server";
},
oneditprepare: function() {
$('#node-config-input-scan').click(function() {
$.get( 'harmony/server')
.done( function(data) {
var ip = JSON.parse(data);
$('#node-config-input-ip').append('<option value="' + ip + '">' + ip + '</option>');
$('#node-config-input-ip').val(ip);
RED.notify("Harmony Hub with IP " + ip + " found.");
})
.fail(function() {
RED.notify("Something went wrong discovering an Harmony Hub", "error");
});
});

function scanForHubs(selected_ip){
$('#node-config-input-select-trigger').addClass('disabled')
$('#node-config-input-ip-select').attr('disabled', 'disabled')
$('#node-config-input-ip-select').append("<option value='' selected>Scanning for hubs...</option>")
$.get( 'harmony/server')
.done( function(data) {
var hubs = JSON.parse(data);
$('#node-config-input-ip-select').empty()
if(!hubs || hubs.length <= 0) {
$('#node-config-input-ip-select').append("<option value='' selected>No hubs</option>")
RED.notify("No hubs found.", "error")
} else {
hubs.forEach(function(hub){
$('#node-config-input-ip-select').append('<option value="' + hub.ip + '">' + hub.ip + '</option>')
})
if( selected_ip ){
$('#node-config-input-ip-select').val(selected_ip)
}else{
$('#node-config-input-ip').val( $('#node-config-input-ip-select option:first').val() )
}
$('#node-config-input-ip-select').removeAttr('disabled')
}
$('#node-config-input-select-trigger').removeClass('disabled')
})
.fail(function() {
RED.notify("Something went wrong discovering an Harmony Hub", "error")
})
}

scanForHubs(this.ip)

$('#node-config-input-select-trigger').click(function() {
if(!$('#node-config-input-select-trigger').hasClass('disabled')){
scanForHubs(this.ip)
}
})

$('#node-config-input-ip-select').on('change', function() {
$('#node-config-input-ip').val($('#node-config-input-ip-select').val())
})
}
});
})
</script>
56 changes: 51 additions & 5 deletions harmony/harmony-server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const HarmonyHubDiscover = require('@harmonyhub/discover').Explorer
var harmonyClient = require('@harmonyhub/client').getHarmonyClient
var events = require('events')
var netstat = require('node-netstat')

module.exports = function (RED) {
function HarmonyServerNode (n) {
Expand All @@ -21,6 +22,47 @@ module.exports = function (RED) {
}
RED.nodes.registerType('harmony-server', HarmonyServerNode)

var getNextAvailablePort = function (portRangeAsString) {
var portString = process.env.USE_PORT_RANGE || portRangeAsString

if (portString) {
var portStart, portLast

portStart = parseInt(portString.split('-')[0])
portLast = parseInt(portString.split('-')[1])

var portArr = []

netstat({
sync: true,
filter: {
local: {
address: null
}
}
}, portArr.push.bind(portArr))

portArr = portArr.map(
portInfo => portInfo.local.port
).filter(
// filter port range and also the index to eliminate duplicates
(portNr, index, arr) => portNr >= portStart && portNr <= portLast && arr.indexOf(portNr) === index
)

if (portArr.length > portLast - portStart) {
throw new Error('No available port in the range ' + portString)
} else {
for (var i = portStart; i <= portLast; ++i) {
if (portArr.indexOf(i) < 0) {
return i
}
}
}
} else {
return 0
}
}

function createClient (node) {
var harmony = node.harmony
var ip = node.ip
Expand All @@ -45,15 +87,19 @@ module.exports = function (RED) {
}

RED.httpAdmin.get('/harmony/server', function (req, res, next) {
const discover = new HarmonyHubDiscover(61991)
const discover = new HarmonyHubDiscover(getNextAvailablePort('5000-6000'))
var hubsFound

discover.on('online', function (hub) {
res.end(JSON.stringify(hub.ip))
discover.stop()
discover.on('update', function (hubs) {
hubsFound = hubs
})

// search for hubs for 3 seconds, then return result
discover.start()
setTimeout(discover.stop, 5000)
setTimeout(function () {
discover.stop()
res.end(JSON.stringify(hubsFound))
}, 3000)
})

RED.httpAdmin.get('/harmony/activities', function (req, res, next) {
Expand Down
12 changes: 6 additions & 6 deletions harmony/harmony.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<script type="text/x-red" data-help-name="H command">
<p>A node to send a <b>Command</b> to a Harmony Hub through Node-RED.</p>
<p>
A Harmony <i class="fa fa-server" /> <b>Hub</b> needs to be selected from the list or created by clicking on the edit button. The Harmony Hub
<b>IP</b> address can be autodetected by clicking on the search button in the configuration node.
A Harmony <i class="fa fa-server" /> <b>Hub</b> needs to be selected from the list or created by clicking on the edit button, which opens the configuration node. The
<b>IP</b> addresses of available Harmony Hubs will be autodetected, or can be entered manually in the configuration node.
</p>
<p>
An <i class="fa fa-television" /> <b>Activity</b> or <i class="fa fa-television" /> <b>Device</b> that is set up on the Harmony Hub needs to be selected.
Expand Down Expand Up @@ -202,8 +202,8 @@
<script type="text/x-red" data-help-name="H activity">
<p>A node to start an <b>Activity</b> on a Harmony Hub through Node-RED.</p>
<p>
A Harmony <i class="fa fa-server" /> <b>Hub</b> needs to be selected from the list or created by clicking on the edit button. The Harmony Hub
<b>IP</b> address can be autodetected by clicking on the search button in the configuration node.
A Harmony <i class="fa fa-server" /> <b>Hub</b> needs to be selected from the list or created by clicking on the edit button, which opens the configuration node. The
<b>IP</b> addresses of available Harmony Hubs will be autodetected, or can be entered manually in the configuration node.
</p>
<p>
An <i class="fa fa-television" /> <b>Activity</b> that is set up on the Harmony Hub needs to be selected.
Expand Down Expand Up @@ -294,8 +294,8 @@
<script type="text/x-red" data-help-name="H observe">
<p>A node to observe changes of activities for a given Harmony Hub through Node-RED</p>
<p>
A Harmony <b>Hub</b> needs to be selected from the list or created by clicking on the edit button. The Harmony Hub
<b>IP</b> address can be autodetected by clicking on the search button in the configuration node.
A Harmony <i class="fa fa-server" /> <b>Hub</b> needs to be selected from the list or created by clicking on the edit button, which opens the configuration node. The
<b>IP</b> addresses of available Harmony Hubs will be autodetected, or can be entered manually in the configuration node.
</p>
<p>
When an <b>Activity</b> is switched on the Harmony Hub, the node sends an object with a payload to the output:
Expand Down
Loading

0 comments on commit 45147a7

Please sign in to comment.