This commit is contained in:
Dmitry Borisenko
2020-09-02 22:33:03 +03:00
parent 26383c0a19
commit 70096c71c8
288 changed files with 0 additions and 29977 deletions

7
.gitignore vendored
View File

@@ -1,7 +0,0 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
lib/libraies-master

View File

@@ -1,2 +0,0 @@
/*.js.gz
/.exclude.files

View File

@@ -1,22 +0,0 @@
{
"name": "IoTmanager",
"chipID": "",
"apssid": "IoTmanager",
"appass": "",
"routerssid": "rise",
"routerpass": "hostel3333",
"timezone": 2,
"ntp": "pool.ntp.org",
"mqttServer": "91.204.228.124",
"mqttPort": 1883,
"mqttPrefix": "/iotTeam",
"mqttUser": "test",
"mqttPass": "test",
"scen": "1",
"pushingboxid": "v7C133E426B0C69E",
"weblogin": "admin",
"webpass": "admin",
"udponoff": "1",
"blink": "1",
"oneWirePin": "2"
}

Binary file not shown.

View File

@@ -1,658 +0,0 @@
<!--This is the plain html source of the hex encoded Editor-Page embedded in SPIFFSEditor.cpp -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>FS Editor</title>
<style type="text/css" media="screen">
.cm {
z-index: 300;
position: absolute;
left: 5px;
border: 1px solid #444;
background-color: #F5F5F5;
display: none;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
font-size: 12px;
font-family: sans-serif;
font-weight: bold;
}
.cm ul {
list-style: none;
top: 0;
left: 0;
margin: 0;
padding: 0;
}
.cm li {
position: relative;
min-width: 60px;
cursor: pointer;
}
.cm span {
color: #444;
display: inline-block;
padding: 6px;
}
.cm li:hover {
background: #444;
}
.cm li:hover span {
color: #EEE;
}
.tvu ul,
.tvu li {
padding: 0;
margin: 0;
list-style: none;
}
.tvu input {
position: absolute;
opacity: 0;
}
.tvu {
font: normal 12px Verdana, Arial, Sans-serif;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
color: #444;
line-height: 16px;
}
.tvu span {
margin-bottom: 5px;
padding: 0 0 0 18px;
cursor: pointer;
display: inline-block;
height: 16px;
vertical-align: middle;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADoSURBVBgZBcExblNBGAbA2ceegTRBuIKOgiihSZNTcC5LUHAihNJR0kGKCDcYJY6D3/77MdOinTvzAgCw8ysThIvn/VojIyMjIyPP+bS1sUQIV2s95pBDDvmbP/mdkft83tpYguZq5Jh/OeaYh+yzy8hTHvNlaxNNczm+la9OTlar1UdA/+C2A4trRCnD3jS8BB1obq2Gk6GU6QbQAS4BUaYSQAf4bhhKKTFdAzrAOwAxEUAH+KEM01SY3gM6wBsEAQB0gJ+maZoC3gI6iPYaAIBJsiRmHU0AALOeFC3aK2cWAACUXe7+AwO0lc9eTHYTAAAAAElFTkSuQmCC') no-repeat;
background-position: 0px 0px;
}
.tvu span:hover {
text-decoration: underline;
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
.tvu {
-webkit-animation: webkit-adjacent-element-selector-bugfix infinite 1s;
}
@-webkit-keyframes webkit-adjacent-element-selector-bugfix {
from {
padding: 0;
}
to {
padding: 0;
}
}
}
#uploader {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 28px;
line-height: 24px;
padding-left: 10px;
background-color: #444;
color: #EEE;
}
#tree {
position: absolute;
top: 28px;
bottom: 0;
left: 0;
width: 160px;
padding: 8px;
}
#editor,
#preview {
position: absolute;
top: 28px;
right: 0;
bottom: 0;
left: 160px;
border-left: 1px solid #EEE;
}
#preview {
background-color: #EEE;
padding: 5px;
}
#loader {
position: absolute;
top: 36%;
right: 40%;
}
.loader {
z-index: 10000;
border: 8px solid #b5b5b5;
/* Grey */
border-top: 8px solid #3498db;
/* Blue */
border-bottom: 8px solid #3498db;
/* Blue */
border-radius: 50%;
width: 240px;
height: 240px;
animation: spin 2s linear infinite;
display: none;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<script>
if (typeof XMLHttpRequest === "undefined") {
XMLHttpRequest = function () {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) { }
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e) { }
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { }
throw new Error("This browser does not support XMLHttpRequest.");
};
}
function ge(a) {
return document.getElementById(a);
}
function ce(a) {
return document.createElement(a);
}
function sortByKey(array, key) {
return array.sort(function (a, b) {
var x = a[key]; var y = b[key];
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
}
var QueuedRequester = function () {
this.queue = [];
this.running = false;
this.xmlhttp = null;
}
QueuedRequester.prototype = {
_request: function (req) {
this.running = true;
if (!req instanceof Object) return;
var that = this;
function ajaxCb(x, d) {
return function () {
if (x.readyState == 4) {
ge("loader").style.display = "none";
d.callback(x.status, x.responseText);
if (that.queue.length === 0) that.running = false;
if (that.running) that._request(that.queue.shift());
}
}
}
ge("loader").style.display = "block";
var p = "";
if (req.params instanceof FormData) {
p = req.params;
} else if (req.params instanceof Object) {
for (var key in req.params) {
if (p === "")
p += (req.method === "GET") ? "?" : "";
else
p += "&";
p += encodeURIComponent(key) + "=" + encodeURIComponent(req.params[key]);
};
}
this.xmlhttp = new XMLHttpRequest();
this.xmlhttp.onreadystatechange = ajaxCb(this.xmlhttp, req);
if (req.method === "GET") {
this.xmlhttp.open(req.method, req.url + p, true);
this.xmlhttp.send();
} else {
this.xmlhttp.open(req.method, req.url, true);
if (p instanceof String)
this.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
this.xmlhttp.send(p);
}
},
stop: function () {
if (this.running) this.running = false;
if (this.xmlhttp && this.xmlhttp.readyState < 4) {
this.xmlhttp.abort();
}
},
add: function (method, url, params, callback) {
this.queue.push({ url: url, method: method, params: params, callback: callback });
if (!this.running) {
this._request(this.queue.shift());
}
}
}
var requests = new QueuedRequester();
function createFileUploader(element, tree, editor) {
var xmlHttp;
var refresh = ce("button");
refresh.innerHTML = 'Refresh List';
ge(element).appendChild(refresh);
var input = ce("input");
input.type = "file";
input.multiple = false;
input.name = "data";
input.id = "upload-select";
ge(element).appendChild(input);
var path = ce("input");
path.id = "upload-path";
path.type = "text";
path.name = "path";
path.defaultValue = "/";
ge(element).appendChild(path);
var button = ce("button");
button.innerHTML = 'Upload';
ge(element).appendChild(button);
var mkfile = ce("button");
mkfile.innerHTML = 'Create';
ge(element).appendChild(mkfile);
var filename = ce("input");
filename.id = "editor-filename";
filename.type = "text";
filename.disabled = true;
filename.size = 20;
ge(element).appendChild(filename);
var savefile = ce("button");
savefile.innerHTML = ' Save ';
ge(element).appendChild(savefile);
function httpPostProcessRequest(status, responseText) {
if (status != 200)
alert("ERROR[" + status + "]: " + responseText);
else
tree.refreshPath(path.value);
}
function createPath(p) {
var formData = new FormData();
formData.append("path", p);
requests.add("PUT", "/edit", formData, httpPostProcessRequest);
}
mkfile.onclick = function (e) {
createPath(path.value);
editor.loadUrl(path.value);
path.value = "/";
};
savefile.onclick = function (e) {
editor.execCommand('saveCommand');
};
refresh.onclick = function (e) {
tree.refreshPath(path.value);
};
button.onclick = function (e) {
if (input.files.length === 0) {
return;
}
var formData = new FormData();
formData.append("data", input.files[0], path.value);
requests.add("POST", "/edit", formData, httpPostProcessRequest);
var uploadPath = ge("upload-path");
uploadPath.value = "/";
var uploadSelect = ge("upload-select");
uploadSelect.value = "";
};
input.onchange = function (e) {
if (input.files.length === 0) return;
var filename = input.files[0].name;
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
var name = /(.*)\.[^.]+$/.exec(filename)[1];
if (typeof name !== undefined) {
filename = name;
}
path.value = "/" + filename + "." + ext;
};
}
function createTree(element, editor) {
var preview = ge("preview");
var treeRoot = ce("div");
treeRoot.className = "tvu";
ge(element).appendChild(treeRoot);
function loadDownload(path) {
ge('download-frame').src = "/edit?download=" + path;
}
function loadPreview(path) {
var edfname = ge("editor-filename");
edfname.value = path;
ge("editor").style.display = "none";
preview.style.display = "block";
preview.innerHTML = '<img src="/edit?edit=' + path + '&_cb=' + Date.now() + '" style="max-width:100%; max-height:100%; margin:auto; display:block;" />';
}
function fillFileMenu(el, path) {
var list = ce("ul");
el.appendChild(list);
var action = ce("li");
list.appendChild(action);
if (isImageFile(path)) {
action.innerHTML = "<span>Preview</span>";
action.onclick = function (e) {
loadPreview(path);
if (document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
};
} else if (isTextFile(path)) {
action.innerHTML = "<span>Edit</span>";
action.onclick = function (e) {
editor.loadUrl(path);
if (document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
};
}
var download = ce("li");
list.appendChild(download);
download.innerHTML = "<span>Download</span>";
download.onclick = function (e) {
loadDownload(path);
if (document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
};
var delFile = ce("li");
list.appendChild(delFile);
delFile.innerHTML = "<span>Delete</span>";
delFile.onclick = function (e) {
httpDelete(path);
if (document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
};
}
function showContextMenu(event, path, isfile) {
var divContext = ce("div");
var scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft;
var left = event.clientX + scrollLeft;
var top = event.clientY + scrollTop;
divContext.className = 'cm';
divContext.style.display = 'block';
divContext.style.left = left + 'px';
divContext.style.top = top + 'px';
fillFileMenu(divContext, path);
document.body.appendChild(divContext);
var width = divContext.offsetWidth;
var height = divContext.offsetHeight;
divContext.onmouseout = function (e) {
if (e.clientX < left || e.clientX > (left + width) || e.clientY < top || e.clientY > (top + height)) {
if (document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(divContext);
}
};
}
function createTreeLeaf(path, name, size) {
var leaf = ce("li");
leaf.id = name;
var label = ce("span");
label.innerHTML = name;
leaf.appendChild(label);
leaf.onclick = function (e) {
if (isTextFile(leaf.id.toLowerCase())) {
editor.loadUrl(leaf.id);
} else if (isImageFile(leaf.id.toLowerCase())) {
loadPreview(leaf.id);
}
};
leaf.oncontextmenu = function (e) {
e.preventDefault();
e.stopPropagation();
showContextMenu(e, leaf.id, true);
};
return leaf;
}
function addList(parent, path, items) {
sortByKey(items, 'name');
var list = ce("ul");
parent.appendChild(list);
var ll = items.length;
for (var i = 0; i < ll; i++) {
if (items[i].type === "file")
list.appendChild(createTreeLeaf(path, items[i].name, items[i].size));
}
}
function isTextFile(path) {
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
if (typeof ext !== undefined) {
switch (ext) {
case "cnv":
case "txt":
case "htm":
case "html":
case "js":
case "css":
case "xml":
case "json":
case "conf":
case "ini":
return true;
}
}
return false;
}
function isImageFile(path) {
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
if (typeof ext !== undefined) {
switch (ext) {
case "png":
case "jpg":
case "jpeg":
case "gif":
case "bmp":
return true;
}
}
return false;
}
this.refreshPath = function (path) {
treeRoot.removeChild(treeRoot.childNodes[0]);
httpGet(treeRoot, "/");
};
function delCb(path) {
return function (status, responseText) {
if (status != 200) {
alert("ERROR[" + status + "]: " + responseText);
} else {
treeRoot.removeChild(treeRoot.childNodes[0]);
httpGet(treeRoot, "/");
}
}
}
function httpDelete(filename) {
var formData = new FormData();
formData.append("path", filename);
requests.add("DELETE", "/edit", formData, delCb(filename));
}
function getCb(parent, path) {
return function (status, responseText) {
if (status == 200)
addList(parent, path, JSON.parse(responseText));
}
}
function httpGet(parent, path) {
requests.add("GET", "/edit", { list: path }, getCb(parent, path));
}
httpGet(treeRoot, "/");
return this;
}
function createEditor(element, file, lang, theme, type) {
function getLangFromFilename(filename) {
var lang = "plain";
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
if (typeof ext !== undefined) {
switch (ext) {
case "cnv": lang = "plain"; break;
case "txt": lang = "plain"; break;
case "hex": lang = "plain"; break;
case "conf": lang = "plain"; break;
case "htm": lang = "html"; break;
case "js": lang = "javascript"; break;
case "css":
case "scss":
case "php":
case "html":
case "json":
case "xml":
case "ini": lang = ext;
}
}
return lang;
}
if (typeof file === "undefined") file = "/index.html";
if (typeof lang === "undefined") {
lang = getLangFromFilename(file);
}
if (typeof theme === "undefined") theme = "textmate";
if (typeof type === "undefined") {
type = "text/" + lang;
if (lang === "c_cpp") type = "text/plain";
}
var editor = ace.edit(element);
function httpPostProcessRequest(status, responseText) {
if (status != 200) alert("ERROR[" + status + "]: " + responseText);
}
function httpPost(filename, data, type) {
var formData = new FormData();
formData.append("data", new Blob([data], { type: type }), filename);
requests.add("POST", "/edit", formData, httpPostProcessRequest);
}
function httpGetProcessRequest(status, responseText) {
ge("preview").style.display = "none";
ge("editor").style.display = "block";
if (status == 200)
editor.setValue(responseText);
else
editor.setValue("");
editor.clearSelection();
}
function httpGet(theUrl) {
requests.add("GET", "/edit", { edit: theUrl }, httpGetProcessRequest);
}
if (lang !== "plain") editor.getSession().setMode("ace/mode/" + lang);
editor.setTheme("ace/theme/" + theme);
editor.$blockScrolling = Infinity;
editor.getSession().setUseSoftTabs(true);
editor.getSession().setTabSize(2);
editor.setHighlightActiveLine(true);
editor.setShowPrintMargin(false);
editor.commands.addCommand({
name: 'saveCommand',
bindKey: { win: 'Ctrl-S', mac: 'Command-S' },
exec: function (editor) {
httpPost(file, editor.getValue() + "", type);
},
readOnly: false
});
editor.commands.addCommand({
name: 'undoCommand',
bindKey: { win: 'Ctrl-Z', mac: 'Command-Z' },
exec: function (editor) {
editor.getSession().getUndoManager().undo(false);
},
readOnly: false
});
editor.commands.addCommand({
name: 'redoCommand',
bindKey: { win: 'Ctrl-Shift-Z', mac: 'Command-Shift-Z' },
exec: function (editor) {
editor.getSession().getUndoManager().redo(false);
},
readOnly: false
});
editor.loadUrl = function (filename) {
var edfname = ge("editor-filename");
edfname.value = filename;
file = filename;
lang = getLangFromFilename(file);
type = "text/" + lang;
if (lang !== "plain") editor.getSession().setMode("ace/mode/" + lang);
httpGet(file);
};
return editor;
}
function onBodyLoad() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) { vars[key] = value; });
var editor = createEditor("editor", vars.file, vars.lang, vars.theme);
var tree = createTree("tree", editor);
createFileUploader("uploader", tree, editor);
if (typeof vars.file === "undefined") vars.file = "/dev_conf.txt";
editor.loadUrl(vars.file);
};
</script>
<script id='ace' src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js" type="text/javascript"
charset="utf-8"></script>
<script>
if (typeof ace.edit == "undefined") {
var script = document.createElement('script');
script.src = "/ace.js";
script.async = false;
document.head.appendChild(script);
}
</script>
</head>
<body onload="onBodyLoad();">
<div id="loader" class="loader"></div>
<div id="uploader"></div>
<div id="tree"></div>
<div id="editor"></div>
<div id="preview" style="display:none;"></div>
<iframe id=download-frame style='display:none;'></iframe>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

View File

@@ -1,69 +0,0 @@
{
"configs": [
"/config.live.json",
"/config.setup.json",
"/lang/lang.ru.json"
],
"title": "Главная",
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "text",
"class": "alert alert-light",
"title": "<center><img src='/icon.jpeg' alt='IoT Manager'></center>"
},
{
"type": "link",
"title": "Конфигурация устройства",
"action": "/?set.device",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Список других устройств в сети",
"action": "/?set.udp",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Конфигурация WIFI",
"action": "/?set.wifi",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Конфигурация MQTT",
"action": "/?set.mqtt",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Конфигурация push",
"action": "/?set.push",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Утилиты",
"action": "/?set.utilities",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Скачать приложение IoT Manager для android",
"action": "https://play.google.com/store/apps/details?id=ru.esp8266.iotmanager",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Скачать приложение IoT Manager для iphone",
"action": "https://apps.apple.com/ru/app/iot-manager/id1155934877",
"class": "btn btn-block btn-default"
}
]
}

View File

@@ -1 +0,0 @@
analog-adc;id;anydata;Сенсоры;Аналоговый;order;pin-adc;map[1,1024,1,1024];c[1]

View File

@@ -1 +0,0 @@
button-in;id;toggle;Кнопки;Освещение;order;pin;db[20]

View File

@@ -1 +0,0 @@
button-out;id;toggle;Кнопки;Освещение;order;pin;inv[1];st[1]

View File

@@ -1 +0,0 @@
button-out;id;toggle;Кнопки;Освещение;order;st[0]

View File

@@ -1 +0,0 @@
button-out;id;toggle;Кнопки;Освещение;order;pin;st[0]

View File

@@ -1 +0,0 @@
input-digit;id;inputDigit;Ввод;Введите#цифру;order;st[60]

View File

@@ -1 +0,0 @@
input-time;id;inputTime;Ввод;Введите#время;order;st[10-00-00]

View File

@@ -1 +0,0 @@
output-text;id;anydata;Вывод;Сигнализация;order;st[Обнаружено#движение]

View File

@@ -1 +0,0 @@
pwm-out;id;range;Ползунки;Яркость;order;pin;st[500]

View File

@@ -1,5 +0,0 @@
{
"more":">",
"less":"<",
"eq":"="
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,39 +0,0 @@
{
"SetDevConf": "Конфигурация устройства",
"SetDevPreset": "Выберите из списка подходящий пресет кофигурации",
"ButSave":"Сохранить",
"ButMainPage":"Главная",
"SetUDPList": "Список других устройств в сети:",
"SetUDPWarn1": "После нажатия на кнопку <b>переформировать список устройств</b> ждите примерно минуту, а затем обновите страницу и список появится вновь",
"SetUDPUpdateList":"Переформировать список устройств",
"SetUDPUpdatePage":"Обновить страницу",
"SetUDPNameOfDev":"Имя этого устройства:",
"SetUDPDateExchange":"Включить обмен данными между устройствами",
"SetUDPWarn2":"Если обмен данными включен, то устройства будут обмениваться широковещательными пакетами udp для формирования списка устройств и для осуществления посылки настроек mqtt. Данный обмен создает дополнительную нагрузку на wifi сеть.",
"SetWiFiNameOfDev":"Имя устройства:",
"SetWiFiRouterConnect":"Подключение к WiFi роутеру:",
"SetWiFiAccessPoint":"Точка доступа:",
"SetWiFiWeb":"Логин и пароль web interface:",
"SetWiFiTimeZone":"Временная зона:",
"SetWiFiNTP":"Сервер NTP:",
"SetWiFiWarn1":"Имя устройства должно состоять из английских букв и иметь длинну от 6 до 12 символов",
"SetWiFiWarn2":"После того как вы введете логин пароль от вашего wifi роутера необходимо нажать кнопку сохранить, а затем обязательно нажать кнопку <b>перезагрузить устройство</b> внизу этой страницы",
"SetWiFiWarn3":"Устройство постоянно сканирует сеть на наличие wifi. Если роутер отключен, то устройство автоматически перейдет в режим точки доступа. Когда wifi появится устройство автоматически подключится к роутеру снова, и выключит точку доступа",
"SetWiFiWarn4":"После изменения поля <b>NTP сервер</b> необходимо перезагрузить устройство",
"SetWiFiWarn5":"Светодиод статуса подключения показывает четыре состояния подключения: <br><b>1. мигает редко</b> - идет подключение к wifi <br><b>2. мигает часто</b> - идет подключение к серверу mqtt <br><b>3. горит постоянно</b> - модуль в режиме точки доступа, <br><b>4. не горит</b> - модуль подключен к wifi и к mqtt. <br>Светодиод подключен к gpio2. Если галочка стоит - то использовать этот пин нельзя",
"SetMQTTServerName":"Имя сервера:",
"SetMQTTPort":"Номер порта:",
"SetMQTTPrefix":"Префикс:",
"SetMQTTUserName":"Имя пользователя:",
"SetMQTTPassword":"Пароль:",
"SetMQTTSendSettings":"Отправить настройки MQTT с этого устройства на все остальные",
"SetMQTTWarn1":"Обратите внимание что поле префикс может состоять только из одного слова и одного разделителя: <b>/prefix</b>, вариант вида: <b>/prefix1/prefix2</b> работать не будет. После изменения поля prefix необходимо перезагрузить устройство",
"SetMQTTWarn2":"Прежде чем нажимать на кнопку <b>Отправить настройки MQTT</b> сохрание их, если Вы их меняли. Настройки получат и перезапишут все устройства в локальной сети"
}

View File

@@ -1 +0,0 @@
Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета
1 Тип элемента Id Виджет Имя вкладки Имя виджета Позиция виджета

View File

@@ -1 +0,0 @@
//

View File

@@ -1,143 +0,0 @@
{
"configs": [
"/config.setup.json",
"/config.option.json",
"/config.live.json",
"/lang/lang.ru.json"
],
"class": "col-sm-offset-1 col-sm-10",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Device ID: {{chipID}}"
},
{
"type": "h4",
"title": "IP address: {{ip}}"
},
{
"type": "h4",
"title": "Time: {{time}}"
},
{
"type": "h4",
"title": "Uptime: {{uptime}}"
},
{
"type": "h4",
"title": "Build version: {{firmware_version}}"
},
{
"type": "h4",
"title": "LittleFS version: 2.4.0"
},
{
"type": "hr"
},
{
"type": "dropdown",
"name": "help-url",
"class": "btn btn-default",
"style": "display:inline",
"title": {
"#": "Выберите элемент из списка<span class=\"caret\"></span>",
"/set?addItem=button-out-p": "1.Кнопка управляющая пином",
"/set?addItem=button-out-np": "2.Кнопка не привязанная к пину",
"/set?addItem=pwm-out": "3.Широтно импульсная модуляция(pwm)",
"/set?addItem=button-in": "4.Физическая кнопка",
"/set?addItem=input-digit": "5.Окно ввода цифровых значений",
"/set?addItem=input-time": "6.Окно ввода времени",
"/set?addItem=output-text": "7.Окно вывода любого текста, предупреждения, цифры",
"/set?addItem=analog-adc": "8.Аналоговый сенсор"
}
},
{
"type": "hr"
},
{
"type": "csv",
"title": [
"html",
"text",
"text",
"text",
"text",
"text"
],
"state": "s.conf.csv",
"style": "width:100%;",
"action": "/set?saveItems",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Удалить все",
"action": "/set?delAllItems",
"class": "btn btn-block btn-default"
},
{
"type": "h2",
"title": "Сценарии"
},
{
"type": "checkbox",
"name": "scen",
"title": "Включить сценарии",
"action": "/set?scen=[[scen]]",
"state": "{{scen}}"
},
{
"type": "file",
"state": "s.scen.txt",
"style": "width:100%;height:350px",
"title": "Сохранить",
"action": "/set?sceninit",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Инструкция к системе автоматизации",
"action": "https://github.com/IoTManagerProject/IoTManager/wiki",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Очистить логи сенсоров",
"action": "/set?cleanlog",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"name": "my-block",
"style": "position:fixed;top:50%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class": "hidden"
},
{
"type": "button",
"title": "Обновить прошивку устройства",
"action": "/check",
"response": "[[my-block]]",
"class": "btn btn-block btn-default"
}
]
}

View File

@@ -1,143 +0,0 @@
{
"configs": [
"/config.setup.json",
"/config.option.json",
"/config.live.json",
"/lang/lang.ru.json"
],
"class": "col-sm-offset-1 col-sm-10",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Device ID: {{chipID}}"
},
{
"type": "h4",
"title": "IP address: {{ip}}"
},
{
"type": "h4",
"title": "Time: {{time}}"
},
{
"type": "h4",
"title": "Uptime: {{uptime}}"
},
{
"type": "h4",
"title": "Build version: {{firmware_version}}"
},
{
"type": "h4",
"title": "LittleFS version: 2.3.5"
},
{
"type": "hr"
},
{
"type": "dropdown",
"name": "help-url",
"class": "btn btn-default",
"style": "display:inline",
"title": {
"#": "{{SetDevPreset}}<span class=\"caret\"></span>",
"/set?preset=001": "1.Вкл. выкл. локального реле",
"/set?preset=002": "2.Вкл. выкл. локального реле в определенное время",
"/set?preset=003": "3.Вкл. выкл. локального реле на определенный период времени",
"/set?preset=004": "4.Вкл. выкл. нескольких локальных реле кнопкой в приложении",
"/set?preset=005": "5.Вкл. выкл. локального реле физической кнопкой и кнопкой в приложении параллельно (для выключателя света)",
"/set?preset=006": "6.Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
"/set?preset=007": "7.Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
"/set?preset=008": "8.Широтно импульсная модуляция",
"/set?preset=009": "9.Сенсор DHT11 (темп, влажность) и логгирование",
"/set?preset=010": "10.Сенсор DHT22, DHT33, DHT44, AM2302, RHT03 (темп, влажность) и логгирование",
"/set?preset=011": "11.Аналоговый сенсор и логгирование",
"/set?preset=012": "12.Cенсор bmp280 (темп, давление) и логгирование",
"/set?preset=013": "13.Cенсор bme280 (темп, давление, влажность, высота) и логгирование",
"/set?preset=014": "14.Сенсор DS18B20 (темп) и логгирование",
"/set?preset=015": "15.Термостат на DS18B20 с переключением в ручной режим и логгированием",
"/set?preset=016": "16.Котроль уровня в баке (датчик расстояния) на сенсорах: JSN-SR04T, HC-SR04, HY-SRF05 и логгирование",
"/set?preset=017": "17.Датчик движения включающий свет",
"/set?preset=018": "18.Охранный датчик движения",
"/set?preset=019": "19.Система управления шаговыми двигателями на основе драйвера A4988 (открытие закрытие штор)",
"/set?preset=020": "20.Система управления сервоприводами",
"/set?preset=021": "21.Модуль uart (serial). Двухстороняя связь с устройством через uart. Получение данных и отправка команд",
"/set?preset=100": "22.Настройки по умолчанию"
}
},
{
"type": "h2",
"title": "{{SetDevConf}}"
},
{
"type": "file",
"state": "dev_conf.txt",
"style": "width:100%;height:350px",
"title": "Сохранить",
"action": "/set?devinit",
"class": "btn btn-block btn-default"
},
{
"type": "h2",
"title": "Сценарии"
},
{
"type": "checkbox",
"name": "scen",
"title": "Включить сценарии",
"action": "/set?scen=[[scen]]",
"state": "{{scen}}"
},
{
"type": "file",
"state": "dev_scen.txt",
"style": "width:100%;height:350px",
"title": "Сохранить",
"action": "/set?sceninit",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Инструкция к системе автоматизации",
"action": "https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/wiki/Instruction",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "Очистить логи сенсоров",
"action": "/set?cleanlog",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"name": "my-block",
"style": "position:fixed;top:50%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class": "hidden"
},
{
"type": "button",
"title": "Обновить прошивку устройства",
"action": "/check",
"response": "[[my-block]]",
"class": "btn btn-block btn-default"
}
]
}

View File

@@ -1,133 +0,0 @@
{
"configs": [
"/config.setup.json",
"/lang/lang.ru.json"
],
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "{{SetMQTTServerName}}",
"style": "width:60%;float:left;"
},
{
"type": "input",
"title": "",
"name": "mqttServer-arg",
"state": "{{mqttServer}}",
"style": "width:40%;float:right"
},
{
"type": "h4",
"title": "{{SetMQTTPort}}",
"style": "width:60%;float:left;"
},
{
"type": "input",
"title": "",
"name": "mqttPort-arg",
"state": "{{mqttPort}}",
"style": "width:40%;float:right"
},
{
"type": "h4",
"title": "{{SetMQTTPrefix}}",
"style": "width:60%;float:left;"
},
{
"type": "input",
"title": "",
"name": "mqttPrefix-arg",
"state": "{{mqttPrefix}}",
"style": "width:40%;float:right"
},
{
"type": "h4",
"title": "{{SetMQTTUserName}}",
"style": "width:60%;float:left;"
},
{
"type": "input",
"title": "",
"name": "mqttUser-arg",
"state": "{{mqttUser}}",
"style": "width:40%;float:right"
},
{
"type": "h4",
"title": "{{SetMQTTPassword}}",
"style": "width:60%;float:left;"
},
{
"type": "input",
"title": "",
"name": "mqttPass-arg",
"state": "{{mqttPass}}",
"style": "width:40%;float:right"
},
{
"type": "h3",
"name": "my-block",
"style": "position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class": "hidden"
},
{
"type": "button",
"title": "{{ButSave}}",
"style": "width:100%;float:left;",
"action": "set?mqttServer=[[mqttServer-arg]]&mqttPort=[[mqttPort-arg]]&mqttPrefix=[[mqttPrefix-arg]]&mqttUser=[[mqttUser-arg]]&mqttPass=[[mqttPass-arg]]",
"class": "btn btn-block btn-default"
},
{
"type": "button",
"style": "width:100%;float:left;",
"title": "{{SetMQTTSendSettings}}",
"action": "set?mqttsend",
"class": "btn btn-block btn-default"
},
{
"type": "button",
"style": "width:100%;float:left;",
"title": "Проверить соединение с MQTT",
"action": "set?mqttcheck",
"response": "[[my-block]]",
"class": "btn btn-block btn-default"
},
{
"type": "text",
"style": "width:100%;float:left;",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetMQTTWarn1}}</p></font></div>"
},
{
"type": "text",
"style": "width:100%;float:left;",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetMQTTWarn2}}</p></font></div>"
},
{
"type": "link",
"style": "width:100%;float:left;",
"title": "Перезагрузить устройство",
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
"class": "btn btn-block btn-danger"
}
]
}

View File

@@ -1,51 +0,0 @@
{
"configs": [
"/config.setup.json",
"/lang/lang.ru.json"
],
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h4",
"style": "width:60%;float:left;",
"title": "Device id:"
},
{
"type": "input",
"title": "",
"name": "push-arg",
"style": "width:40%;float:right",
"state": "{{pushingboxid}}"
},
{
"type": "button",
"title": "{{ButSave}}",
"action": "set?pushingboxid=[[push-arg]]",
"class": "btn btn-block btn-default",
"style": "width:100%;display:inline"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Перезагрузить устройство",
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
"class": "btn btn-block btn-danger"
}
]
}

View File

@@ -1,96 +0,0 @@
{
"configs": [
"/config.setup.json",
"/lang/lang.ru.json"
],
"title": "Главная",
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "{{SetUDPList}}"
},
{
"type": "hr"
},
{
"type": "csv",
"title": [
"html",
"html",
"html"
],
"state": "dev.csv",
"style": "width:100%;",
"class": "nan"
},
{
"type": "hr"
},
{
"type": "link",
"title": "{{SetUDPUpdateList}}",
"action": "/set?updatelist",
"class": "btn btn-block btn-default"
},
{
"type": "link",
"title": "{{SetUDPUpdatePage}}",
"action": "/set?updatepage",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetUDPWarn1}}</p></font></div>",
"style": "width:100%;float:left;"
},
{
"type": "h3",
"title": "{{SetUDPNameOfDev}}"
},
{
"type": "input",
"title": "{{SetUDPNameOfDev}}",
"name": "devname-arg",
"state": "{{name}}",
"pattern": "[A-Za-z0-9]{6,12}"
},
{
"type": "button",
"title": "{{ButSave}}",
"action": "/set?devname=[[devname-arg]]",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "checkbox",
"name": "udponoff",
"title": "{{SetUDPDateExchange}}",
"action": "/set?udponoff=[[udponoff]]",
"state": "{{udponoff}}"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetUDPWarn2}}</p></font></div>"
}
]
}

View File

@@ -1,39 +0,0 @@
{
"configs": [
"/config.live.json",
"/config.setup.json",
"/lang/lang.ru.json"
],
"title": "Главная",
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "Сканирование шины i2c"
},
{
"type": "h4",
"title": "{{i2c}}"
},
{
"type": "link",
"title": "Сканировать",
"action": "/set?i2c",
"class": "btn btn-block btn-default"
}
]
}

View File

@@ -1,185 +0,0 @@
{
"configs": [
"/config.setup.json",
"/lang/lang.ru.json"
],
"title": "Конфигурация",
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-default"
},
{
"type": "link",
"title": "{{ButMainPage}}",
"action": "/",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "{{SetWiFiNameOfDev}}"
},
{
"type": "input",
"title": "{{SetWiFiNameOfDev}}",
"name": "devname-arg",
"state": "{{name}}",
"pattern": "[A-Za-z0-9]{6,12}"
},
{
"type": "button",
"title": "{{ButSave}}",
"action": "set?devname=[[devname-arg]]",
"class": "btn btn-block btn-default"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn1}}</p></font></div>"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "{{SetWiFiRouterConnect}}"
},
{
"type": "input",
"title": "",
"name": "routerssid-arg",
"state": "{{routerssid}}"
},
{
"type": "password",
"title": "",
"name": "routerpass-arg",
"state": "{{routerpass}}"
},
{
"type": "button",
"title": "{{ButSave}}",
"class": "btn btn-block btn-default",
"action": "set?routerssid=[[routerssid-arg]]&routerpass=[[routerpass-arg]]"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn2}}</p></font></div>"
},
{
"type": "hr"
},
{
"type": "checkbox",
"name": "blink",
"title": "Включить светодиод статуса подключения",
"action": "/set?blink=[[blink]]",
"state": "{{blink}}"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn5}}</p></font></div>"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "{{SetWiFiAccessPoint}}"
},
{
"type": "input",
"title": "",
"name": "apssid-arg",
"state": "{{apssid}}",
"pattern": ".{1,20}"
},
{
"type": "password",
"title": "",
"name": "appass-arg",
"state": "{{appass}}",
"pattern": ".{8,20}"
},
{
"type": "button",
"title": "{{ButSave}}",
"action": "set?apssid=[[apssid-arg]]&appass=[[appass-arg]]",
"class": "btn btn-block btn-default"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn3}}</p></font></div>"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "{{SetWiFiWeb}}"
},
{
"type": "input",
"title": "Логин",
"name": "weblogin-arg",
"state": "{{weblogin}}",
"pattern": ".{1,20}"
},
{
"type": "password",
"title": "Пароль",
"name": "webpass-arg",
"state": "{{webpass}}",
"pattern": ".{1,20}"
},
{
"type": "button",
"title": "{{ButSave}}",
"action": "set?weblogin=[[weblogin-arg]]&webpass=[[webpass-arg]]",
"class": "btn btn-block btn-default"
},
{
"type": "hr"
},
{
"type": "h3",
"title": "{{SetWiFiTimeZone}}"
},
{
"type": "input",
"title": "",
"name": "timezone-arg",
"state": "{{timezone}}",
"pattern": ".{1,20}"
},
{
"type": "input",
"title": "",
"name": "ntp-arg",
"state": "{{ntp}}"
},
{
"type": "button",
"title": "{{ButSave}}",
"action": "set?timezone=[[timezone-arg]]&ntp=[[ntp-arg]]",
"class": "btn btn-block btn-default"
},
{
"type": "text",
"title": "<div style='margin-top:10px;margin-bottom:10px;'><font color='black'><p style='border: 1px solid #DCDCDC; border-radius: 3px; background-color: #F5F5F5; padding: 10px;'>{{SetWiFiWarn4}}</p></font></div>"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Перезагрузить устройство",
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/set?device=ok');}",
"class": "btn btn-block btn-danger"
}
]
}

View File

@@ -1,6 +0,0 @@
{
"widget": "anydata",
"icon": "body",
"color": "red",
"descrColor": "red"
}

View File

@@ -1,5 +0,0 @@
{
"widget": "anydata",
"after": "",
"icon": ""
}

View File

@@ -1,5 +0,0 @@
{
"widget": "chart",
"series": "Temperature, °C",
"dateFormat": "HH:mm"
}

View File

@@ -1,7 +0,0 @@
{
"widget": "fillgauge",
"circleColor": "#00FFFF",
"textColor": "#FFFFFF",
"waveTextColor": "#000000",
"waveColor": "#00FFFF"
}

View File

@@ -1,6 +0,0 @@
{
"widget" : "input",
"size" : "small",
"color" : "orange",
"type" : "date"
}

View File

@@ -1,5 +0,0 @@
{
"widget" : "input",
"color" : "blue",
"type" : "number"
}

View File

@@ -1,6 +0,0 @@
{
"widget" : "input",
"size" : "small",
"color" : "orange",
"type" : "text"
}

View File

@@ -1,5 +0,0 @@
{
"widget" : "input",
"color" : "blue",
"type" : "time"
}

View File

@@ -1,12 +0,0 @@
{
"widget": "progress-line",
"icon": "sunny",
"descrColor": "",
"color": "",
"max": "100",
"background": "",
"stroke": "10",
"disabled": "",
"before": "",
"after": ""
}

View File

@@ -1,11 +0,0 @@
{
"widget": "progress-round",
"descrColor": "",
"max": "100",
"stroke": "20",
"color": "#45ccce",
"background": "#777",
"before": "",
"semicircle": "1",
"after": ""
}

View File

@@ -1,9 +0,0 @@
{
"widget" : "range",
"descrColor": "red",
"after" : "%",
"k" : 0.0977,
"min" : 0,
"max" : 100,
"debounce": 500
}

View File

@@ -1,7 +0,0 @@
{
"widget" : "select",
"size" : "small",
"fill" : "outline",
"options" : "["Zero item", "First item", "Second item"]",
"status" : 2
}

View File

@@ -1,5 +0,0 @@
{
"widget": "toggle",
"icon": "",
"iconOff": ""
}

566
doc/1.txt
View File

@@ -1,566 +0,0 @@
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## Возможности
- Объединение различных по типу и назначению устройств: управление, получение данных, и настройка параметров - всё в одном приложении
- Взаимодействие с устройствами осуществляется через "облачный" сервис с использованием протокола mqtt, позволит контролировать их из любой точки Мира (при наличии доступа в Интернет)
- Поддержка нескольких профилей и их переключение "на лету", дает возможность объединить устройства в группы
Настройка (после "прошивки") производится через веб-интерфейс, чтобы получить к нему доступ необходимо соединиться с WiFi AP устройства и набрать в адресной строке браузера http://192.168.4.1.
Далее выбрать типовой шаблон автоматизации, произвести настройку под свои требования и задачи.
Основные разделы интерфейса: конфигурация и сценарии.
В окне конфигурации задаются "объекты", "элементы управления" устройства (dashboard) - им устройство будет представлено в приложении компаньоне проекта. В окне сценариев задаются реакции на события и изменения в параметрах работы системы.
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## Команды, назначение и применение
Команды служат для настройки и управления устройством и его взаимодействия
**`buttonSet 1 1`** Изменит состояние "кнопки" №1, установит его в значение 1
**`pinSet 13 0`** Установит GPIO 13 состояние 0
**`pinChange 13`** Состояние GPIO 13 будет изменено на противоположное
**`pwmSet 1 500`** Настройка pwm №1 будет использовано значение 500
**`timeSet 1 08-00-00`** Установит для элемента ввода времени - inputTime значение 08:00:00
**`digitSet 1 56`** Элемент №1 (для цифровых параметров) отобразит число 56
**`stepperSet 1 100 1`** Шаговый двигатель №1 - вращение 100 "шагов" по часовой стрелке (для движения в обратную сторону используются отрицательные значения параметра)
**`servoSet 1 180`** Сервопривод №1 принять положение 180°
**`timerStart 1 60 sec`** Установить для таймера №1 обратный отсчёт в 60 секунд
**`timerStop 1`** Остановить таймер №1
**`textSet 1 Привет`** Установить для элемента текстовое поле №1 - "привет"
**`push Внимание Протечка`** Отправить push-уведомление с темой "внимание" и содержанием "протечка"
**`firmwareUpdate`** Обновить прошивку устройства "по воздуху"
**`firmwareVersion Версия прошивки Системные 1`** Узнать версию прошивки устройстве
## Сценарии
Элементарный блок в сценарии состоит из набора команд и триггера - условия для их выполнения
**temp > 60**
digitSet 1 60
stepperSet 1 100 1
textSet 1 Перегрев
**end**
Условие: когда температура превысит 60°
Запустит: команда шаговому двигателю, в приложение отправить сообщение и цифровое значение температуры.
В сценарии может быть несколько блоков, при необходимости из приложения есть возможность "выключать" часть из них.
Неактивные блоки сценария будут проигнорированы.
Для взаимодействия устройств между собой предусмотрены команды mqtt и http
**temp > 60**
mqtt 154348-134 digitSet_1_56
mqtt 154348-136 stepperSet _1_100_1
http 192.168.1.10 textSet_1_Перегрев
**end**
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 1.1 Объект "кнопка"
(эти строки мы пишем в "конфигурации устройства")
### a) кнопка управляющая выходом (пином). Пины нумеруются по системе нумирации gpio для esp контроллеров.
`button 1 13 кухня освещение 0 1`
**"button"** это объект создающий кнопку в приложении
**"1"** это номер этой кнопки (необходимый для ее аутентификации)
**"13"** это номер пина которым будет управлять данная кнопка
**"кухня"** это название кнопки в приложении
**"освещение"** это название вкладки в приложении на которой появится данная кнопка
**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1)
**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта
### б) виртуальная кнопка - кнопка реакцию на которую можно задать в сценариях:
`button 1 na запустить таймеры 0 1`
**"button"** это объект создающий кнопку в приложении
**"1"** это номер этой кнопки (необходимый для ее аутентификации)
**"na"** абривиатура not available означающая что эта кнопка виртуальная и что пин не установлен
**"запустить"** это название кнопки в приложении
**"таймеры"** это название вкладки в приложении на которой появится данная кнопка
**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1)
**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта
### в) кнопка включающая и выключающая все сценарии:
`button 1 scenario запустить таймеры 0 1`
**"button"** это объект создающий кнопку в приложении
**"1"** это номер этой кнопки (необходимый для ее аутентификации)
**"scenario"** слово означающее что эта кнопка для управления сценариями
**"запустить"** это название кнопки в приложении
**"таймеры"** это название вкладки в приложении на которой появится данная кнопка
**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1)
**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта
### г) кнопка включающая выключающая определенные блоки сценариев:
`button 1 line1,line3, Включить#отправку#push Оповещение 0 1`
**"button"** это объект создающий кнопку в приложении
**"1"** это номер этой кнопки (необходимый для ее аутентификации)
**"line1,line3,"** это блоки сценариев нумирация сверху вниз. Блоком считается выражение от начала до слова end
**"Включить#отправку#push"** это название кнопки в приложении
**"Оповещение"** это название вкладки в приложении на которой появится данная кнопка
**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1)
**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта
## 1.2 Команды управления объектом "кнопка"
(эти строки мы пишем в "сценариях")
### а) Команда включения выключения кнопки по ее номеру
`buttonSet 1 1`
**"buttonSet"** команда управления объектом button
**"1"** номер кнопки которой будем управлять
**"1"** состояние включено, 0 - выключено
### б) Команда изменения состояния кнопки на противоположное
`buttonChange 1`
**"buttonChange"** команда управления объектом button
**"1"** номер кнопки которой будем управлять
## 1.3 Вызов событий объектом "кнопока"
(эти строки мы пишем в "сценариях")
объект button может быть равен либо 0 либо 1
`button1 = 1`
`button2 = 0`
Пример использования:
`button1 = 1`
`buttonSet 2 1`
`buttonSet 3 0`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 2.1 Объект "физическая кнопка"
`switch 1 0 10`
**switch** это объект создающий физическую кнопку
**1** номер кнопки
**0** пин кнопки (при подключении необходим подтягивающий резистор)
**10** задержка для избавления от дребезга с мили секундах
## 2.2 Вызов событий объектом "физическая кнопка"
`switch1` может быть равна нулю или единицы, ноль - событие отбрасывания кнопки, единица - событие нажатия
`switch1 = 1`
`buttonChange 1`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 3.1 Объект "широтноимпульсная модуляция"
`pwm 1 12 яркость освещение 1023 1`
**"pwm"** это объект создающий управление шим в приложении в виде ползунка
**"1"** это номер этого объекта
**"12"** это номер пина на котором будет генерироваться шим заданной в приложении величены
**"Яркость"** это название кнопки в приложении
**"Оповещение"** это название вкладки в приложении на которой появится данная кнопка
**"1023"** это начальное значение шим сигнала и ползунка (изменяется от 0 до 1023)
**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта
## 3.2 Команда управления объектом "широтноимпульсная модуляция"
`pwmSet 1 500`
**"pwmSet"** команда управления объектом
**"1"** номер объекта, которым будем управлять
**"500"** значение которое установится после выполнения команды (от 0 до 1023)
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 4.1 Объект "окно ввода времени"
`inputTime time1 Во#сколько#включить? Таймеры 20-30-00 1`
**inputTime** это объект создающий окно ввода в приложении
**time1** переменная в которую будет записано время введенное в окно
**Во#сколько#включить?** это название окна в приложении
**Таймеры** это название вкладки в приложении
**20-30-00** начальное значение времени после загрузки устройства
**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
## 4.2 Управление объектом "окно ввода времени"
`timeSet 1 08-00-00`
**"timeSet"** команда управления объектом
**"1"** номер объекта, которым будем управлять в данном случае окном ввода с `time1`
**"08-00-00"** время которое хотим установить
В окно ввода можно вводить время в приложении но если необходимо изменить время автоматически
по какому нибудь событию то можно использовать команду выше - **timeSet**.
## 4.3 Вызов событий объектом "окно ввода времени"
`timenow = time1`
`buttonSet 1 1`
`end`
`timenow` всегда хранит в себе текущее время, и поэтому исходя из данного сценария кнопка номер 1 включится в то время которое будет введено в окно ввода `time1`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 5.1 Объект "окно ввода цифры"
`inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2`
**inputDigit** это объект создающий окно ввода в приложении
**digit1** переменная в которую будет записана цифра, введенная в окно
**Через#сколько#секунд#выключить?** это название окна в приложении
**Таймеры** это название вкладки в приложении
**5** цифра по умолчанию, после загрузки модуля
**2** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
## 5.2 Управление объектом "окно ввода цифры":
`digitSet 1 56`
**"digitSet"** команда управления объектом
**"1"** номер объекта, которым будем управлять в данном случае окном ввода с `digit1`
**"56"** цифра которую хотим установить
В окно ввода можно вводить цифры в приложении, но если необходимо изменить цифру автоматически
по какому нибудь событию, то можно использовать команду выше - **digitSet**.
## 5.3 Вызов событий объектом "окно ввода цифры"
`dallas > digit1`
`buttonSet 1 0`
`end`
`button1 = 1`
`timerStart 1 digit1 sec`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 6.1 Объект "dallas" (сенсор температуры ds18b20)
`dallas temp1 2 123456 Водонагреватель,#t°C Термостат any-data 1`
**dallas** это объект чтения датчика температуры
**2** пин датчика температуры
**Водонагреватель,#t°C** это название виджета в приложении
**Датчики** название вкладки в приложении
**any-data** или **progress-round** или **progress-line** три разных варианта виджета отображения
**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
## 6.2 Вызов событий объектом "dallas"
В сценариях dallas можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=):
`dallas > digit1`
`buttonSet 1 0`
`end`
Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=):
`dallas > 60`
`buttonSet 1 0`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 7.1 Объект "analog" (аналоговый вход контроллера)
`analog adc 0 Аналоговый#вход,#% Датчики progress-round 310 620 1 100 1`
**analog** это объект чтения аналогового входа
**adc** это переменная
**0** пин аналогового входа (для esp8266 всегда 0, для esp32 пока что не доделал читаться будет всегда пин 34)
**Аналоговый#вход,#%** это название виджета в приложении
**Датчики** название вкладки в приложении
**any-data** или **progress-round** или **progress-line** три разных варианта виджета отображения
**310** начальная величина читаемого диапазона
**620** конечная величина читаемого диапазона
**1** начальная величина выводимого диапазона
**100** конечная величина выводимого диапазона
**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
## 7.2 Вызов событий объектом "analog"
В сценариях analog можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=):
`analog > digit1`
`buttonSet 1 0`
`end`
Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=):
`analog > 50`
`buttonSet 1 0`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 8.1 Объект "level" (ультразвуковой дальномер JSN-SR04T, HC-SR04, HY-SRF05)
`level Вода#в#баке,#% Датчики any-data 125 20 1`
**level** это объект чтения датчика расстояния
**Вода#в#баке** это название виджета в приложении
**Датчики** название вкладки в приложении
**any-data** или **progress-round** или **progress-line** три разных варианта отображения виджета
**125** расстояние от датчика до дна бака в сантиметрах
**20** расстояние от датчика до поверхности воды, когда бак полный, в сантиметрах
**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
Подключать дальномер нужно:
| | trig | echo |
| :-: | :-: | :-: |
| wemos | D5 | D6 |
| esp | 14 | 12 |
## 8.2 Вызов событий объектом "level"
В сценариях level можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=):
`level > digit1`
`buttonSet 1 0`
`end`
Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=):
`level > 95`
`buttonSet 1 0`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 9.1 Объект "dht" (Сенсоры DHT11, DHT22, DHT33, DHT44, AM2302, RHT03)
dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 1
dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 2
dhtComfort Степень#комфорта: Датчики 3
dhtPerception Восприятие: Датчики 4
dhtDewpoint Точка#росы: Датчики 5
**dhtT** или **dhtH** температура или влажность
**DHT11** или **DHT22** чтение DHT11 или DHT22, DHT33, DHT44, AM2302, RHT03 соответственно
**2** пин датчика
**Температура#DHT,#t°C** это название виджета в приложении
**Датчики** название вкладки в приложении
**any-data** или **progress-round** или **progress-line** три разных варианта отображения виджета
**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
## 9.2 Вызов событий объектом "dhtT" или "dhtH"
В сценариях "dhtT" или "dhtH" можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=):
`dhtT > digit1`
`buttonSet 1 0`
`end`
`dhtH > digit1`
`buttonSet 1 0`
`end`
Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=):
`dhtT > 50`
`buttonSet 1 0`
`end`
`dhtH < 40`
`buttonSet 1 0`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 10.1 Объект "stepper" (Драйвер шагового двигателя A4988)
stepper 1 12 4
stepper 2 13 5
**stepper** объект создающий шаговый двигатель
**1** номер шаговика
**12** номер пина количества шагов
**4** номер пина направления
## 10.2 управление объектом "stepper"
`stepperSet 1 200 1`
**stepperSet** команда управления шаговым двигателем
**1** номер шагового двигателя (их может быть не более двух)
**200** количество шагов (обратное направление отрицательное значение параметра)
**1** интервал между шагами (мс)
`button1 = 1`
`stepperSet 1 200 1`
`end`
`button1 = 0`
`stepperSet 1 -200 1`
`end`
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 11.1 Объект "обратный таймер"
Прежде чем читать этот раздел запустите пресет №3 на устройстве.
Нажав на кнопку "Выберите во что вы хотите превратить esp"
Можно использовать цифры из окон ввода:
`timerStart 1 digit1 sec`
Можно писать цифры прям в объект:
`timerStart 1 10 sec`
Можно установить часы минуты или секунды:
`timerStart 1 10 sec`
`timerStart 1 10 min`
`timerStart 1 10 hours`
Используем это объект в сценариях вот так:
`button1 = 1`
`timerStart 1 digit1 sec`
`end`
Смысл в том что при нажатии на кнопку один запуститься обратный отчет, на величину digit1 секунд. Если напишем например:
`dallas < 60`
`timerStart 1 digit1 sec`
`end`
то такой же отчет запустится когда значение температуры вырастит больше 60 градусов. Таким образом обратный отчет можно запустить реакцией на любое событие. Итак теперь обратный отчет запущен, обратный таймер уменьшается, и нам надо назначить действие на тот момент когда он обнулится. Для этого я придумал выражение: `timer1 = 0`
Используем его и в общем получаем вот такой сценарий:
`button1 = 1`
`timerStart 1 digit1 sec`
`end`
`timer1 = 0`
`buttonSet 1 0`
`end`
Когда таймер закончит отсчёт, кнопка станет "неактивной". Используйте преет №3, как пример подобного сценария
Например:
`dallas < 60`
`buttonSet 1 0`
`buttonSet 2 0`
`pwmSet 1 1023`
`mqtt 2653450020 buttonChange_1`
`mqtt 2653450020 pinSet_13_1`
`http 192.168.1.32 pinSet_14_1`
`end`
Вот что может произойти на разных устройствах по одному событию повышения температуры...
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 12 Журнал (лог) данных
`logging analog 1 100 slow Аналоговый#вход Датчики 7`
**logging** объект для логирования
**analog** или **dhtT** или **dhtH** какой сенсор будем логировать, можно указать любой
**1** период между точками в минутах
**100** количество точек (старые точки будут удаляться по мере добавления новых)
**slow** или **fast** метод выгрузки графика в приложение, slow - выгружает график по одной точке (меньше расходуется оперативка, лучше использовать для esp8266), fast - выгрузка графика сразу (больше расход оперативки, подходит для esp32)
**Аналоговый#вход** название графика в приложении
**Датчики** название вкладки в приложении
**7** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
## 13 Взаимодействие устройств между собой
Устройства могут между собой обмениваться командами. Команды можно отправлять по http или по mqtt.
По событию на одном устройстве можно вызвать действие на другом. Например на esp01 стоит датчик температуры, реле стоит на esp02.
Настройки esp01:
`dhtT temp 2 dht11 Температура#DHT,#t°C Датчики any-data 1`
`temp < 40`
`http 192.168.10.25 buttonSet_1_1`
`end`
Настройки esp02:
`button 1 13 Включить#реле Реле 0 1`
И теперь когда температура датчика на esp01 станет меньше 40 градусов то на esp02 будет отправлена команда на включение кнопки: buttonSet_1_1
Если вы хотите отправить команду через mqtt то сценарий будет выглядеть следующим образом:
`temp < 40`
`mqtt 12343442-12413131 buttonSet_1_1`
`end`
где `12343442-12413131` id esp02 той на которую отправляем команду. Id можно взять в веб интерфейсе на странице конфигурация устройства. Или в списке устройств в сети.
Теперь рассмотрим вариант внешнего управления esp с помощью get запросов.
`http://192.168.88.239/cmd?command=buttonSet%201%201`
Разберем эту строку. Сама команда в ней выглядит вот так: buttonSet%201%201. `%20` заменяют пробел.
То есть что бы составить get запрос на изменение например pwm нужно:
Взять команду `pwmSet 1 500`
Заменить в ней пробелы на `%20` получится так: `pwmSet%201%20500`
И добавить ее в конец строки `http://192.168.88.239/cmd?command=` где указывается ip адрес устройства
В итоге получится http://192.168.88.239/cmd?command=pwmSet%201%20500

View File

@@ -1,85 +0,0 @@
# В этой инструкции будет описано как с esp отправлять email и push
# Часть 1. Привязать email и pushbullet к сайту pushingbox
### 1. Необходимо перейти на сайт: [pushingbox](https://www.pushingbox.com/)
### 2. Войти с помощью google
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_1.png)
### 3. Перейти в мои сервисы и добавить новый сервис
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_2.png)
### 4. Нас интересуют два сервиса email и pushbullet
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_4%2B.png)
### 5. Выбираем сначало сервис для отправки email. В окно `Name of your email configuration` - вводим слово "email". В окно `Email address` - вводим ваш email адрес. жмем submit
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_5.png)
manager_modules_firmware/blob/master/push_instruction/Screenshot_6.png)
### 6.1 Привязываем pushbullet. Переходим на сайт [pushbullet.com](https://www.pushbullet.com/)
### 6.2 Входим с гуглом или фейсбуком
### 6.3 Идем в настройки
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_7.png)
### 6.4 Создаем токен
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_8.png)
### 6.5 Идем опять в сервисы и теперь выбираем сервис pushbullet [pushingbox.com/services](https://www.pushingbox.com/services.php) нажимаем add service
### Берем токен, и вставляем его в окно Access token.
### Окно Device token (optional) оставляем пустым.
### В окно Name of your Pushbullet configuration пишем слово "push".
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_6.png)
### 7. Теперь наш email и pushbullet привязаны к pushingbox. Далее можно скачать приложение pushbullet на телефон и войти с гуглом или фейсбуком сответственно с пунктом 6.3 этой инструкции
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_9.png)
# Часть 2. Создание сценариев отправки email
### 8.1. Сценарий для отправки email. Заходим в My Scenarios:
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_10.png)
### 8.2 Пишем слово email (это имя сценария отправки email) жмем add:
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_12.png)
### 8.3 Нажимаем add an action
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_14.png)
### 8.4 Выбираем наш email который мы зарегестрировали ранее и нажимаем Add an action with this service
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_11.png)
### 8.5 Делаем все как на скриншоте и жмем submit
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_15.png)
### 8.6 Возвращаемся на мои сценарии
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_17.png)
### 8.7 Вставляем токен в веб интерфейс esp
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_18.png)
# Часть 3. Создание сценариев отправки push
### 9.1. Сценарий для отправки push. Заходим в My Scenarios:
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_10.png)
### 9.2 Пишем слово push (это имя сценария отправки email) жмем add:
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_19.png)
### 9.3 Нажимаем add an action
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_20.png)
### 9.4 Выбираем наш pushbullet который мы зарегестрировали ранее и нажимаем Add an action with this service
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_11.png)
### 9.5 Делаем все как на скриншоте и жмем submit
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_15.png)
### 9.6 Возвращаемся на мои сценарии
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_21.png)
### 9.7 Вставляем токен в веб интерфейс esp
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_18.png)
# Часть 4. Итог
При создании такой конфигурации как на картинке:
`button 1 na Отправить#push Push 0 1`
`button1 = 1`
`push внимание кнопка#нажата`
`end`
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_22.png)
Если мы введем токен для email то будут приходить email
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_17.png)
Если для push то будут приходить push в pushbullet
![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_21.png)
Способ описанный в данной инструкции более сложный в настройке но зато очень надежный.

View File

@@ -1,32 +0,0 @@
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
### 1. Скачать архив из [релизов](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/releases) или из закрепленного сообщения группы телеграм с последней версией прошивки
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
### 2. Для ESP8266 c 4 и больше мб памяти (все сделать как на скриншотах)
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_1.png)
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_2.png)
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
### 2. Для ESP8266 c 1 мб памяти (все сделать как на скриншотах)
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_1mb_1.png)
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_1mb_2.png)
***
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true)
### 2. Для ESP32 (все сделать как на скриншотах)
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp32_1.png)
![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp32_2.png)

View File

@@ -1,3 +0,0 @@
button 1 5 Включить#реле Реле 0 1
//это простая кнопка номер 1 управляющая пином 5 имеющая начальное состояние 0

View File

@@ -1,6 +0,0 @@
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 1
inputTime time2 Во#сколько#выключить? Таймеры 20-35-00 2
button 1 5 Кнопка#(по#таймеру) Таймеры 0 3
//время в приложение необходимо вводить в строгом формате: ЧЧ-ММ-СС
//можно создавать любое количество таймеров, копируя строку inputTime...

View File

@@ -1,4 +0,0 @@
button 1 5 Вкл#на#время Таймеры 0 1
inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2
//в сценариях можно поменять на sec, min или hours если нужны другие размерности времени

View File

@@ -1,3 +0,0 @@
button 1 na Включить#все Освещение 0 1
//при нажатии на эту кнопку пины номер 5 и 13 поведут себя как установленно в сценариях

View File

@@ -1,4 +0,0 @@
button 1 13 Включить#реле Реле 0 1
switch 1 0 10
//можно управлять реле на пине 13 кнопкой на пине 0 или кнопкой в приложении

View File

@@ -1,6 +0,0 @@
button 1 5 Включить#все Реле 0 1
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
//того esp, кнопка на этом девайсе будет выключать другие устройства по воздуху

View File

@@ -1,6 +0,0 @@
switch 1 0 10
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
//того esp, к данному модулю нужно подключить кнопку к пину 0 и тогда
//один девайс будет управлять другим по воздуху

View File

@@ -1,6 +0,0 @@
pwm 1 3 Яркость#коредор: Реле 1023 1
pwm 2 4 Яркость#ванная: Реле 510 2
//в приложении появятся ползунки, соответствующее значение pwm
//будет установленно на пинах 3 и 4
//1023 и 510 это начальные значения после загрузки модуля

View File

@@ -1,7 +0,0 @@
dhtT t 2 dht11 Температура#DHT,#t°C Датчики anydata 1
dhtH h 2 dht11 Влажность#DHT,#t°C Датчики anydata 2
dhtComfort Степень#комфорта: Датчики 3
dhtPerception Восприятие: Датчики 4
dhtDewpoint Точка#росы: Датчики 5
logging t 1 50 Температура Датчики 6
logging h 1 50 Влажность Датчики 7

View File

@@ -1,7 +0,0 @@
dhtT t 2 dht22 Температура#DHT,#t°C Датчики anydata 1
dhtH h 2 dht22 Влажность#DHT,#t°C Датчики anydata 2
dhtComfort Степень#комфорта: Датчики 3
dhtPerception Восприятие: Датчики 4
dhtDewpoint Точка#росы: Датчики 5
logging t 1 50 Температура Датчики 6
logging h 1 50 Влажность Датчики 7

View File

@@ -1,8 +0,0 @@
analog adc 0 Аналоговый#вход,#% Датчики progress-round 310 620 1 100 1
logging adc 5 100 Аналоговый#вход Датчики 2
//если датчик углекислого газа выдает напряжение от 1 вольта до 2 вольт, то значит
//значение чтения аналогового входа будут примерно равным
//при 1 вольте - 310, а при 2 вольтах - 620 (считаем по пропорции)
//данная строка переведет диапазон 310-620 в диапазон 1-100 и отобразит в приложении
//варианты отображения: anydata, progress-round, progress-line, fillgauge

View File

@@ -1,6 +0,0 @@
bmp280T temp1 0x76 Температура#bmp280 Датчики anydata 1
bmp280P press1 0x76 Давление#bmp280 Датчики anydata 2
logging temp1 1 100 Температура Датчики 3
logging press1 1 100 Давление Датчики 4
//Чтение и логгирование датчика bmp280. Датчик подключается к шине i2c (esp8266 - gpio 5, 4)

View File

@@ -1,9 +0,0 @@
bme280T temp1 0x76 Температура#bmp280 Датчики anydata 1
bme280P pres1 0x76 Давление#bmp280 Датчики anydata 2
bme280H hum1 0x76 Влажность#bmp280 Датчики anydata 3
bme280A altit1 0x76 Высота#bmp280 Датчики anydata 4
logging temp1 1 100 Температура Датчики 5
logging press1 1 100 Давление Датчики 6
logging hum1 1 100 Влажность Датчики 7
//Чтение и логгирование датчика bme280. Датчик подключается к шине i2c (esp8266 - gpio 5, 4)

View File

@@ -1,7 +0,0 @@
dallas temp1 2 1 Температура Датчики anydata 1
dallas temp2 2 2 Температура Датчики anydata 2
logging temp1 1 100 Температура Датчики 3
logging temp2 1 100 Температура Датчики 4
//2 - номер пина датчика
//варианты отображения: anydata, progress-round, progress-line, fillgauge

View File

@@ -1,12 +0,0 @@
dallas 2 Водонагреватель,#t°C Термостат anydata 1
logging dallas 5 100 Температура Термостат 2
inputDigit digit1 При#скольки#выключить? Термостат 40 3
inputDigit digit2 При#скольки#включить? Термостат 20 4
button 1 5 Нагреватель Термостат 0 5
button 2 line1,line2, Автоматический#режим Термостат 1 6
//2 - номер пина датчика
//5 - номер пина реле
//это термостат который будет держать температуру между двумя
//установленными в приложении значениями, так же можно выключить
//автоматический режим, и тогда нагреватель будет управляться в ручную

View File

@@ -1,12 +0,0 @@
levelPr p 14 12 Уровень#в#баке,#% Датчики fillgauge 125 25 1
ultrasonicCm cm 14 12 Дистанция,#см Датчики anydata 2
inputDigit digit1 При#скольки#выключить? Датчики 95 3
inputDigit digit2 При#скольки#включить? Датчики 10 4
button 1 5 Насос Датчики 0 5
logging p 1 100 Вода#в#баке Датчики 6
//125 - это расстояние от датчика до дна бака в сантиметрах
//25 - это расстояние от датчика до поверхности воды когда бак полный в сантиметрах
//distancePr - эта строка выводит процент заполнения бака
//distanceCm - эта строка выводит расстояние в сантиметрах
//варианты отображения: anydata, progress-round, progress-line, fillgauge

View File

@@ -1,11 +0,0 @@
button 1 5 Прихожая Освещение 0 1
inputDigit digit1 Задержка#выключения Освещение 30 2
switch 1 0 10
//0 - номер пина датчика движения
//5 - номер пина реле
//при срабатывании датчика движения включится реле и обратный таймер на 30 сек
//если движение не будет обнаружено повтороно в течении 30 секунд - свет выключится
//если движение повторится в течении 30 секунд то таймер продлится опять на 30 сек
//свет выключится только в том случае если в комнате все замрет на 30 сек
//задержку выключения можно будет настраивать в приложении

View File

@@ -1,12 +0,0 @@
switch 1 0 20
text 1 Вход: Охрана 1
textSet 1 не#обнаружено-time
button 1 na Сбросить Охрана 0 2
button 2 line3, Включить#push Охрана 1 3
//0 - номер пина датчика
//при срабатывании датчика движения устройство пошлет пуш и в приложении будет
//написано в текстовом поле, что движение было обнаружено
//так же будет зафиксирован момент времени срабатывания датчика
//в приложении можно отключать отправку пуш сообщений на тот случай если дома хозяин
//перевести датчик снова в режим ожидания движения можно нажав кнопку сброса в приложении

View File

@@ -1,17 +0,0 @@
stepper 1 12 4
stepper 2 13 5
button 1 na Открыть#штору#1 Шторы 0 1
button 2 na Открыть#штору#2 Шторы 0 2
//для подключения необходим драйвер шагового двигателя A4988
//stepper 1 12 4 шаговый двигатель с параметрами: 1 - номер шагового двигателя,
//12 - номер пина количества шагов, 4 - номер пина направления
//stepper 2 13 5 шаговый двигатель с параметрами: 2 - номер шагового двигателя,
//13 - номер пина количества шагов, 5 - номер пина направления
//stepperSet 1 200 5 - прокрутить шаговик номер 1 на 200 шагов по часовой стрелке
//с задержкой между шагами 5 милисекунд (чем меньше задержка тем больше скорость)
//если поставить -200 то будет вращаться против часовой стрелки
//можно подключить не более двух шаговиков

View File

@@ -1,17 +0,0 @@
servo 1 12 50 Мой#сервопривод Сервоприводы 0 100 0 180 1
servo 2 13 50 Мой#сервопривод Сервоприводы 0 100 0 180 2
button 1 na Открыть1 Сервоприводы 0 3
button 2 na Открыть2 Сервоприводы 0 4
//Можно создавать не более двух сервоприводов на одном устройстве.
//1 - номер привода
//12 - номер пина
//50 - начальное значение в процентах
//0 - 100 диапазон ползунка
//0 - 180 диапазон угла
//Представим ситуацию когда есть некая заслонка и при угле в 30 градусов она закрыта,
//а при угле в 90 градусов открыта. В этом случае необходимо написать
//0 100 30 90 и тогда поставив ползунок в 0 % серва встанет в положение 30 градусов,
//а если поставить ползунок в 100 % серва встанет в положение 90 градусов.

View File

@@ -1,7 +0,0 @@
serialBegin 9600 12 13
button 1 na Управляется#из#arduino Serial 0 1
button 2 na Отправить#в#arduino Serial 0 2
text 1 Текст#из#arduino Serial 3
//12 13 это пины uart к которым вы можете подключить arduino. Скетч для arduino выложен в группу.
//команда serialWrite ard-on отправит в arduino текст ard-on

View File

@@ -1,12 +0,0 @@
button 1 na Включить#все Реле 0 1
button 2 13 Прихожая Реле 0 2
button 3 14 Кухня Реле 0 3
pwm 1 3 Яркость#коредор: Реле 1023 4
pwm 2 4 Яркость#ванная: Реле 510 5
analog adc 0 Аналоговый#вход Датчики fillgauge 1 1023 1 1023 6
logging adc 1 100 Аналоговый#вход Датчики 7
//Это демо конфигурация. В ней показано как связать кнопки c помощью сценариев
//Кнопка номер 1 связана с кнопкой 2, 3 и с pwm 2
//Так же продемонстрированна система логгирования данных строкой logging
//1 - это интервал между точками в минутах, 100 это количество точек

View File

@@ -1 +0,0 @@

View File

@@ -1,6 +0,0 @@
timenow = time1
buttonSet 1 1
end
timenow = time2
buttonSet 1 0
end

View File

@@ -1,6 +0,0 @@
button1 = 1
timerStart 1 digit1 sec
end
timer1 = 0
buttonSet 1 0
end

View File

@@ -1,8 +0,0 @@
button1 = 1
pinSet 5 1
pinSet 13 0
end
button1 = 0
pinSet 5 0
pinSet 13 1
end

View File

@@ -1,3 +0,0 @@
switch1 = 1
buttonChange 1
end

View File

@@ -1,8 +0,0 @@
button1 = 1
mqtt 3233662-1589485 buttonSet_1_1
mqtt 2233662-1589486 buttonSet_1_1
end
button1 = 0
mqtt 3233662-1589485 buttonSet_1_0
mqtt 2233662-1589486 buttonSet_1_0
end

View File

@@ -1,4 +0,0 @@
switch1 = 1
mqtt 3233662-1589485 buttonChange_1
mqtt 2233662-1589486 buttonChange_1
end

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1 +0,0 @@

View File

@@ -1,6 +0,0 @@
dallas > digit1
buttonSet 1 0
end
dallas < digit2
buttonSet 1 1
end

View File

@@ -1,6 +0,0 @@
p > digit1
buttonSet 1 0
end
p < digit2
buttonSet 1 1
end

View File

@@ -1,7 +0,0 @@
switch1 = 1
timerStart 1 digit1 sec
buttonSet 1 1
end
timer1 = 0
buttonSet 1 0
end

View File

@@ -1,10 +0,0 @@
switch1 = 1
textSet 1 обнаружено#движение-time
end
button1 = 1
textSet 1 не#обнаружено-time
buttonSet 1 0
end
switch1 = 1
push Внимание обнаружено#движение!
end

View File

@@ -1,12 +0,0 @@
button1 = 1
stepperSet 1 200 1
end
button1 = 0
stepperSet 1 -200 1
end
button2 = 1
stepperSet 2 200 1
end
button2 = 0
stepperSet 2 -200 1
end

View File

@@ -1,12 +0,0 @@
button1 = 1
servoSet 1 100
end
button1 = 0
servoSet 1 0
end
button2 = 1
servoSet 2 100
end
button2 = 0
servoSet 2 0
end

View File

@@ -1,6 +0,0 @@
button2 = 1
serialWrite ard-11-1
end
button2 = 0
serialWrite ard-11-0
end

View File

@@ -1,13 +0,0 @@
button1 = 1
buttonSet 2 1
buttonSet 3 1
pwmSet 2 1024
end
button1 = 0
buttonSet 2 0
buttonSet 3 0
pwmSet 2 0
end
adc > 50
buttonSet 2 1
end

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

View File

@@ -1,56 +0,0 @@
#pragma once
#include <Arduino.h>
class BusScanner {
public:
BusScanner(const char* tag, String& out, size_t tries) : _found{0},
_tries{tries},
_out{&out} {
_tag = new char(strlen(tag) + 1);
strcpy(_tag, tag);
}
void scan() {
init();
bool res;
do {
res = syncScan();
} while (!res && --_tries);
if (!_found) {
addResult("не найдено");
}
}
const char* tag() {
return _tag;
}
protected:
virtual void init(){};
virtual boolean syncScan() = 0;
protected:
void addResult(const String& str) {
_out->concat(str);
}
void addResult(uint8_t addr, boolean last = true) {
_found++;
String str = "0x";
if (addr < 16) {
str += "0";
}
str += String(addr, HEX);
str += !last ? ", " : ", ";
addResult(str);
};
private:
char* _tag;
size_t _found;
size_t _tries;
String* _out;
};

View File

@@ -1,18 +0,0 @@
#pragma once
#include "Bus/BusScanner.h"
#include "Bus/I2CScanner.h"
#include "Consts.h"
#include "Utils/JsonUtils.h"
class BusScannerFactory {
public:
static BusScanner* get(String& config, BusScanner_t type, String& str) {
switch (type) {
case BS_I2C:
return new I2CScanner(str);
default:
return nullptr;
}
}
};

View File

@@ -1,12 +0,0 @@
#pragma once
#include "Bus/BusScanner.h"
class I2CScanner : public BusScanner {
public:
I2CScanner(String& out);
protected:
virtual void init() override;
virtual boolean syncScan() override;
};

View File

@@ -1,26 +0,0 @@
#pragma once
#include <Arduino.h>
#include <stdint.h>
#include <functional>
// Декларируем тип - сигнатуру метода , который мы готовы принять в данном случае это
// должен быть метод без результата и без параметров.
// Новый тип мы называем AsynсActionCb - хотя можешь назвать вообще как нравиться а что значит callBack
typedef std::function<void()> AsyncActionCb; //метод без результата и параметров
typedef std::function<bool(const String)> AsyncParamActionCb; //метод без результата и параметров
class CallBackTest {
private:
long count;
AsyncActionCb _cb;
AsyncParamActionCb _pcb;
public:
CallBackTest();
void loop();
void setCallback(AsyncActionCb cb);
void setCallback(AsyncParamActionCb pcb);
};
//extern CallBackTest* CB;

Some files were not shown because too many files have changed in this diff Show More