Устройство поддерживает программные модули, которые можно создавать самому или использовать готовые и загружать их в виде HTML страниц или набора страниц/скриптов/стилей прямо в устройство. AIO модули можно сжимать (с версии ESP 1.11+) с помощью gzip и загружать с расширением rmod.
Что бы удалить страницу(ы) нажмите Submit без прикреплённого файла. Каждая загрузка удаляет все загруженное ранее, если необходимо добавить модуль, загружайте его вместе с уже загруженным ранее.
С версии 1.17 появилась возможность загрузки кастомного кода, который выполняется глобально. Для этого нужно загрузить в устройство файл с именем custom.js с Вашим кодом. С версии 1.20 при наличии этого файла в устройстве на интерфейсе в правом нижнем углу будет висеть маленький значок JS.
<!doctype html>
<html><head>
<title>...</title>
<script async src="/theme.js"></script>
<script src="/ui.js"></script>
<meta name="viewport" content="width=device-width,initial-scale=0.8">
<link rel="icon" href="/logo.webp">
<link rel="apple-touch-icon" sizes="256x256" href="/logo.webp">
<link rel="manifest" crossorigin="use-credentials" href="/manifest.json">
</head>
<body style="opacity:0">
<div class="conn_lost_out" id="conn_layout" style="display:none">
<div class="conn_lost_in"></div>
</div>
<div id="layout">
<div id="main">
<div class="header"><h1 l10n="mswitch.title">...</h1></div>
<div class="cntr ps" id="ps"><div class="spinner"></div></div>
<div class="content" id="cMenu">
<div class="pure-g cntr" id="x" hidden>
<div class="pure-u-1 pure-u-md-1-2" style="width:fit-content"><div class="card">
<h1>Boost</h1>
<button id="my-boost-1" class="pure-button button-primary">Boost 1.3</button>
<button id="my-boost-2" class="pure-button button-primary">Boost 1.0</button>
<h1>Fan PWM</h1>
<button id="my-fan-1" class="pure-button button-primary">95C + 8C</button>
<button id="my-fan-2" class="pure-button button-primary">90C + 10C</button>
<button id="my-fan-3" class="pure-button button-primary">Toggle</button>
<h1>PG0</h1>
<button id="my-pg-0" class="pure-button button-primary">Toggle</button>
<button id="my-pg-1" class="pure-button button-primary">Turn on 1 sec</button>
<h1>PG1</h1>
<button id="my-pg-2" class="pure-button button-primary">Toggle</button>
<button id="my-pg-3" class="pure-button button-primary">Turn on 1 sec</button>
<h1>Sound test</h1>
<button id="alarm-snd" class="pure-button button-primary">Alarm</button>
<button id="connlost-snd" class="pure-button button-primary">Connection lost</button>
<h1>Vibration test</h1>
<button id="vibr-test" class="pure-button button-primary">Test</button>
</div>
</div>
</div>
<footer style="text-align:right; font-size:10px;">v0.04</footer>
</div>
</div>
</div>
<script>
'use strict';
let d;
//BOOST 1.3 BUTTON
function my_boost_1() {
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/sp 130", 0, 1);
set("/sb 35", d+=100, 1);
set("/dt 70", d+=100, 1);
set("/dc 10", d+=100, 1);
}
//BOOST 1.0 BUTTON
function my_boost_2() {
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/sp 100", 0, 1);
set("/sb 35", d+=100, 1);
set("/dt 66", d+=100, 1);
set("/dc 0", d+=100, 1);
}
//FAN START 95C + 8C BUTTON
function my_fan_1() {
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/fa 95", 0, 1);
set("/fw 8", d+=100, 1);
}
//FAN START 90C + 10C BUTTON
function my_fan_2(){
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/fa 90", 0, 1);
set("/fw 10", d+=100, 1);
}
//TURN ON FAN MAX
function my_fan_3(){
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/fsw", 0, 1);
}
//PG0 output
function my_pg_0(){
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/x0r", 0, 1);
}
//PG0 output
function my_pg_1(){
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/x0r 1", 0, 1);
}
//PG1 output
function my_pg_2(){
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/x1r", 0, 1);
}
//PG1 output
function my_pg_3(){
d = 0;
brr(50); //Vibration feedback 1-1000ms
set("/x1r 1", 0, 1);
}
//Test vibration (safari not supported)
function my_vibr(){
try { window.navigator.vibrate([50,100,50,100,50]) }
catch(e) {}
}
//Buttons declaration
onLoad(()=> {
loaded = true;
setTimeout(()=>{$('title')[0].innerHTML = "RedBoxOBD - mSwitch"},500);
bnd($("#my-boost-1"), "click", my_boost_1);
bnd($("#my-boost-2"), "click", my_boost_2);
bnd($("#my-fan-1"), "click", my_fan_1);
bnd($("#my-fan-2"), "click", my_fan_2);
bnd($("#my-fan-3"), "click", my_fan_3);
bnd($("#my-pg-0"), "click", my_pg_0);
bnd($("#my-pg-1"), "click", my_pg_1);
bnd($("#my-pg-2"), "click", my_pg_2);
bnd($("#my-pg-3"), "click", my_pg_3);
bnd($("#alarm-snd"), "click", ()=>{alarm.play()});
bnd($("#connlost-snd"), "click", ()=>{connection_lost.play()});
bnd($("#vibr-test"), "click", my_vibr);
//Для динамической локализации (с версии ESP 1.32+)
const translations = {
'en': {
"mswitch.title": "Buttons"
},
'ru': {
"mswitch.title": "Кнопки"
},
'es': {
"mswitch.title": "Botones"
}
};
localization.addMultiLanguageTranslations(translations);
});
</script>
</body></html>
Готовые модули различного функционала доступны в загрузках