homebridge-irobot
Version:
A homebridge plugin for controlling iRobot devices
314 lines (311 loc) • 13 kB
HTML
<p class="text-center">
<img src="https://user-images.githubusercontent.com/75853497/143301930-e2f3bc9a-9f0d-4e03-95f8-c69769712ca5.png"
alt="homebridge-irobot logo" style="width: 60%;" />
</p>
<div id="pageIntro" class="text-center" style="display: none;">
<p class="lead">Thank you for installing <strong>homebridge-iRobot</strong></p>
<p>
You can enter your iRobot username and password on the next page
</p>
<button type="button" class="btn btn-primary" id="introContinue">
Continue →
</button>
</div>
<div id="menuWrapper" class="btn-group w-100 mb-0" role="group" aria-label="UI Menu" style="display: none;">
<button type="button" class="btn btn-primary ml-0" id="menuSettings">
Settings
</button>
<button type="button" class="btn btn-primary" id="menuDevices">
Devices
</button>
<button type="button" class="btn btn-primary mr-0" id="menuHome">
Support
</button>
</div>
<div id="disabledBanner" class="alert alert-secondary mb-0 mt-3" role="alert" style="display: none;">
Plugin is currently disabled
<button id="disabledEnable" type="button" class="btn btn-link p-0 m-0 float-right">
Enable
</button>
</div>
<div id="pageDevices" class="mt-4" style="display: none;">
<div id="deviceInfo">
<form>
<div class="form-group">
<select class="form-control" id="deviceSelect"></select>
</div>
</form>
<table class="table w-100" id="deviceTable" style="display: none;">
<thead>
<tr class="table-active">
<th scope="col" style="width: 40%;">Device Name</th>
<th scope="col" style="width: 60%;" id="displayName">Undefined</th>
</tr>
</thead>
<tbody>
<tr style="display: none;">
<th scope="row">Status</th>
<td id="status">Undefined</td>
</tr>
<tr>
<th scope="row">Blid</th>
<td id="blid">Undefined</td>
</tr>
<tr>
<th scope="row">Password</th>
<td id="password">Undefined</td>
</tr>
<tr>
<th scope="row">IP Address</th>
<td id="ip_address">Undefined</td>
</tr>
<tr>
<th scope="row">Model</th>
<td id="model">Undefined</td>
</tr>
<tr>
<th scope="row">Software Version</th>
<td id="sw">Undefined</td>
</tr>
<tr>
<th scope="row">MAC Address</th>
<td id="mac_address">Undefined</td>
</tr>
<tr>
<th scope="row">Room-By-Room Support</th>
<td id="room_by_room">Undefined</td>
</tr>
<tr id="mapCount" style="display:none;">
<th scope="row">Maps</th>
<td id="maps">Undefined</td>
</tr>
<tr id="regionCount" style="display:none;">
<th scope="row">Rooms</th>
<td id="regions">Undefined</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="pageSupport" class="mt-4" style="display: none;">
<p class="text-center lead">Thank you for using <strong>homebridge-iRobot</strong></p>
<p class="text-center">The links below will take you to my GitHub wiki (some wiki links dont work yet)</p>
<h4>Setup</h4>
<ul>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Installation" target="_blank">Installation</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Configuration" target="_blank">Configuration</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Beta-Version" target="_blank">Beta Version</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Node-Version" target="_blank">Node Version</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Uninstallation" target="_blank">Uninstallation</a>
</li>
</ul>
<!--<h4>Features</h4>
<ul>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Supported-Devices" target="_blank">Supported
Devices</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Cloud-Control" target="_blank">Cloud Control</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Local-Control" target="_blank">Local Control</a>
</li>
</ul-->
<h4>Help/About</h4>
<ul>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/wiki/Common-Errors" target="_blank">Common Errors</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/issues/new/choose" target="_blank">Support Request</a>
</li>
<li>
<a href="https://github.com/bloomkd46/homebridge-iRobot/blob/latest/CHANGELOG.md" target="_blank">Changelog</a>
</li>
<!--<li>
<a href="https://github.com/sponsors/bloomkd46" target="_blank">About Me</a>
</li>-->
</ul>
<h4>Credits</h4>
<ul>
<li>To <a href="https://github.com/bwp91/homebridge-meross">homebridge-Meross</a> of which I based this readme,
wiki, and homebridge-ui off of</li>
<li>
To the creators/contributors of
<a href="https://homebridge.io" target="_blank">Homebridge</a> who make this plugin possible.
</li>
<li>To <a href="https://github.com/koalazak/dorita980">Dorita980</a> Who cracked the iRobot API</li>
</ul>
<h4>Disclaimer</h4>
<ul>
<li>
I am in no way affiliated with iRobot and this plugin is a personal project that I maintain in
my free time.
</li>
<li>
Use this plugin entirely at your own risk - please see licence for more information.
</li>
</ul>
</div>
<script>
; (async () => {
try {
const currentConfig = await homebridge.getPluginConfig()
showIntro = () => {
const introContinue = document.getElementById('introContinue')
introContinue.addEventListener('click', () => {
homebridge.showSpinner()
document.getElementById('pageIntro').style.display = 'none'
document.getElementById('menuWrapper').style.display = 'inline-flex'
showSettings()
homebridge.hideSpinner()
})
document.getElementById('pageIntro').style.display = 'block'
}
showDevices = async () => {
homebridge.showSpinner()
homebridge.hideSchemaForm()
document.getElementById('menuHome').classList.remove('btn-elegant')
document.getElementById('menuHome').classList.add('btn-primary')
document.getElementById('menuDevices').classList.add('btn-elegant')
document.getElementById('menuDevices').classList.remove('btn-primary')
document.getElementById('menuSettings').classList.remove('btn-elegant')
document.getElementById('menuSettings').classList.add('btn-primary')
document.getElementById('pageSupport').style.display = 'none'
document.getElementById('pageDevices').style.display = 'block'
const cachedAccessories =
typeof homebridge.getCachedAccessories === 'function'
? await homebridge.getCachedAccessories()
: await homebridge.request('/getCachedAccessories')
if (cachedAccessories.length > 0) {
cachedAccessories.sort((a, b) => {
return a.displayName.toLowerCase() > b.displayName.toLowerCase()
? 1
: b.displayName.toLowerCase() > a.displayName.toLowerCase()
? -1
: 0
})
}
const deviceSelect = document.getElementById('deviceSelect')
deviceSelect.innerHTML = ''
cachedAccessories.forEach(a => {
const option = document.createElement('option')
option.text = a.displayName
option.value = a.UUID
deviceSelect.add(option)
})
showDeviceInfo = async UUID => {
homebridge.showSpinner()
const thisAcc = cachedAccessories.find(x => x.UUID === UUID)
const context = thisAcc.context
document.getElementById('displayName').innerHTML = thisAcc.displayName || 'N/A'
document.getElementById('blid').innerHTML = context.device.blid || 'N/A'
document.getElementById('password').innerHTML = context.device.password || 'N/A'
document.getElementById('status').innerHTML = (context.connected || false)
? '<i class="fas fa-circle mr-1 green-text"></i> Online'
: '<i class="fas fa-circle mr-1 red-text"></i> Offline'
document.getElementById('model').innerHTML = context.device.model || 'N/A'
document.getElementById('ip_address').innerHTML = context.device.ip || 'N/A'
document.getElementById('mac_address').innerHTML = context.device.info.mac || 'N/A'
document.getElementById('sw').innerHRML = context.device.info.sw || 'NA'
document.getElementById('room_by_room').innerHTML = context.device.multiRoom || false
document.getElementById('mapCount').style.display = 'none'
document.getElementById('regionCount').style.display = 'none'
if (context.maps !== undefined) {
document.getElementById('mapCount').style.display = 'table-row'
document.getElementById('maps').innerHTML = context.maps.length || 0
let regions = 0;
for (const map of context.maps) {
if (map.regions !== undefined) {
regions += map.regions.length
}
}
if (regions !== undefined) {
document.getElementById('regionCount').style.display = 'table-row'
document.getElementById('regions').innerHTML = regions
}
}
document.getElementById('deviceTable').style.display = 'inline-table'
homebridge.hideSpinner()
}
deviceSelect.addEventListener('change', event => showDeviceInfo(event.target.value))
if (cachedAccessories.length > 0) {
showDeviceInfo(cachedAccessories[0].UUID)
} else {
const option = document.createElement('option')
option.text = 'No Devices'
deviceSelect.add(option)
deviceSelect.disabled = true
}
homebridge.hideSpinner()
}
showSupport = () => {
homebridge.showSpinner()
homebridge.hideSchemaForm()
document.getElementById('menuHome').classList.add('btn-elegant')
document.getElementById('menuHome').classList.remove('btn-primary')
document.getElementById('menuDevices').classList.remove('btn-elegant')
document.getElementById('menuDevices').classList.add('btn-primary')
document.getElementById('menuSettings').classList.remove('btn-elegant')
document.getElementById('menuSettings').classList.add('btn-primary')
document.getElementById('pageSupport').style.display = 'block'
document.getElementById('pageDevices').style.display = 'none'
homebridge.hideSpinner()
}
showSettings = () => {
homebridge.showSpinner()
document.getElementById('menuHome').classList.remove('btn-elegant')
document.getElementById('menuHome').classList.add('btn-primary')
document.getElementById('menuDevices').classList.remove('btn-elegant')
document.getElementById('menuDevices').classList.add('btn-primary')
document.getElementById('menuSettings').classList.add('btn-elegant')
document.getElementById('menuSettings').classList.remove('btn-primary')
document.getElementById('pageSupport').style.display = 'none'
document.getElementById('pageDevices').style.display = 'none'
homebridge.showSchemaForm()
homebridge.hideSpinner()
}
showDisabledBanner = () => {
document.getElementById('disabledBanner').style.display = 'block'
}
enablePlugin = async () => {
homebridge.showSpinner()
document.getElementById('disabledBanner').style.display = 'none'
currentConfig[0].disablePlugin = false
await homebridge.updatePluginConfig(currentConfig)
await homebridge.savePluginConfig()
homebridge.hideSpinner()
}
menuHome.addEventListener('click', () => showSupport())
menuDevices.addEventListener('click', () => showDevices())
menuSettings.addEventListener('click', () => showSettings())
disabledEnable.addEventListener('click', () => enablePlugin())
if (currentConfig.length) {
document.getElementById('menuWrapper').style.display = 'inline-flex'
showSettings()
if (currentConfig[0].disablePlugin) {
showDisabledBanner()
}
} else {
currentConfig.push({ name: 'iRobot' })
await homebridge.updatePluginConfig(currentConfig)
showIntro()
}
} catch (err) {
homebridge.toast.error(err.message, 'Error')
} finally {
homebridge.hideSpinner()
}
})()
</script>