🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

iobroker.openwrt

Package Overview
Dependencies
Maintainers
2
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iobroker.openwrt - npm Package Compare versions

Comparing version
0.0.1
to
0.0.3
github-ressources/example_objects.png

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

+78
-20

@@ -39,2 +39,5 @@ <html>

var getCommandList = [];
var getTypeList = [];
// This will be called by the admin adapter when the settings page loads

@@ -77,6 +80,4 @@ function load(settings, onChange) {

});
}));
}));
$('#inp_password').on('keydown', (function () {

@@ -94,2 +95,5 @@ $('#fTestAuth').removeClass('disabled');

var id = $key.attr('id');
if (id === 'inp_password') {
settings[id] = decrypt(secret, settings[id]);
}
if ($key.attr('type') === 'checkbox') {

@@ -108,3 +112,8 @@ // do not call onChange direct, because onChange could expect some arguments

});
getCommandList = settings.list_commands || [];
getTypeList = settings.list_types || [];
onChange(false);
values2table("list_commands", getCommandList, onChange);
values2table("list_types", getTypeList, onChange);
// reinitialize all the Materialize labels on the page if you are dynamically adding inputs:

@@ -134,7 +143,8 @@ if (M) M.updateTextFields();

default:
obj[$this.attr('id')] =
$this.data('crypt') && $this.val() ? encrypt(secret, $this.val()) : $this.val();
obj[$this.attr('id')] = $this.data('crypt') && $this.val() ? encrypt(secret, $this.val()) : $this.val();
break;
}
});
obj.list_commands = table2values("list_commands");
obj.list_types = table2values("list_types");
callback(obj);

@@ -144,2 +154,12 @@ }

<style>
/* Title of each section */
.title { font-weight: bold; }
/* Info text of each section */
.info { margin-left: 1em; }
/* Table header */
.table-values th { height: 2em; background-color:#2196F3; font-size:90%; }
/* Table: Add button */
.table-button-add { margin: 0.3em 0 1em 0; }
</style>
</head>

@@ -152,3 +172,3 @@

<div class="row">
<div class="col s12 m4 l2">
<div class="col s12 m6 l4">
<img src="openwrt.png" class="logo">

@@ -164,6 +184,6 @@ </div>

<div class="row">
<div class="input-field col s12 m6 l2">
<div class="input-field col s12 m6 l4">
<input class="value" type="text" id="inp_url" />
<label for="inp_url" class="translate">inp_url_short</label>
<i><span class="translate">inp_url_long</span></i>
<label for="inp_url" class="translate">lab_url_short</label>
<i><span class="translate">lab_url_long</span></i>
</div>

@@ -177,11 +197,11 @@

<div class="row">
<div class="input-field col s4 m2 l1">
<div class="input-field col s12 m6 l2">
<input class="value" type="text" id="inp_username" />
<label for="inp_username" class="translate">inp_username_short</label>
<i><span class="translate">inp_username_long</span></i>
<label for="inp_username" class="translate">lab_username_short</label>
<i><span class="translate">lab_username_long</span></i>
</div>
<div class="input-field col s4 m2 l1">
<div class="input-field col s12 m6 l2">
<input class="value" data-crypt="1" type="password" id="inp_password" />
<label for="inp_password" class="translate">inp_password_short</label>
<i><span class="translate">inp_password_long</span></i>
<label for="inp_password" class="translate">lab_password_short</label>
<i><span class="translate">lab_password_long</span></i>
</div>

@@ -194,13 +214,51 @@ <div class="col s6">

<div class="row">
<div class="input-field col s12 m6 l2">
<div class="input-field col s12 m6 l4">
<input class="value" type="number" id="inp_refresh" />
<label for="inp_refresh" class="translate">inp_refresh_short</label>
<i><span class="translate">inp_refresh_long</span></i>
<label for="inp_refresh" class="translate">lab_refresh_short</label>
<i><span class="translate">lab_refresh_long</span></i>
</div>
</div>
<div class="row">
<div id="tab-list_commands" class="col s12 page">
<p class="translate title">lab_settings</p>
<p class="translate info">text_settings</p>
<div class="col s12 m6 l4" id="list_commands">
<a class="btn-floating waves-effect waves-light blue table-button-add"><i class="material-icons">add</i></a>
<span class="translate info" style="margin-right: 50px;">lab_BtnAddCMD</span>
<div class="table-values-div">
<table class="table-values">
<thead>
<tr>
<th class="header translate" data-name="alias">list_commands-alias</th>
<th class="header translate" data-name="cmd">list_commands-cmd</th>
<th class="header translate" data-buttons="delete">list_commands-del</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="col s12 m6 l4" id="list_types">
<a class="btn-floating waves-effect waves-light blue table-button-add"><i class="material-icons">add</i></a>
<span class="translate info" style="margin-right: 50px;">lab_BtnAddType</span>
<div class="table-values-div">
<table class="table-values">
<thead>
<tr>
<th class="header translate" data-name="stateid">list_types-stateid</th>
<th class="header translate" style="width: 150px" data-name="type" data-options="Text;Number;Boolean" data-type="select" style="width: 150px">list_types-type</th>
<th class="header translate" data-buttons="delete">list_types-del</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
</html>

@@ -19,48 +19,264 @@ /*global systemDictionary:true */

"en": "General",
"de": "Allgemein"
"de": "Allgemein",
"ru": "Общий",
"pt": "Em geral",
"nl": "Algemeen",
"fr": "Général",
"it": "Generale",
"es": "General",
"pl": "Ogólny",
"zh-cn": "一般的"
},
"text_general": {
"en": "OpenWRT RPC API Configuration",
"de": "OpenWRT RPC API Konfiguration"
"de": "OpenWRT RPC API-Konfiguration",
"ru": "Конфигурация OpenWRT RPC API",
"pt": "Configuração da API OpenWRT RPC",
"nl": "OpenWRT RPC API-configuratie",
"fr": "Configuration de l'API OpenWRT RPC",
"it": "Configurazione API RPC OpenWRT",
"es": "Configuración de la API de OpenWRT RPC",
"pl": "Konfiguracja interfejsu API OpenWRT RPC",
"zh-cn": "OpenWRT RPC API 配置"
},
"inp_url_short": {
"lab_url_short": {
"en": "URL",
"de": "URL"
"de": "URL",
"ru": "URL",
"pt": "URL",
"nl": "URL",
"fr": "URL",
"it": "URL",
"es": "URL",
"pl": "URL",
"zh-cn": "网址"
},
"inp_url_long": {
"lab_url_long": {
"en": "URL to RPC | e.g. http://192.168.1.1/cgi-bin/luci/rpc/",
"de": "URL zu RPC-Dienst | z.B. http://192.168.1.1/cgi-bin/luci/rpc/"
"de": "URL zu RPC | z.B. http://192.168.1.1/cgi-bin/luci/rpc/",
"ru": "URL-адрес RPC | например http://192.168.1.1/cgi-bin/luci/rpc/",
"pt": "URL para RPC | por exemplo. http://192.168.1.1/cgi-bin/luci/rpc/",
"nl": "URL naar RPC | bijv. http://192.168.1.1/cgi-bin/luci/rpc/",
"fr": "URL vers RPC | par exemple. http://192.168.1.1/cgi-bin/luci/rpc/",
"it": "URL per RPC | per esempio. http://192.168.1.1/cgi-bin/luci/rpc/",
"es": "URL a RPC | p.ej. http://192.168.1.1/cgi-bin/luci/rpc/",
"pl": "URL do RPC | np. http://192.168.1.1/cgi-bin/luci/rpc/",
"zh-cn": "RPC 的 URL |例如http://192.168.1.1/cgi-bin/luci/rpc/"
},
"btn_checkURL": {
"en": "Check URL",
"de": "URL prüfen"
"de": "URL prüfen",
"ru": "Проверить URL",
"pt": "Verifique o URL",
"nl": "Controleer URL",
"fr": "Vérifier l'URL",
"it": "Controlla URL",
"es": "Verificar URL",
"pl": "Sprawdź adres URL",
"zh-cn": "检查网址"
},
"inp_username_short": {
"lab_username_short": {
"en": "Username",
"de": "Benutzername"
"de": "Nutzername",
"ru": "Имя пользователя",
"pt": "Nome do usuário",
"nl": "gebruikersnaam",
"fr": "Nom d'utilisateur",
"it": "Nome utente",
"es": "Nombre de usuario",
"pl": "Nazwa użytkownika",
"zh-cn": "用户名"
},
"inp_username_long": {
"lab_username_long": {
"en": "OpenWRT username",
"de": "OpenWRT Benutzername"
"de": "OpenWRT-Benutzername",
"ru": "Имя пользователя OpenWRT",
"pt": "Nome de usuário OpenWRT",
"nl": "OpenWRT-gebruikersnaam",
"fr": "Nom d'utilisateur OpenWRT",
"it": "Nome utente OpenWRT",
"es": "Nombre de usuario de OpenWRT",
"pl": "Nazwa użytkownika OpenWRT",
"zh-cn": "OpenWRT 用户名"
},
"inp_password_short": {
"lab_password_short": {
"en": "OpenWRT password",
"de": "OpenWRT Passwort"
"de": "OpenWRT-Passwort",
"ru": "Пароль OpenWRT",
"pt": "Senha OpenWRT",
"nl": "OpenWRT-wachtwoord",
"fr": "Mot de passe OpenWRT",
"it": "Password OpenWRT",
"es": "Contraseña OpenWRT",
"pl": "Hasło OpenWRT",
"zh-cn": "OpenWRT 密码"
},
"inp_password_long": {
"lab_password_long": {
"en": "OpenWRT password",
"de": "OpenWRT Passwort"
"de": "OpenWRT-Passwort",
"ru": "Пароль OpenWRT",
"pt": "Senha OpenWRT",
"nl": "OpenWRT-wachtwoord",
"fr": "Mot de passe OpenWRT",
"it": "Password OpenWRT",
"es": "Contraseña OpenWRT",
"pl": "Hasło OpenWRT",
"zh-cn": "OpenWRT 密码"
},
"btn_checkAuth": {
"en": "Check Auth",
"de": "Auth prüfen"
"de": "Authentifizierung prüfen",
"ru": "Проверить аутентификацию",
"pt": "Verificar autenticação",
"nl": "Controleer Auth",
"fr": "Vérifier l'autorisation",
"it": "Verifica autenticazione",
"es": "Verificar autenticación",
"pl": "Sprawdź uwierzytelnianie",
"zh-cn": "检查身份验证"
},
"inp_refresh_short": {
"lab_refresh_short": {
"en": "Refresh interval",
"de": "Aktualisierungsintervall"
"de": "Aktualisierungsintervall",
"ru": "Интервал обновления",
"pt": "Intervalo de atualização",
"nl": "Vernieuwingsinterval",
"fr": "Intervalle de rafraîchissement",
"it": "Intervallo di aggiornamento",
"es": "Intervalo de actualización",
"pl": "Częstotliwość odświeżania",
"zh-cn": "刷新间隔"
},
"inp_refresh_long": {
"lab_refresh_long": {
"en": "Refresh interval (minutes)",
"de": "Aktualisierungsintervall (Minuten)"
"de": "Aktualisierungsintervall (Minuten)",
"ru": "Интервал обновления (минуты)",
"pt": "Intervalo de atualização (minutos)",
"nl": "Verversingsinterval (minuten)",
"fr": "Intervalle de rafraîchissement (minutes)",
"it": "Intervallo di aggiornamento (minuti)",
"es": "Intervalo de actualización (minutos)",
"pl": "Interwał odświeżania (minuty)",
"zh-cn": "刷新间隔(分钟)"
},
"lab_settings": {
"en": "Datatransfer - Commands&DataTypes",
"de": "Datenübertragung - Befehle und Datentypen",
"ru": "Передача данных - Команды и типы данных",
"pt": "Datatransfer - Comandos e DataTypes",
"nl": "Gegevensoverdracht - Commando's en gegevenstypen",
"fr": "Transfert de données - Commandes et types de données",
"it": "Trasferimento dati - Comandi e tipi di dati",
"es": "Transferencia de datos: comandos y tipos de datos",
"pl": "Transfer danych — polecenia i typy danych",
"zh-cn": "数据传输 - 命令和数据类型"
},
"text_settings": {
"en": "You probably just need the left table with the Command-List<br>The table on the right should be used if a DataType is determined wrong for a created ioBroker-States [under Tab Objects] (type: Text, Boolean or Number)",
"de": "Du wirst in der Regel nur die linke Tabelle mit den Kommandos benötigen.<br>Die rechts Tabelle die nur zum korrieren der automatisch erkannten DatenTypen für ioBroker-States [im Objects-Tab] (Type: Text, Boolean oder Number)",
"ru": "Вам, наверное, просто нужен левый стол с Command-List<br>The table on the right должен быть использован, если DataType определен не так для созданных ioBroker-States [under Tab Objects] (type: Text, Boolean или Number)",
"pt": "Você provavelmente só precisa da tabela esquerda com o comando-List<br> A tabela à direita deve ser usada se um DataType é determinado errado para um ioBroker-States criado [sob objetos de guia] (tipo: texto, booleano ou número)",
"nl": "Je hebt waarschijnlijk de linkertafel nodig met de Command-List, de tafel aan de rechterkant zou moeten worden gebruikt als een DataType verkeerd vastgesteld is voor een gecreëerde ioBroker-States [onderwerp",
"fr": "Vous avez probablement juste besoin de la table de gauche avec le Command-List profanéLe tableau de droite devrait être utilisé si un DataType est déterminé à tort pour un ioBroker-States créé [sous les objets Tab] (type: Texte, Boolean ou Nombre)",
"it": "Probabilmente avete solo bisogno della tabella sinistra con il Comando-List <br> La tabella a destra dovrebbe essere utilizzata se un DataType è determinato sbagliato per uno ioBroker-States creato [sotto Oggetti della scheda] (tipo: Testo, Boolean o Numero)",
"es": "Usted probablemente sólo necesita la tabla izquierda con el Command-List obtenidosbr confianzaLa tabla sobre la derecha debe ser utilizada si un DataType está determinado mal para un ioBroker-States creado [bajo objetos de la pestaña] (tipo: Texto, Booleano o Número)",
"pl": "Prawdopodobnie potrzebujesz lewej tablicy z napisem Command-List<br> Tabela na prawej stronie powinna być używana, jeśli daneType jest zdeterminowana dla stworzonego ioBroker-States under Objects (typ: Text, Boolean lub Number)",
"zh-cn": "你可能只需要与指挥部-List <br>左面桌面,如果数据Type被确定为创建的OioBroker-States[根据Tab物体](原状、Bolean或编号)便应该使用该权利表。"
},
"lab_BtnAddCMD": {
"en": "Add ubus Command",
"de": "ubus-Befehl hinzufügen",
"ru": "Добавить команду ubus",
"pt": "Adicionar comando ubus",
"nl": "Ubus-opdracht toevoegen",
"fr": "Ajouter une commande ubus",
"it": "Aggiungi comando ubus",
"es": "Agregar comando ubus",
"pl": "Dodaj polecenie ubus",
"zh-cn": "添加 ubus 命令"
},
"list_commands-alias": {
"en": "Alias",
"de": "Alias",
"ru": "Алиас",
"pt": "Alias",
"nl": "Alias",
"fr": "Alias",
"it": "Alias",
"es": "Alias",
"pl": "Alias",
"zh-cn": "Aliasasas"
},
"list_commands-cmd": {
"en": "ubus Command",
"de": "ubus-Befehl",
"ru": "команда ubus",
"pt": "Comando ubus",
"nl": "ubus Commando",
"fr": "Commande Ubus",
"it": "comando ubus",
"es": "comando ubus",
"pl": "ubus Polecenie",
"zh-cn": "ubus 命令"
},
"list_commands-del": {
"en": "Delete",
"de": "Löschen",
"ru": "Удалить",
"pt": "Excluir",
"nl": "Verwijderen",
"fr": "Effacer",
"it": "Elimina",
"es": "Borrar",
"pl": "Kasować",
"zh-cn": "删除"
},
"lab_BtnAddType": {
"en": "Add type definition",
"de": "Typdefinition hinzufügen",
"ru": "Добавить определение типа",
"pt": "Adicionar definição de tipo",
"nl": "Typedefinitie toevoegen",
"fr": "Ajouter une définition de type",
"it": "Aggiungi la definizione del tipo",
"es": "Agregar definición de tipo",
"pl": "Dodaj definicję typu",
"zh-cn": "添加类型定义"
},
"list_types-stateid": {
"en": "State ID (see Objects)",
"de": "State-ID (siehe Objekte)",
"ru": "ID состояния (см. Объекты)",
"pt": "ID de estado (ver objetos)",
"nl": "Status-ID (zie Objecten)",
"fr": "ID d'état (voir Objets)",
"it": "ID stato (vedi Oggetti)",
"es": "ID de estado (ver Objetos)",
"pl": "Identyfikator stanu (patrz Obiekty)",
"zh-cn": "状态 ID(请参阅对象)"
},
"list_types-type": {
"en": "Datatype",
"de": "Datentyp (soll)",
"ru": "Тип данных",
"pt": "Tipo de dados",
"nl": "Data type",
"fr": "Type de données",
"it": "Tipo di dati",
"es": "Tipo de datos",
"pl": "Typ danych",
"zh-cn": "数据类型"
},
"list_types-del": {
"en": "Delete",
"de": "Löschen",
"ru": "Удалить",
"pt": "Excluir",
"nl": "Verwijderen",
"fr": "Effacer",
"it": "Elimina",
"es": "Borrar",
"pl": "Kasować",
"zh-cn": "删除"
}
};
};
{
"common": {
"name": "openwrt",
"version": "0.0.1",
"news": {
"0.0.1": {
"en": "initial release",
"de": "Erstveröffentlichung",
"ru": "Начальная версия",
"pt": "lançamento inicial",
"nl": "Eerste uitgave",
"fr": "Première version",
"it": "Versione iniziale",
"es": "Versión inicial",
"pl": "Pierwsze wydanie",
"zh-cn": "首次出版"
}
},
"title": "OpenWRT",
"titleLang": {
"en": "OpenWrt",
"de": "OpenWrt",
"ru": "OpenWrt",
"pt": "OpenWrt",
"nl": "OpenWrt",
"fr": "OpenWrt",
"it": "OpenWrt",
"es": "OpenWrt",
"pl": "OpenWrt",
"zh-cn": "OpenWrt"
},
"desc": {
"en": "Interact with the openwrt RPC API",
"de": "Interagiere mit der openwrt RPC API",
"ru": "Взаимодействовать с openwrt RPC API",
"pt": "Interaja com a API RPC openwrt",
"nl": "Interactie met de openwrt RPC API",
"fr": "Interagir avec l'API openwrt RPC",
"it": "Interagisci con l'API RPC openwrt",
"es": "Interactúa con la API openwrt RPC",
"pl": "Interakcja z openwrt RPC API",
"zh-cn": "与openwrt RPC API交互"
},
"authors": [
"Schnup89 <tobias_tsafi@gmx.de>"
],
"keywords": [
"openwrt",
"network",
"api",
"router"
],
"license": "MIT",
"platform": "Javascript/Node.js",
"messagebox": true,
"message": true,
"subscribe": "messagebox",
"main": "main.js",
"icon": "openwrt.png",
"enabled": true,
"extIcon": "https://raw.githubusercontent.com/Schnup89/ioBroker.openwrt/master/admin/openwrt.png",
"readme": "https://github.com/Schnup89/ioBroker.openwrt/blob/master/README.md",
"loglevel": "info",
"mode": "daemon",
"type": "infrastructure",
"compact": true,
"connectionType": "local",
"dataSource": "poll",
"materialize": true,
"supportCustoms": true,
"dependencies": [
{
"js-controller": ">=1.4.2"
}
]
"common": {
"name": "openwrt",
"version": "0.0.3",
"news": {
"0.0.1": {
"en": "initial release",
"de": "Erstveröffentlichung",
"ru": "Начальная версия",
"pt": "lançamento inicial",
"nl": "Eerste uitgave",
"fr": "Première version",
"it": "Versione iniziale",
"es": "Versión inicial",
"pl": "Pierwsze wydanie",
"zh-cn": "首次出版"
},
"0.0.2": {
"en": "Added Last-Update key to states",
"de": "Letzter Update-Schlüssel zu Staaten hinzugefügt",
"ru": "Добавлен ключ последнего обновления к состояниям",
"pt": "Adicionada a chave da última atualização aos estados",
"nl": "Last-Update-sleutel toegevoegd aan staten",
"fr": "Ajout de la clé de dernière mise à jour aux états",
"it": "Aggiunto tasto Ultimo aggiornamento agli stati",
"es": "Se agregó la clave de última actualización a los estados",
"pl": "Dodano klucz ostatniej aktualizacji do stanów",
"zh-cn": "为状态添加了 Last-Update 键"
},
"0.0.3": {
"en": "Added Alias and isAvailable",
"de": "Alias und isAvailable hinzugefügt",
"ru": "Добавлено Alias и доступно",
"pt": "Adicionado Alias e éDisponível",
"nl": "Toegevoegd Alias en is beschikbaar",
"fr": "Ajouté Alias et estDisponible",
"it": "Aggiunto Alias ed è disponibile",
"es": "Alias adicionales y está disponible",
"pl": "Added Alias and Is Available (ang.)",
"zh-cn": "增 编"
}
},
"native": {
"sToken": "",
"inp_url": "http://openwrt/cgi-bin/luci/rpc/",
"inp_username": "admin",
"inp_password": "",
"inp_refresh": 1
"titleLang": {
"en": "OpenWrt",
"de": "OpenWrt",
"ru": "OpenWrt",
"pt": "OpenWrt",
"nl": "OpenWrt",
"fr": "OpenWrt",
"it": "OpenWrt",
"es": "OpenWrt",
"pl": "OpenWrt",
"zh-cn": "OpenWrt"
},
"objects": [],
"instanceObjects": [
{
"_id": "info",
"type": "channel",
"common": {
"name": "Information"
},
"native": {}
},
{
"_id": "info.connection",
"type": "state",
"common": {
"role": "indicator.connected",
"name": "Device or service connected",
"type": "boolean",
"read": true,
"write": false,
"def": false
},
"native": {}
}
]
"desc": {
"en": "Interact with the openwrt RPC API",
"de": "Interagiere mit der openwrt RPC API",
"ru": "Взаимодействовать с openwrt RPC API",
"pt": "Interaja com a API RPC openwrt",
"nl": "Interactie met de openwrt RPC API",
"fr": "Interagir avec l'API openwrt RPC",
"it": "Interagisci con l'API RPC openwrt",
"es": "Interactúa con la API openwrt RPC",
"pl": "Interakcja z openwrt RPC API",
"zh-cn": "与openwrt RPC API交互"
},
"authors": [
"Schnup89 <tobias_tsafi@gmx.de>"
],
"keywords": [
"openwrt",
"network",
"api",
"router"
],
"license": "MIT",
"platform": "Javascript/Node.js",
"messagebox": true,
"message": true,
"subscribe": "messagebox",
"main": "main.js",
"icon": "openwrt.png",
"enabled": true,
"extIcon": "https://raw.githubusercontent.com/Schnup89/ioBroker.openwrt/master/admin/openwrt.png",
"readme": "https://github.com/Schnup89/ioBroker.openwrt/blob/master/README.md",
"loglevel": "info",
"mode": "daemon",
"type": "infrastructure",
"compact": true,
"connectionType": "local",
"dataSource": "poll",
"materialize": true,
"supportCustoms": false,
"dependencies": [
{
"js-controller": ">=3.3.22"
}
],
"installedFrom": "Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e"
},
"native": {
"sToken": "",
"inp_url": "http://openwrt/cgi-bin/luci/rpc/",
"inp_username": "root",
"inp_password": "",
"inp_refresh": 1,
"list_commands": [
{
"alias": "wan_status",
"cmd": "ubus call network.interface.wan status"
}
],
"list_types": []
},
"objects": [],
"instanceObjects": [
{
"_id": "info",
"type": "channel",
"common": {
"name": "Information"
},
"native": {}
},
{
"_id": "info.connection",
"type": "state",
"common": {
"role": "indicator.connected",
"name": "Device or service connected",
"type": "boolean",
"read": true,
"write": false,
"def": false
},
"native": {}
}
]
}
MIT License
Copyright (c) 2020 Schnup89 <tobias_tsafi@gmx.de>
Copyright (c) 2022 Schnup89 <tobias_tsafi@gmx.de>

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

+263
-161

@@ -11,2 +11,3 @@ "use strict";

const request = require("request");
const type = require("get-type");

@@ -20,2 +21,13 @@ // eslint-disable-next-line no-unused-vars

Array.prototype.remove = function() {
var what, a = arguments, L = a.length, ax;
while (L && this.length) {
what = a[--L];
while ((ax = this.indexOf(what)) !== -1) {
this.splice(ax, 1);
}
}
return this;
};
class Openwrt extends utils.Adapter {

@@ -33,3 +45,3 @@

this.on("ready", this.onReady.bind(this));
this.on("objectChange", this.onObjectChange.bind(this));
//this.on("objectChange", this.onObjectChange.bind(this));
this.on("stateChange", this.onStateChange.bind(this));

@@ -62,3 +74,3 @@ this.on("message", this.onMessage.bind(this));

this.log.info("##### LOAD CONFIG #####");
this.log.debug("##### LOAD CONFIG #####");

@@ -90,6 +102,18 @@ //Check refresh interval field, if its's not set, we set it

}
this.log.info("Decrypted the encrypted password!");
this.log.debug("Decrypted the encrypted password!");
//Check for empty Commands or Alias, if found, preCheck = false
if (this.config.list_commands.length > 0) {
for (let nEntry = 0; nEntry < this.config.list_commands.length; nEntry++) {
if (!this.config.list_commands[nEntry].alias || !this.config.list_commands[nEntry].alias) {
this.log.error("## Alias or Command-Entry empty, only Path-Check available");
bPreCheckErr = true; //Dont run
}
}
}else{
this.log.error("## No Commands defined, only Path-Check available");
bPreCheckErr = true; //Dont run
}
this.log.info("##### RUN ADAPTER ##### ");
this.log.debug("##### RUN ADAPTER ##### ");
if (!bPreCheckErr) {

@@ -100,8 +124,42 @@ //Get first Time Token

this.fHTTPGetValues();
}else{
this.log.info("##### PRE CHECK ERRORS, MAIN FUNCTIONS DISABLED! Check Settings");
} else {
this.log.error("##### PRE CHECK ERRORS, MAIN FUNCTIONS DISABLED! Check Settings");
}
//Object2SendCMD
this.setObjectNotExists("sendCommand", {
type: "state",
common: { name: "sendCommand", type: "string", role: "text", write: true},
native: {}
}, (id, error) => {this.setState("sendCommand", "", true);});
//Object2WriteResult
this.setObjectNotExists("sendCommandLastResult", {
type: "state",
common: { name: "sendCommand", type: "string", role: "text", write: false},
native: {}
}, (id, error) => {this.setState("sendCommandLastResult", "", true);});
this.getDevices((err,devices) => {
try {
const device_list = this.config.list_commands.map(entry => {return entry.alias});
device_list.forEach(device => {
this.setObjectNotExists(device, {
type: "device",
common: { name: device},
native: {}
});
});
devices.forEach(device => {
const device_name = device._id.replace(this.namespace+".","");
if (!device_list.includes(device_name)) {
this.delObject(device_name, {recursive: true})
}
})
}catch (e) {
this.log.warn("Check that Alias and UBUS-Command are both filled. Error: "+e);
}
});
this.subscribeStates("*");
}

@@ -115,2 +173,7 @@

try {
if (tmr_GetValues) {
clearInterval(tmr_GetValues);
clearTimeout(tmr_GetValues);
tmr_GetValues = null;
}
this.log.info("cleaned everything up...");

@@ -124,7 +187,8 @@ callback();

/**
* Is called if a subscribed object changes
* @param {string} id
* @param {ioBroker.Object | null | undefined} obj
*/
onObjectChange(id, obj) {
// * Is called if a subscribed object changes
// * @param {string} id
// * @param {ioBroker.Object | null | undefined} obj
*/
/*onObjectChange(id, obj) {
if (obj) {

@@ -137,16 +201,21 @@ // The object was changed

}
}
}*/
/**
* Is called if a subscribed state changes
* @param {string} id
* @param {ioBroker.State | null | undefined} state
*/
// * Is called if a subscribed state changes
// * @param {string} id
//* @param {ioBroker.State | null | undefined} state
*/
onStateChange(id, state) {
if (state) {
// The state was changed
this.log.info(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
if (id == this.namespace + ".sendCommand" && state.val) { //& value not "" empty
this.log.debug("SendCommand: " + state.val);
this.fHTTPSendCommand(state.val, true);
this.setState("sendCommand", "");
}
} else {
// The state was deleted
this.log.info(`state ${id} deleted`);
this.log.debug(`state ${id} deleted`);
}

@@ -187,15 +256,19 @@ }

this.log.info("Called fHTTPCheckURL");
this.log.debug("Called fHTTPCheckURL");
request(oReqOpt, (error, response, body) => {
if (error) {
this.log.warn("fHTTPCheckURL Unexpected Error: " + error);
resolve(false);
} else {
if (!body.includes("jsonrpc")) {
this.log.warn("fHTTPCheckURL 'jsonrpc' not found in response.");
try {
if (error) {
this.log.warn("fHTTPCheckURL Unexpected Error: " + error);
resolve(false);
} else {
this.log.info("fHTTPCheckURL success");
resolve(true);
} else {
if (!body.includes("jsonrpc")) {
this.log.warn("fHTTPCheckURL 'jsonrpc' not found in response.");
resolve(false);
} else {
this.log.debug("fHTTPCheckURL success");
resolve(true);
}
}
} catch (e) {
this.log.error("##### fHTTPCheckURL CatchError: " + e);
}

@@ -219,18 +292,22 @@ });

};
this.log.info("Called fHTTPCheckAuth");
this.log.debug("Called fHTTPCheckAuth");
request(oReqOpt, (error, response, body) => {
if (this.fValidateHTTPResult(error,response,"CheckAuth")) {
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
this.log.info("fHTTPCheckAuth success");
resolve(true);
}else{
this.log.info("fHTTPCheckAuth ResultError: " + body);
try {
if (this.fValidateHTTPResult(error,response,"CheckAuth")) {
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
this.log.debug("fHTTPCheckAuth success");
resolve(true);
}else{
this.log.error("fHTTPCheckAuth ResultError: " + body);
resolve(false);
}
} else {
//Log Message printed in fValidateHTTPResult function
resolve(false);
}
} else {
//Log Message printed in fValidateHTTPResult function
resolve(false);
resolve(true);
} catch (e) {
this.log.error("##### fHTTPCheckAuth CatchError: " + e);
}
resolve(true);
});

@@ -247,3 +324,3 @@ });

if (!(response.statusCode == 200)) {
this.log.info("##### fHTTP" + sFuncName + " HTTPCode: " + response.statusCode);
this.log.debug("##### fHTTP" + sFuncName + " HTTPCode: " + response.statusCode);
if (response.statusCode == 403) {

@@ -255,5 +332,5 @@ await this.fHTTPGetToken();

}
return true; //NO Error
}

@@ -265,3 +342,3 @@ fHTTPGetToken() { //NOT ASYNC

"method": "login",
"params": ["root",sPass]
"params": [this.config.inp_username,sPass]
};

@@ -275,12 +352,22 @@ const oReqOpt = {

this.log.info("Called fHTTGetToken");
this.log.debug("Called fHTTGetToken");
request(oReqOpt, (error, response, body) => {
if (this.fValidateHTTPResult(error,response,"GetToken")) {
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
this.log.info("Saved new Token: " + oBody.result);
this.config.sToken = oBody.result;
}else{
this.log.info("##### fHTTPGetToken ResultError: " + body);
try {
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
this.log.debug("Saved new Token: " + oBody.result);
this.config.sToken = oBody.result;
this.setState("info.connection",true,true);
}else{
this.log.debug("##### fHTTPGetToken ResultError: " + body);
this.setState("info.connection",false,true);
}
} catch (e) {
this.log.debug("##### fHTTPGetToken CatchError: " + e);
this.setState("info.connection",false,true);
}
} else {
//Error Message is printed in validate function
this.setState("info.connection",false,true);
}

@@ -294,30 +381,21 @@ resolve(true);

//Set Timer for next Update
tmr_GetValues = setTimeout(() =>this.fHTTPGetValues(),this.config.inp_refresh * 1000);
tmr_GetValues = setTimeout(() =>this.fHTTPGetValues(),this.config.inp_refresh * 60000);
//GetUptime
this.fHTTPGetSysinfo();
//GetHostname
this.fHTTPGetSysBoard();
//GetInterfaces
this.fHTTPGetInterfaces();
for (let nEntry = 0; nEntry < this.config.list_commands.length; nEntry++) {
this.fHTTPGetUbusCMD(this.config.list_commands[nEntry].cmd,this.config.list_commands[nEntry].alias);
}
}
//##################### DATA FUNCTION
fSetValue2State(sValue, oValues){
this.setObjectNotExists(oValues.name, {
type: "state",
common: oValues,
native: {}
});
this.setState(oValues.name, sValue);
// eslint-disable-next-line no-unused-vars
fOverrideExists(sKey) {
const sType = "";
const sRole = "";
//ToDo, check if Override exists, change const to let and overrite it!
return { name: "", type: sType, role: sRole, read: true, write: false };
}
fHTTPGetSysinfo() { //System-Information
fHTTPSendCommand(sCMD, bFirstTry) {
const oReqBody = {
"method": "exec",
"params": [ "ubus call system info" ]
"params": [ sCMD ]
};

@@ -334,22 +412,21 @@ const oReqOpt = {

request(oReqOpt, async (error, response, body) => {
if (await this.fValidateHTTPResult(error,response,"GetSysinfo")) {
//bug... output \n\t\ seems broken, delete it
body = this.replaceAll(body,"\n\t","");
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
const oSysInfo = JSON.parse(oBody.result);
if(typeof oSysInfo.uptime != "undefined") this.fSetValue2State(oSysInfo.uptime, { name: "sys.uptime", type: "number", role: "time", read: true, write: false });
if(typeof oSysInfo.load != "undefined") {
this.fSetValue2State(oSysInfo.load[1], { name: "sys.load1M", type: "number", role: "value", read: true, write: false });
this.fSetValue2State(oSysInfo.load[2], { name: "sys.load5M", type: "number", role: "value", read: true, write: false });
this.fSetValue2State(oSysInfo.load[3], { name: "sys.load15M", type: "number", role: "value", read: true, write: false });
}
if(typeof oSysInfo.memory.total != "undefined") this.fSetValue2State(oSysInfo.memory.total, { name: "sys.memory.total", type: "number", role: "value", read: true, write: false });
if(typeof oSysInfo.memory.free != "undefined") this.fSetValue2State(oSysInfo.memory.free, { name: "sys.memory.free", type: "number", role: "value", read: true, write: false });
if(typeof oSysInfo.memory.shared != "undefined") this.fSetValue2State(oSysInfo.memory.shared, { name: "sys.memory.shared", type: "number", role: "value", read: true, write: false });
if(typeof oSysInfo.memory.buffered != "undefined") this.fSetValue2State(oSysInfo.memory.buffered, { name: "sys.memory.buffered", type: "number", role: "value", read: true, write: false });
if(typeof oSysInfo.swap.total != "undefined") this.fSetValue2State(oSysInfo.swap.total, { name: "sys.swap.total", type: "number", role: "value", read: true, write: false });
if(typeof oSysInfo.swap.free != "undefined") this.fSetValue2State(oSysInfo.swap.free, { name: "sys.swap.free", type: "number", role: "value", read: true, write: false });
//this.fSetValue2State(oBody.result, oSetObj);
if (await this.fValidateHTTPResult(error,response,"SendCommand, " + sCMD)) {
try {
//bug... output \n\t\ seems broken, delete it
body = this.replaceAll(body,"\n\t","");
let sBody = JSON.stringify(JSON.parse(body));
sBody = sBody.replace(/\\t/g,"");
sBody = sBody.replace(/\\n/g,"");
sBody = sBody.replace(/\\r/g,"");
this.setState("sendCommandLastResult",sBody);
} catch (e) {
this.log.error("##### SendCommand, " + sCMD + " + CatchError: " + e);
this.setState("sendCommandLastResult","{ \"error\": \"" + e + "\" }");
}
} else {
if (bFirstTry) {
this.fHTTPSendCommand(sCMD, false); //If Token was not valid, this ensures it gets renew while fvalidehttpresult
} else {
this.setState("sendCommandLastResult",JSON.stringify(response));
}
}

@@ -359,42 +436,79 @@ });

fHTTPGetSysBoard() { //System-Information
const oReqBody = {
"method": "exec",
"params": [ "ubus call system board" ]
};
const oReqOpt = {
"method": "POST",
"url": this.config.inp_url + "sys?auth="+this.config.sToken,
"headers": {
"Content-Type": ["application/json", "text/plain"]
},
"body": JSON.stringify(oReqBody)
};
request(oReqOpt, async (error, response, body) => {
if (await this.fValidateHTTPResult(error,response,"GetSysBoard")) {
//bug... output \n\t\ seems broken, delete it
body = this.replaceAll(body,"\n\t","");
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
const oSysInfo = JSON.parse(oBody.result);
if(typeof oSysInfo.kernel != "undefined") this.fSetValue2State(oSysInfo.kernel, { name: "sys.kernel", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.hostname != "undefined") this.fSetValue2State(oSysInfo.hostname, { name: "sys.hostname", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.system != "undefined") this.fSetValue2State(oSysInfo.system, { name: "sys.system", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.model != "undefined") this.fSetValue2State(oSysInfo.model, { name: "sys.model", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.board_name != "undefined") this.fSetValue2State(oSysInfo.board_name, { name: "sys.board_name", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.release.distribution != "undefined") this.fSetValue2State(oSysInfo.release.distribution, { name: "sys.release.distribution", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.release.version != "undefined") this.fSetValue2State(oSysInfo.release.version, { name: "sys.release.version", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.release.revision != "undefined") this.fSetValue2State(oSysInfo.release.revision, { name: "sys.release.revision", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.release.target != "undefined") this.fSetValue2State(oSysInfo.release.target, { name: "sys.release.target", type: "text", role: "text", read: true, write: false });
if(typeof oSysInfo.release.description != "undefined") this.fSetValue2State(oSysInfo.release.description, { name: "sys.release.description", type: "text", role: "text", read: true, write: false });
}
//##################### DATA FUNCTION
fSetValue2State(oValue, oKey, sFolder, oTree, channelnames){
// eslint-disable-next-line prefer-const
let oCommon = this.fOverrideExists(oKey);
oCommon.name = oKey;
//this.log.info(oKey + ": " + type.get(oValue));
if (oCommon.type == "") { //NOT Overwritten
switch(type.get(oValue)) {
case "string":
oCommon.type = "string";
oCommon.role = "string";
oCommon.write = false;
break;
case "number":
oCommon.type = "number";
oCommon.role = "value";
oCommon.write = false;
break;
case "boolean":
oCommon.type = "boolean";
oCommon.role = "inidicator";
oCommon.write = false;
break;
case "array":
if (Object.entries(oTree[oKey]).length) {
this.setObjectNotExists(sFolder + "." + oKey, {
type: "channel",
native: {}
});
channelnames.remove(this.namespace + "." + sFolder + "." + oKey);
this.fSetValue2State(true,"isAvailable",sFolder+"."+oKey,oTree[oKey], channelnames);
this.fSetValue2State(this.formatDate(new Date(), "TT.MM.JJJJ hh:mm:ss"),"lastUpdate",sFolder+"."+oKey,oTree[oKey], channelnames);
for (const [key, value] of Object.entries(oTree[oKey])) {
oValue = oValue + ", "+ value;
this.fSetValue2State(value,key,sFolder+"."+oKey,oTree[oKey], channelnames);
}
oValue.slice(-1);
}
return; //No need to set this Parent Object
case "object":
if (Object.entries(oTree[oKey]).length) {
this.setObjectNotExists(sFolder + "." + oKey, {
type: "channel",
native: {}
});
channelnames.remove(this.namespace + "." + sFolder + "." + oKey);
this.fSetValue2State(true,"isAvailable",sFolder+"."+oKey,oTree[oKey], channelnames);
this.fSetValue2State(this.formatDate(new Date(), "TT.MM.JJJJ hh:mm:ss"),"lastUpdate",sFolder+"."+oKey,oTree[oKey], channelnames);
for (const [key, value] of Object.entries(oTree[oKey])) {
oValue = oValue + ", "+ value;
this.fSetValue2State(value,key,sFolder+"."+oKey,oTree[oKey], channelnames);
}
oValue.slice(-1);
}
return; //No need to set this Parent Object
default:
this.log.warn("Unhandled DataType: " + type.get(oValue) + " for " + oKey);
return; // Do Nothing
}
});
}
this.setObjectNotExists(sFolder + "." + oCommon.name, {
type: "state",
common: oCommon,
native: {}
}, (id, error) => {this.setState(sFolder + "." + oCommon.name, oValue, true);}
);
}
/*
fHTTPGetHostname() { //Hostname
fHTTPGetUbusCMD(sCMD,sAlias) { //ubus Communication
const oReqBody = {
"method": "hostname"
"method": "exec",
"params": [ sCMD ]
};

@@ -411,38 +525,26 @@ const oReqOpt = {

request(oReqOpt, async (error, response, body) => {
if (await this.fValidateHTTPResult(error,response,"GetHostname")) {
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
const oSetObj = { name: "sys.hostname", type: "text", role: "text", read: true, write: false };
this.fSetValue2State(oBody.result, oSetObj);
if (await this.fValidateHTTPResult(error,response,"GetUbusCMD, " + sCMD)) {
try {
//bug... output \n\t\ seems broken, delete it
body = this.replaceAll(body,"\n\t","");
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
const oTree = JSON.parse(oBody.result);
let sFolder = this.replaceAll(sAlias," ","_"); //Format CMD to be OK as ObjectName
sFolder = this.replaceAll(sFolder ,/\./,"-"); //Format CMD to be OK as ObjectName
this.getChannelsOf(sFolder.split(".")[0],(err,channels) => {
const channelnames = channels.map(channel => {return channel._id})
for (const [key, value] of Object.entries(oTree)) {
this.fSetValue2State(value,key,sFolder, oTree, channelnames);
}
channelnames.forEach(channel => {
this.fSetValue2State(false,"isAvailable",channel,oTree, channelnames);
})
});
}
} catch (e) {
this.log.error("##### GetUbusCMD, " + sCMD + " + CatchError: " + e);
}
}
});
}*/
fHTTPGetInterfaces() { //Get Interfaces
const oReqBody = {
"method": "net.devices"
};
const oReqOpt = {
"method": "POST",
"url": this.config.inp_url + "sys?auth="+this.config.sToken,
"headers": {
"Content-Type": ["application/json", "text/plain"]
},
"body": JSON.stringify(oReqBody)
};
request(oReqOpt, async (error, response, body) => {
if (await this.fValidateHTTPResult(error,response,"GetInterfaces")) {
const oBody = JSON.parse(body);
if (!oBody.error && oBody.result) {
oBody.result.forEach(oDev => {
//eth1.1 would result crappy, we replace . with /
oDev = oDev.replace(".","/");
const oSetObj = { name: "net.devices." + oDev + ".exists", type: "boolean", role: "indicator", read: true, write: false };
this.fSetValue2State(true, oSetObj);
});
}
}
});
}

@@ -449,0 +551,0 @@ }

{
"name": "iobroker.openwrt",
"version": "0.0.1",
"description": "Interact with the openwrt RPC API",
"_from": "github:Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e",
"_id": "iobroker.openwrt@0.0.3",
"_inBundle": false,
"_integrity": "",
"_location": "/iobroker.openwrt",
"_phantomChildren": {},
"_requested": {
"type": "git",
"raw": "Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e",
"rawSpec": "Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e",
"saveSpec": "github:Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e",
"fetchSpec": null,
"gitCommittish": "40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "github:Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e",
"_spec": "Schnup89/ioBroker.openwrt#40b7f9d8a784f6082bf1f10cc965c8f8ed2e128e",
"_where": "/opt/iobroker",
"author": {

@@ -9,17 +27,12 @@ "name": "Schnup89",

},
"homepage": "https://github.com/Schnup89/ioBroker.openwrt",
"license": "MIT",
"keywords": [
"openwrt",
"network",
"api",
"router"
],
"repository": {
"type": "git",
"url": "https://github.com/Schnup89/ioBroker.openwrt"
"bugs": {
"url": "https://github.com/Schnup89/ioBroker.openwrt/issues"
},
"bundleDependencies": false,
"dependencies": {
"@iobroker/adapter-core": "^2.3.0"
"@iobroker/adapter-core": "^2.3.0",
"get-type": "^1.1.0"
},
"deprecated": false,
"description": "Interact with the openwrt RPC API",
"devDependencies": {

@@ -35,25 +48,37 @@ "@iobroker/testing": "^2.2.0",

"@types/sinon-chai": "^3.2.4",
"axios": "^0.19.2",
"axios": "^0.21.2",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"eslint": "^6.8.0",
"get-type": "^1.1.0",
"gulp": "^4.0.2",
"mocha": "^7.1.1",
"proxyquire": "^2.1.3",
"sinon-chai": "^3.5.0",
"sinon": "^8.1.1"
"request": "^2.88.2",
"sinon": "^8.1.1",
"sinon-chai": "^3.5.0"
},
"homepage": "https://github.com/Schnup89/ioBroker.openwrt",
"keywords": [
"openwrt",
"network",
"api",
"router"
],
"license": "MIT",
"main": "main.js",
"name": "iobroker.openwrt",
"repository": {
"type": "git",
"url": "git+https://github.com/Schnup89/ioBroker.openwrt.git"
},
"scripts": {
"lint": "eslint",
"test": "npm run test:js && npm run test:package",
"test:integration": "mocha test/integration --exit",
"test:js": "mocha --opts test/mocha.custom.opts",
"test:package": "mocha test/package --exit",
"test:unit": "mocha test/unit --exit",
"test:integration": "mocha test/integration --exit",
"test": "npm run test:js && npm run test:package",
"lint": "eslint"
"test:unit": "mocha test/unit --exit"
},
"bugs": {
"url": "https://github.com/Schnup89/ioBroker.openwrt/issues"
},
"readmeFilename": "README.md"
"version": "0.0.3"
}
+64
-55

@@ -1,4 +0,5 @@

![Logo](admin/openwrt.png)
# ioBroker.openwrt
<img src="admin/openwrt.png" width="64">
# ioBroker.openwrt V0.0.3 seems broken, do not update
[![NPM version](http://img.shields.io/npm/v/iobroker.openwrt.svg)](https://www.npmjs.com/package/iobroker.openwrt)

@@ -8,3 +9,2 @@ [![Downloads](https://img.shields.io/npm/dm/iobroker.openwrt.svg)](https://www.npmjs.com/package/iobroker.openwrt)

![Number of Installations (stable)](http://iobroker.live/badges/openwrt-stable.svg)
[![Dependency Status](https://img.shields.io/david/Schnup89/iobroker.openwrt.svg)](https://david-dm.org/Schnup89/iobroker.openwrt)
[![Known Vulnerabilities](https://snyk.io/test/github/Schnup89/ioBroker.openwrt/badge.svg)](https://snyk.io/test/github/Schnup89/ioBroker.openwrt)

@@ -16,74 +16,83 @@

## openwrt adapter for ioBroker
Interact with the openwrt RPC API
This Adapter interacts with the OpenWrt RPC API of a OpenWrt-Device (Router, Switch, AccessPoint, RaspberryPI, etc.).
## Developer manual
This section is intended for the developer. It can be deleted later
**Reading data from ubus to ioBroker-Objects:**
At the moment only the "ubus call" results are fetched. With that commands you should get the most data out of the router.
The json-results are parsed and written to the objects database, <a href="https://openwrt.org/docs/techref/ubus">see here [ubus]</a>
### Getting started
**Setting data with ubus from ioBroker to OpenWrt:**
You can send Commands to the router over the API with the State-Object "sendCommand".
Put in the command you want to send to the router, the result will be written as JSON-Object to the "sendCommandLastResult" Object and the "sendCommand"-Object will be cleared.
You are almost done, only a few steps left:
1. Create a new repository on GitHub with the name `ioBroker.openwrt`
1. Push all files to the GitHub repo. The creator has already set up the local repository for you:
```bash
git push origin master
```
1. Head over to [main.js](main.js) and start programming!
### Best Practices
We've collected some [best practices](https://github.com/ioBroker/ioBroker.repositories#development-and-coding-best-practices) regarding ioBroker development and coding in general. If you're new to ioBroker or Node.js, you should
check them out. If you're already experienced, you should also take a look at them - you might learn something new :)
### ToDo / new Features
- ToDo: Initial Testing
- ToDo: Dynamic Objects, see https://forum.iobroker.net/topic/32465/dynamischer-objektbaum (german)
- Feature: Interface Handling (get Informations automaticly)
### Scripts in `package.json`
Several npm scripts are predefined for your convenience. You can run them using `npm run <scriptname>`
| Script name | Description |
|-------------|----------------------------------------------------------|
| `test:js` | Executes the tests you defined in `*.test.js` files. |
| `test:package` | Ensures your `package.json` and `io-package.json` are valid. |
| `test` | Performs a minimal test run on package files and your tests. |
| `lint` | Runs `ESLint` to check your code for formatting errors and potential bugs. |
### Writing tests
When done right, testing code is invaluable, because it gives you the
confidence to change your code while knowing exactly if and when
something breaks. A good read on the topic of test-driven development
is https://hackernoon.com/introduction-to-test-driven-development-tdd-61a13bc92d92.
Although writing tests before the code might seem strange at first, but it has very
clear upsides.
## Setup and Check API on Target-Device
### Setup
To enable the API, install the following package and restart `uhttpd`:
The template provides you with basic tests for the adapter startup and package files.
It is recommended that you add your own tests into the mix.
```bash
opkg install luci-mod-rpc
/etc/init.d/uhttpd restart
```
### Publishing the adapter
To get your adapter released in ioBroker, please refer to the documentation
of [ioBroker.repositories](https://github.com/ioBroker/ioBroker.repositories#requirements-for-adapter-to-get-added-to-the-latest-repository).
Source: [HowTo at the official OpenWrt-Github-Repo](https://github.com/openwrt/luci/wiki/JsonRpcHowTo)
### Test the adapter manually on a local ioBroker installation
In order to install the adapter locally without publishing, the following steps are recommended:
1. Create a tarball from your dev directory:
```bash
npm pack
```
1. Upload the resulting file to your ioBroker host
1. Install it locally (The paths are different on Windows):
```bash
cd /opt/iobroker
npm i /path/to/tarball.tgz
```
### Check
To check that the API ist working fine, just navigate to this url with your webbrowser:
```bash
http://[TargetDeviceIPorHostname]/cgi-bin/luci/rpc/auth
```
For later updates, the above procedure is not necessary. Just do the following:
1. Overwrite the changed files in the adapter directory (`/opt/iobroker/node_modules/iobroker.openwrt`)
1. Execute `iobroker upload openwrt` on the ioBroker host
If you get something like this, the API is successfully installed:
```bash
{"id":null,"error":{"message":"Parse error.","code":-32700},"jsonrpc":"2.0"}
```
> Side-Note: The URL-Check on the "admin"-Page checks for "jsonrpc" text in response
## Usage
- Type the URL, Username and Password (same as the SSH/Webinterface) in the admin page
- If everything works fine, you will see the new Objects:
<img src="github-ressources/example_objects.png" width=300>
- Get more Data with specific ubus call-commands, [check this out](https://github.com/Schnup89/ioBroker.openwrt/wiki/ubus-commands)
## Troubleshooting
If there is something wrong, you can check the communication at the admin-panel.
First the URL should be "OK", test it with the "Check URL"-Button.
Second the Authentication with user/pass can be tested with the "Check Auth"-Button.
If there are some error's the button will get red, look at the ioBroker-Logs for more informations .
## Changelog
### 0.0.3
* (Schnup89) Merged PR15, Thanks to "TyrionWarMage", New Parameter "Alias" and "isAvailable"
### 0.0.2
* (Schnup89) Merged PR13, Thanks to "TyrionWarMage", Parameter "Last Updated" is now set to the states
### 0.0.1
* (Schnup89) initial release
## License
MIT License
Copyright (c) 2020 Schnup89 <tobias_tsafi@gmx.de>
Copyright (c) 2022 Schnup89 <tobias_tsafi@gmx.de>

@@ -106,2 +115,2 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
<script type="text/x-iobroker" data-template-name="openwrt">
<div class="row">
<div class="col s2">
<input type="checkbox" data-field="enabled" data-default="false"/>
<!-- this field is mandatory, just to find out if to include this settings or not</span-->
<span class="translate">enabled</span>
</div>
<div class="col s4">
<input type="text" data-field="interval" size="30">
<span class="translate">period of time</span>
</div>
<div class="col s4">
<input type="text" data-field="state" size="30">
<span class="translate">new state</span>
</div>
<div class="col s2">
<input type="checkbox" data-field="setAck" data-default="false">
<span class="translate">ack</span>
</div>
</div>
</script>
<script type="text/javascript">
$.get("adapter/openwrt/words.js", function(script) {
let translation = script.substring(script.indexOf('{'), script.length);
translation = translation.substring(0, translation.lastIndexOf(';'));
$.extend(systemDictionary, JSON.parse(translation));
});
// There are two ways how to predefine default settings:
// - with attribute "data-default" (content independent)
// - with function in global variable "defaults". Function name is equal with adapter name.
// as input function receives object with all information concerning it
if (typeof defaults !== 'undefined') {
defaults["openwrt"] = function (obj, instanceObj) {
return {
enabled: false,
interval: '5m',
state: false,
setAck: false
};
}
}
</script>

Sorry, the diff of this file is not supported yet