@homebridge-plugins/homebridge-ewelink
Version:
Homebridge plugin to integrate eWeLink devices into HomeKit.
406 lines (401 loc) • 14.9 kB
HTML
<style>
.dark-mode {
background-color: #242424;
color: lightgrey;
.form-control {
background-color: #333333 ;
border: none ;
color: #eeeeee ;
}
thead, tbody, tr {
border-style: hidden;
}
th {
color: #eeeeee ;
font-weight: 500 ;
}
}
select {
background-image:
linear-gradient(45deg, transparent 50%, gray 50%),
linear-gradient(135deg, gray 50%, transparent 50%),
linear-gradient(to right, #ccc, #ccc);
background-position:
calc(100% - 20px) calc(1em + 2px),
calc(100% - 15px) calc(1em + 2px),
calc(100% - 2.5em) 0.5em;
background-size:
5px 5px,
5px 5px,
1px 1.5em;
background-repeat: no-repeat;
}
</style>
<p class="text-center">
<img
src="https://user-images.githubusercontent.com/43026681/101325266-63126600-3863-11eb-9382-4a2924f0e540.png"
alt="homebridge-ewelink logo"
style="width: 60%;"
/>
</p>
<div id="pageIntro" class="text-center" style="display: none;">
<p class="lead">Thank you for installing <strong>homebridge-ewelink</strong></p>
<p>
You will need to enter your eWeLink 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">
My 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 mt-3" 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"></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Cloud Status</th>
<td id="reachableWAN"></td>
</tr>
<tr>
<th scope="row">LAN Status</th>
<td id="reachableLAN"></td>
</tr>
<tr>
<th scope="row">LAN IP</th>
<td id="lanIP"></td>
</tr>
<tr>
<th scope="row">Homebridge ID</th>
<td id="hbDeviceId"></td>
</tr>
<tr>
<th scope="row">eWeLink ID</th>
<td id="eweDeviceId"></td>
</tr>
<tr>
<th scope="row">Brand</th>
<td id="eweBrandName"></td>
</tr>
<tr>
<th scope="row">Model (UIID)</th>
<td id="eweModel"></td>
</tr>
<tr>
<th scope="row">Firmware</th>
<td id="eweFirmware"></td>
</tr>
<tr>
<th scope="row">MAC Address</th>
<td id="eweMacAddress"></td>
</tr>
<tr>
<th scope="row">Shared Device</th>
<td id="eweShared"></td>
</tr>
<tr>
<td colspan="2" style="text-align: center" id="imgIcon"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="pageSupport" class="mt-4" style="display: none;">
<p class="text-center lead">Thank you for using <strong>homebridge-ewelink</strong></p>
<p class="text-center">The links below will take you to our GitHub wiki</p>
<h4>Setup</h4>
<ul>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Installation" target="_blank"
>Installation</a
>
</li>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Configuration" target="_blank"
>Configuration</a
>
</li>
<li>
<a href="https://github.com/homebridge/homebridge/wiki/How-to-Install-Alternate-Plugin-Versions" target="_blank"
>Beta Version</a
>
</li>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Node-Version" target="_blank"
>Node Version</a
>
</li>
</ul>
<h4>Features</h4>
<ul>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Supported-Devices" target="_blank"
>Supported Devices</a
>
</li>
<li>
<a
href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Accessory-Simulations"
target="_blank"
>Accessory Simulations</a
>
</li>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Connection-Methods" target="_blank"
>Connection Methods</a
>
</li>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Internal-API" target="_blank"
>Internal API</a
>
</li>
</ul>
<h4>Help/About</h4>
<ul>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/wiki/Common-Errors" target="_blank"
>Common Errors</a
>
</li>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/issues/new/choose" target="_blank"
>Support Request</a
>
</li>
<li>
<a href="https://github.com/homebridge-plugins/homebridge-ewelink/blob/latest/CHANGELOG.md" target="_blank"
>Changelog</a
>
</li>
<li>
<a href="https://github.com/sponsors/bwp91" target="_blank">About Me</a>
</li>
</ul>
<h4>Credits</h4>
<ul>
<li>
To the original plugin maintainer:
<a href="https://github.com/gbro115" target="_blank">@gbro115</a>.
</li>
<li>
To successive contributors:
<a href="https://github.com/MrTomAsh" target="_blank">@MrTomAsh</a> and
<a href="https://github.com/howanghk" target="_blank">@howanghk</a> for
<a href="https://github.com/howanghk/homebridge-ewelink" target="_blank"
>homebridge-ewelink-max</a
>.
</li>
<li>
To the creators/contributors of
<a href="https://homebridge.io" target="_blank">Homebridge</a> who make this plugin possible.
</li>
<li>
To the creators/contributors of
<a href="https://github.com/simont77/fakegato-history" target="_blank">Fakegato</a>:
<a href="https://github.com/simont77" target="_blank">@simont77</a> and
<a href="https://github.com/NorthernMan54" target="_blank">@NorthernMan54</a>.
</li>
<li>
To the creator of the awesome plugin header logo:
<a href="https://www.instagram.com/keryan.me" target="_blank">Keryan Belahcene</a>.
</li>
<li>To all users who have shared their devices to enable functionality.</li>
</ul>
<h4>Disclaimer</h4>
<ul>
<li>
I am in no way affiliated with eWeLink nor any of the device brands (like Sonoff) 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 = () => {
homebridge.disableSaveButton?.()
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.disableSaveButton?.()
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.context.hbDeviceId
deviceSelect.add(option)
})
showDeviceInfo = async hbDeviceId => {
homebridge.showSpinner()
const thisAcc = cachedAccessories.find(x => x.context.hbDeviceId === hbDeviceId)
const context = thisAcc.context
document.getElementById('displayName').innerHTML = thisAcc.displayName
document.getElementById('reachableWAN').innerHTML = context.reachableWAN
? '<i class="fas fa-circle mr-1 green-text"></i> Online'
: '<i class="fas fa-circle mr-1 red-text"></i> Offline'
document.getElementById('reachableLAN').innerHTML = context.reachableLAN
? '<i class="fas fa-circle mr-1 green-text"></i> Online'
: '<i class="fas fa-circle mr-1 red-text"></i> Offline'
document.getElementById('lanIP').innerHTML = context.ip || 'N/A'
document.getElementById('hbDeviceId').innerHTML = context.hbDeviceId || 'N/A'
document.getElementById('eweDeviceId').innerHTML = context.eweDeviceId || 'N/A'
document.getElementById('eweBrandName').innerHTML = context.eweBrandName || 'N/A'
document.getElementById('eweFirmware').innerHTML = context.firmware || 'N/A'
document.getElementById('eweMacAddress').innerHTML = context.macAddress || 'N/A'
document.getElementById('eweModel').innerHTML =
(context.eweModel || 'N/A') + ' (' + (context.eweUIID || 'N/A') + ')'
document.getElementById('eweShared').innerHTML = context.eweShared
? 'Yes (by ' + context.eweShared + ')'
: 'No'
document.getElementById('imgIcon').innerHTML = context.eweBrandLogo
? '<img src="' + context.eweBrandLogo + '" style="width: 150px;">'
: ''
document.getElementById('deviceTable').style.display = 'inline-table'
homebridge.hideSpinner()
}
deviceSelect.addEventListener('change', event => showDeviceInfo(event.target.value))
if (cachedAccessories.length > 0) {
showDeviceInfo(cachedAccessories[0].context.hbDeviceId)
} else {
const option = document.createElement('option')
option.text = 'No Devices'
deviceSelect.add(option)
deviceSelect.disabled = true
}
homebridge.hideSpinner()
}
showSupport = () => {
homebridge.showSpinner()
homebridge.disableSaveButton?.()
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()
homebridge.enableSaveButton?.()
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: 'eWeLink' })
await homebridge.updatePluginConfig(currentConfig)
showIntro()
}
} catch (err) {
homebridge.toast.error(err.message, 'Error')
} finally {
homebridge.hideSpinner()
}
})()
</script>