mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
some fix
This commit is contained in:
2
data/.exclude.files
Normal file
2
data/.exclude.files
Normal file
@@ -0,0 +1,2 @@
|
||||
/*.js.gz
|
||||
/.exclude.files
|
||||
BIN
data/ace.js.gz
Normal file
BIN
data/ace.js.gz
Normal file
Binary file not shown.
7
data/configs/analog.config.txt
Normal file
7
data/configs/analog.config.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
analog 0 Аналоговый#вход,#% Датчики progress-round 310 620 1 100 1
|
||||
|
||||
//если датчик углекислого газа выдает напряжение от 1 вольта до 2 вольт, то значит
|
||||
//значение чтения аналогового входа будут примерно равным
|
||||
//при 1 вольте - 310, а при 2 вольтах - 620 (считаем по пропорции)
|
||||
//данная строка переведет диапазон 310-620 в диапазон 1-100 и отобразит в приложении
|
||||
//варианты отображения: any-data, progress-round, progress-line
|
||||
1
data/configs/analog.scenario.txt
Normal file
1
data/configs/analog.scenario.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
dallas 2 Водонагреватель,#t°C Датчики any-data 1
|
||||
|
||||
//2 - номер пина датчика
|
||||
//варианты отображения: any-data, progress-round, progress-line
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -2,4 +2,7 @@ dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 1
|
||||
dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 2
|
||||
dhtComfort Степень#комфорта: Датчики 3
|
||||
dhtPerception Восприятие: Датчики 4
|
||||
dhtDewpoint Точка#росы: Датчики 5
|
||||
dhtDewpoint Точка#росы: Датчики 5
|
||||
|
||||
//2 - номер пина датчика
|
||||
//варианты отображения: any-data, progress-round, progress-line
|
||||
@@ -2,4 +2,7 @@ dhtT DHT22 2 Температура#DHT,#t°C Датчики any-data 1
|
||||
dhtH DHT22 2 Влажность#DHT,#% Датчики any-data 2
|
||||
dhtComfort Степень#комфорта: Датчики 3
|
||||
dhtPerception Восприятие: Датчики 4
|
||||
dhtDewpoint Точка#росы: Датчики 5
|
||||
dhtDewpoint Точка#росы: Датчики 5
|
||||
|
||||
//2 - номер пина датчика
|
||||
//варианты отображения: any-data, progress-round, progress-line
|
||||
@@ -4,27 +4,21 @@ button 3 14 Кухня Реле 0 3
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 4
|
||||
pwm 2 4 Яркость#ванная: Реле 510 5
|
||||
//---------------------------------------------------------------------
|
||||
//analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
|
||||
analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
|
||||
inputDigit digit1 При#скольки#включить? Датчики 10 7
|
||||
inputDigit digit2 При#скольки#выключить? Датчики 0 8
|
||||
button 4 na Нагреватель Датчики 0 9
|
||||
//dallas 2 Водонагреватель,#t°C Датчики any-data 10
|
||||
//dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 11
|
||||
//dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 12
|
||||
//dhtComfort Степень#комфорта: Датчики 12
|
||||
//dhtPerception Восприятие: Датчики 13
|
||||
//dhtDewpoint Точка#росы: Датчики 14
|
||||
//level Вода#в#баке,#% Датчики any-data 125 20 15
|
||||
//---------------------------------------------------------------------
|
||||
button 5 na Вкл#обратный#таймер Таймеры 0 16
|
||||
inputDigit digit3 Через#сколько#секунд#включить? Таймеры 5 17
|
||||
button 6 na Включится#по#таймеру Таймеры 0 18
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20.30 19
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 19
|
||||
button 7 5 Включится#по#таймеру Таймеры 0 20
|
||||
//---------------------------------------------------------------------
|
||||
switch 1 0 20
|
||||
textSet 1 неопределено
|
||||
text 1 Квартира Двери 22
|
||||
text 1 Вход: Охрана 20
|
||||
textSet 1 не#обнаружено-time
|
||||
button 8 na Сбросить Охрана 0 21
|
||||
//---------------------------------------------------------------------
|
||||
button 8 scenario Вкл#выкл#все#сценарии Сценарии 1 23
|
||||
button 9 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
|
||||
button 9 scenario Вкл#выкл#все#сценарии Сценарии 1 23
|
||||
button 10 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
|
||||
@@ -24,9 +24,10 @@ timenow = time1
|
||||
buttonSet 7 1
|
||||
end
|
||||
switch1 = 1
|
||||
textSet 1 закрыто-time
|
||||
push закрыто вход
|
||||
textSet 1 обнаружено#движение-time
|
||||
push Внимание обнаружено#движение!
|
||||
end
|
||||
switch1 = 0
|
||||
textSet 1 открыто-time
|
||||
button8 = 1
|
||||
textSet 1 не#обнаружено-time
|
||||
buttonSet 8 0
|
||||
end
|
||||
10
data/configs/level.config.txt
Normal file
10
data/configs/level.config.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
level Вода#в#баке,#% Датчики any-data 125 20 1
|
||||
inputDigit digit1 При#скольки#выключить? Датчики 95 2
|
||||
inputDigit digit2 При#скольки#включить? Датчики 10 3
|
||||
button 1 5 Насос Датчики 0 4
|
||||
button 2 line1,line2, Автоматический#режим Датчики 1 5
|
||||
|
||||
//125 - это расстояние от датчика до дна бака в сантиметрах
|
||||
//20 - это расстояние от датчика до поверхности воды когда бак полный в сантиметрах
|
||||
//вывод данных будет в процентах заполнения бака
|
||||
//варианты отображения: any-data, progress-round, progress-line
|
||||
6
data/configs/level.scenario.txt
Normal file
6
data/configs/level.scenario.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
level > digit1
|
||||
buttonSet 1 0
|
||||
end
|
||||
level < digit2
|
||||
buttonSet 1 1
|
||||
end
|
||||
11
data/configs/moution_r.config.txt
Normal file
11
data/configs/moution_r.config.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
button 1 5 Прихожая Освещение 0 1
|
||||
inputDigit digit1 Задержка#выключения Освещение 30 2
|
||||
switch 1 0 10
|
||||
|
||||
//0 - номер пина датчика движения
|
||||
//5 - номер пина реле
|
||||
//при срабатывании датчика движения включится реле и обратный таймер на 30 сек
|
||||
//если движение не будет обнаружено повтороно в течении 30 секунд - свет выключится
|
||||
//если движение повторится в течении 30 секунд то таймер продлится опять на 30 сек
|
||||
//свет выключится только в том случае если в комнате все замрет на 30 сек
|
||||
//задержку выключения можно будет настраивать в приложении
|
||||
7
data/configs/moution_r.scenario.txt
Normal file
7
data/configs/moution_r.scenario.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
switch1 = 1
|
||||
timerStart 1 digit1 sec
|
||||
buttonSet 1 1
|
||||
end
|
||||
timer1 = 0
|
||||
buttonSet 1 0
|
||||
end
|
||||
10
data/configs/moution_s.config.txt
Normal file
10
data/configs/moution_s.config.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
switch 1 0 20
|
||||
text 1 Вход: Охрана 1
|
||||
textSet 1 не#обнаружено-time
|
||||
button 1 na Сбросить Охрана 0 2
|
||||
|
||||
//0 - номер пина датчика
|
||||
//при срабатывании датчика движения устройство пошлет пуш и в приложении будет
|
||||
//написано в текстовом поле, что движение было обнаружено, так же будет зафиксирован
|
||||
//момент времени срабатывания датчика
|
||||
//перевести датчик снова в режим ожидания движения можно нажав кнопку сброса в приложении
|
||||
8
data/configs/moution_s.scenario.txt
Normal file
8
data/configs/moution_s.scenario.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
switch1 = 1
|
||||
textSet 1 обнаружено#движение-time
|
||||
push Внимание обнаружено#движение!
|
||||
end
|
||||
button1 = 1
|
||||
textSet 1 не#обнаружено-time
|
||||
buttonSet 1 0
|
||||
end
|
||||
6
data/configs/pwm.config.txt
Normal file
6
data/configs/pwm.config.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 1
|
||||
pwm 2 4 Яркость#ванная: Реле 510 2
|
||||
|
||||
//в приложении появятся ползунки, соответствующее значение pwm
|
||||
//будет установленно на пинах 3 и 4
|
||||
//1023 и 510 это начальные значения после загрузки модуля
|
||||
1
data/configs/pwm.scenario.txt
Normal file
1
data/configs/pwm.scenario.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
button 1 5 Включить#реле Реле 0 1
|
||||
button 1 5 Включить#реле Реле 0 1
|
||||
|
||||
//это простая кнопка номер 1 управляющая пином 5 имеющая начальное состояние 0
|
||||
@@ -1 +1,6 @@
|
||||
button 1 5 Включить#все Реле 0 1
|
||||
button 1 5 Включить#все Реле 0 1
|
||||
|
||||
|
||||
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
|
||||
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
|
||||
//того esp, кнопка на этом девайсе будет выключать другие устройства по воздуху
|
||||
@@ -1,2 +1,4 @@
|
||||
button 1 5 Вкл#на#время Таймеры 0 1
|
||||
inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2
|
||||
inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2
|
||||
|
||||
//в сценариях можно поменять на sec, min или hours если нужны другие размерности времени
|
||||
@@ -1 +1,3 @@
|
||||
switch 1 0 10
|
||||
switch 1 0 10
|
||||
|
||||
//физическая кнопка номер 1 подключенная к пину 0, задержка от дребезга 10 мс
|
||||
@@ -1 +1,3 @@
|
||||
button 1 na Включить#все Освещение 0 1
|
||||
button 1 na Включить#все Освещение 0 1
|
||||
|
||||
//при нажатии на эту кнопку пины номер 5 и 13 поведут себя как установленно в сценариях
|
||||
@@ -1 +1,6 @@
|
||||
switch 1 0 10
|
||||
switch 1 0 10
|
||||
|
||||
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
|
||||
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
|
||||
//того esp, к данному модулю нужно подключить кнопку к пину 0 и тогда
|
||||
//один девайс будет управлять другим по воздуху
|
||||
@@ -1,2 +1,4 @@
|
||||
button 1 13 Включить#реле Реле 0 1
|
||||
switch 1 0 10
|
||||
switch 1 0 10
|
||||
|
||||
//можно управлять реле на пине 13 кнопкой на пине 0 или кнопкой в приложении
|
||||
@@ -1,3 +1,6 @@
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20.30 1
|
||||
inputTime time2 Во#сколько#выключить? Таймеры 20.35 2
|
||||
button 1 5 Включится#по#таймеру Таймеры 0 3
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 1
|
||||
inputTime time2 Во#сколько#выключить? Таймеры 20-35-00 2
|
||||
button 1 5 Кнопка#(по#таймеру) Таймеры 0 3
|
||||
|
||||
//время в приложение необходимо вводить в строгом формате: ЧЧ-ММ-СС
|
||||
//можно создавать любое количество таймеров, копируя строку inputTime...
|
||||
@@ -1,4 +1,12 @@
|
||||
dallas 2 Водонагреватель,#t°C Термостат any-data 1
|
||||
inputDigit digit1 При#скольки#включить? Термостат 40 2
|
||||
inputDigit digit2 При#скольки#выключить? Термостат 20 3
|
||||
button 1 5 Нагреватель Термостат 0 4
|
||||
inputDigit digit1 При#скольки#выключить? Термостат 40 2
|
||||
inputDigit digit2 При#скольки#включить? Термостат 20 3
|
||||
button 1 5 Нагреватель Термостат 0 4
|
||||
button 2 line1,line2, Автоматический#режим Термостат 1 5
|
||||
|
||||
|
||||
//2 - номер пина датчика
|
||||
//5 - номер пина реле
|
||||
//это термостат который будет держать температуру между двумя
|
||||
//установленными в приложении значениями, так же можно выключить
|
||||
//автоматический режим, и тогда нагреватель будет управляться в ручную
|
||||
@@ -1,6 +1,6 @@
|
||||
dallas > digit1
|
||||
buttonSet 1 1
|
||||
buttonSet 1 0
|
||||
end
|
||||
dallas < digit2
|
||||
buttonSet 1 0
|
||||
buttonSet 1 1
|
||||
end
|
||||
@@ -4,6 +4,7 @@
|
||||
"/config.live.json",
|
||||
"/config.setup.json",
|
||||
"/config.option.json"
|
||||
|
||||
],
|
||||
"class":"col-sm-offset-1 col-sm-10",
|
||||
"content": [
|
||||
@@ -29,115 +30,30 @@
|
||||
},
|
||||
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Чтобы превратить ESP во что либо из списка, нажмите на соответствующию кнопку:"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Раздел 1. Управление нагрузкой"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. локального реле",
|
||||
"action": "/relay",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. локального реле в определенное время",
|
||||
"action": "/relay_timer",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. локального реле на определенный период времени",
|
||||
"action": "/relay_countdown",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. нескольких локальных реле кнопкой в приложении",
|
||||
"action": "/relay_several",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. локального реле физической кнопкой (кнопка так же дублируется в приложении)",
|
||||
"action": "/relay_switch",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
|
||||
"action": "/relay_button_remote",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
|
||||
"action": "/relay_switch_remote",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Раздел 2. Сенсоры"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сенсор DHT11",
|
||||
"action": "/dht11",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сенсор DHT22, DHT33, DHT44, AM2302, RHT03",
|
||||
"action": "/dht22",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сенсор DS18B20",
|
||||
"action": "/dallas",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Термостат на DS18B20",
|
||||
"action": "/termostat",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Датчик движения включающий свет",
|
||||
"action": "/moution-relay",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Охранный датчик движения",
|
||||
"action": "/moution-security",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Выключатель",
|
||||
"action": "/switch",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сбросить сценарии и конфигурации по умолчанию",
|
||||
"action": "/default",
|
||||
"class": "btn btn-block btn-danger"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "hr"
|
||||
"type":"dropdown",
|
||||
"name":"help-url",
|
||||
"class":"btn btn-warning btn-lg",
|
||||
"style":"display:inline",
|
||||
"title": {
|
||||
"#":"Выбирите то, во что Вы хотите превратить ESP <span class=\"caret\"></span>",
|
||||
"/relay":"Вкл. выкл. локального реле",
|
||||
"/relay_timer":"Вкл. выкл. локального реле в определенное время",
|
||||
"/relay_countdown":"Вкл. выкл. локального реле на определенный период времени",
|
||||
"/relay_several":"Вкл. выкл. нескольких локальных реле кнопкой в приложении",
|
||||
"/relay_switch":"Вкл. выкл. локального реле физической кнопкой (кнопка так же дублируется в приложении)",
|
||||
"/relay_button_remote":"Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
|
||||
"/relay_switch_remote":"Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
|
||||
"/pwm":"Широтно импульсная модуляция",
|
||||
"/dht11":"Сенсор DHT11",
|
||||
"/dht22":"Сенсор DHT22, DHT33, DHT44, AM2302, RHT03",
|
||||
"/analog":"Аналоговый сенсор",
|
||||
"/dallas":"Сенсор DS18B20",
|
||||
"/termostat":"Термостат на DS18B20 с переключением в ручной режим",
|
||||
"/level":"Контроль уровня в баке на сенсорах: JSN-SR04T, HC-SR04, HY-SRF05 (управление насосом)",
|
||||
"/moution_relay":"Датчик движения включающий свет",
|
||||
"/moution_security":"Охранный датчик движения",
|
||||
"/default":"Настройки по умолчанию"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
@@ -180,71 +96,6 @@
|
||||
"action": "/scenario?status=1",
|
||||
"class":"btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Данные модулей"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль уровня воды (level)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Расстояние от датчика до воды: {{level_in}} см"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": " Заполнение бака: {{level}} %"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль аналогового входа (analog)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Прочитанное значение: {{analog_in}}"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Преобразованное значение: {{analog}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль температурного датчика (dallas)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Текущее значение: {{dallas}} °C"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль pH сенсора от df robot (ph)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Текущее значение: {{ph}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
|
||||
572
data/edit.htm
Normal file
572
data/edit.htm
Normal file
@@ -0,0 +1,572 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ESP Editor</title>
|
||||
<style type="text/css" media="screen">
|
||||
.contextMenu{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}
|
||||
.contextMenu ul{list-style:none;top:0;left:0;margin:0;padding:0}
|
||||
.contextMenu li{position:relative;min-width:60px;cursor:pointer}
|
||||
.contextMenu span{color:#444;display:inline-block;padding:6px}
|
||||
.contextMenu li:hover{background:#444}
|
||||
.contextMenu li:hover span{color:#EEE}
|
||||
.css-treeview ul,.css-treeview li{padding:0;margin:0;list-style:none}
|
||||
.css-treeview input{position:absolute;opacity:0}
|
||||
.css-treeview{font:normal 11px Verdana,Arial,Sans-serif;-moz-user-select:none;-webkit-user-select:none;user-select:none}
|
||||
.css-treeview span{color:#00f;cursor:pointer}
|
||||
.css-treeview span:hover{text-decoration:underline}
|
||||
.css-treeview input+label+ul{margin:0 0 0 22px}
|
||||
.css-treeview input ~ ul{display:none}
|
||||
.css-treeview label,.css-treeview label::before{cursor:pointer}
|
||||
.css-treeview input:disabled+label{cursor:default;opacity:.6}
|
||||
.css-treeview input:checked:not(:disabled) ~ ul{display:block}
|
||||
.css-treeview label,.css-treeview label::before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAACgCAYAAAAFOewUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAApxJREFUeNrslM1u00AQgGdthyalFFOK+ClIIKQKyqUVQvTEE3DmAhLwAhU8QZoH4A2Q2gMSFace4MCtJ8SPBFwAkRuiHKpA6sRN/Lu7zG5i14kctaUqRGhGXnu9O/Pt7MzsMiklvF+9t2kWTDvyIrAsA0aKRRi1T0C/hJ4LUbt5/8rNpWVlp8RSr9J40b48fxFaTQ9+ft8EZ6MJYb0Ok+dnYGpmPgXwKIAvLx8vYXc5GdMAQJgQEkpjRTh36TS2U+DWW/D17WuYgm8pwJyY1npZsZKOxImOV1I/h4+O6vEg5GCZBpgmA6hX8wHKUHDRBXQYicQ4rlc3Tf0VMs8DHBS864F2YFspjgUYjKX/Az3gsdQd2eeBHwmdGWXHcgBGSkZXOXohcEXebRoQcAgjqediNY+AVyu3Z3sAKqfKoGMsewBeEIOPgQxxPJIjcGH6qtL/0AdADzKGnuuD+2tLK7Q8DhHHbOBW+KEzcHLuYc82MkEUekLiwuvVH+guQBQzOG4XdAb8EOcRcqQvDkY2iCLuxECJ43JobMXoutqGgDa2T7UqLKwt9KRyuxKVByqVXXqIoCCUCAqhUOioTWC7G4TQEOD0APy2/7G2Xpu1J4+lxeQ4TXBbITDpoVelRN/BVFbwu5oMMJUBhoXy5tmdRcMwymP2OLQaLjx9/vnBo6V3K6izATmSnMa0Dq7ferIohJhr1p01zrlz49rZF4OMs8JkX23vVQzYp+wbYGV/KpXKjvspl8tsIKCrMNAYFxj2GKS5ZWxg4ewKsJfaGMIY5KXqPz8LBBj6+yDvVP79+yDp/9F9oIx3OisHWwe7Oal0HxCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgwD8E/BZgAP0qhKj3rXO7AAAAAElFTkSuQmCC") no-repeat}
|
||||
.css-treeview label,.css-treeview span,.css-treeview label::before{display:inline-block;height:16px;line-height:16px;vertical-align:middle}
|
||||
.css-treeview label{background-position:18px 0}
|
||||
.css-treeview label::before{content:"";width:16px;margin:0 22px 0 0;vertical-align:middle;background-position:0 -32px}
|
||||
.css-treeview input:checked+label::before{background-position:0 -16px}
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0){.css-treeview{-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:200px;padding:8px}
|
||||
#editor,#preview{position:absolute;top:28px;right:0;bottom:0;left:200px}
|
||||
#preview{background-color:#EEE;padding:5px}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
var urlXXX = 'http://192.168.211.181';//bolt
|
||||
if (window.location.search.substring(1).split("=")[1]) {
|
||||
urlXXX = 'http://'+window.location.search.substring(1).split("=")[1];
|
||||
} else {
|
||||
urlXXX = 'http://'+window.location.hostname;
|
||||
}
|
||||
|
||||
function createFileUploader(element, tree, editor){
|
||||
var xmlHttp;
|
||||
var input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.multiple = false;
|
||||
input.name = "data";
|
||||
document.getElementById(element).appendChild(input);
|
||||
var path = document.createElement("input");
|
||||
path.id = "upload-path";
|
||||
path.type = "text";
|
||||
path.name = "path";
|
||||
path.defaultValue = "/";
|
||||
document.getElementById(element).appendChild(path);
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = 'Upload';
|
||||
document.getElementById(element).appendChild(button);
|
||||
var mkdir = document.createElement("button");
|
||||
mkdir.innerHTML = 'MkDir';
|
||||
document.getElementById(element).appendChild(mkdir);
|
||||
var mkfile = document.createElement("button");
|
||||
mkfile.innerHTML = 'MkFile';
|
||||
document.getElementById(element).appendChild(mkfile);
|
||||
|
||||
function httpPostProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
else {
|
||||
tree.refreshPath(path.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
function createPath(p){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("path", p);
|
||||
xmlHttp.open("PUT", urlXXX+"/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
|
||||
mkfile.onclick = function(e){
|
||||
if(path.value.indexOf(".") === -1) return;
|
||||
createPath(path.value);
|
||||
editor.loadUrl(path.value);
|
||||
};
|
||||
mkdir.onclick = function(e){
|
||||
if(path.value.length < 2) return;
|
||||
var dir = path.value
|
||||
if(dir.indexOf(".") !== -1){
|
||||
if(dir.lastIndexOf("/") === 0) return;
|
||||
dir = dir.substring(0, dir.lastIndexOf("/"));
|
||||
}
|
||||
createPath(dir);
|
||||
};
|
||||
button.onclick = function(e){
|
||||
if(input.files.length === 0){
|
||||
return;
|
||||
}
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("data", input.files[0], path.value);
|
||||
xmlHttp.open("POST", urlXXX+"/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
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){
|
||||
//1197 bolt if(name.length > 8) name = name.substring(0, 8);
|
||||
filename = name;
|
||||
}
|
||||
if(typeof ext !== undefined){
|
||||
if(ext === "html") ext = "htm";
|
||||
else if(ext === "jpeg") ext = "jpg";
|
||||
filename = filename + "." + ext;
|
||||
}
|
||||
if(path.value === "/" || path.value.lastIndexOf("/") === 0){
|
||||
path.value = "/"+filename;
|
||||
} else {
|
||||
path.value = path.value.substring(0, path.value.lastIndexOf("/")+1)+filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createTree(element, editor){
|
||||
var preview = document.getElementById("preview");
|
||||
var treeRoot = document.createElement("div");
|
||||
treeRoot.className = "css-treeview";
|
||||
document.getElementById(element).appendChild(treeRoot);
|
||||
|
||||
function loadDownload(path){
|
||||
document.getElementById('download-frame').src = path+"?download=true";
|
||||
}
|
||||
|
||||
function loadPreview(path){
|
||||
document.getElementById("editor").style.display = "none";
|
||||
preview.style.display = "block";
|
||||
preview.innerHTML = '<img src="'+ urlXXX +path+'" style="max-width:100%; max-height:100%; margin:auto; display:block;" />';
|
||||
}
|
||||
|
||||
function fillFolderMenu(el, path){
|
||||
var list = document.createElement("ul");
|
||||
el.appendChild(list);
|
||||
var action = document.createElement("li");
|
||||
list.appendChild(action);
|
||||
var isChecked = document.getElementById(path).checked;
|
||||
var expnd = document.createElement("li");
|
||||
list.appendChild(expnd);
|
||||
if(isChecked){
|
||||
expnd.innerHTML = "<span>Collapse</span>";
|
||||
expnd.onclick = function(e){
|
||||
document.getElementById(path).checked = false;
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var refrsh = document.createElement("li");
|
||||
list.appendChild(refrsh);
|
||||
refrsh.innerHTML = "<span>Refresh</span>";
|
||||
refrsh.onclick = function(e){
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
} else {
|
||||
expnd.innerHTML = "<span>Expand</span>";
|
||||
expnd.onclick = function(e){
|
||||
document.getElementById(path).checked = true;
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
var upload = document.createElement("li");
|
||||
list.appendChild(upload);
|
||||
upload.innerHTML = "<span>Upload</span>";
|
||||
upload.onclick = function(e){
|
||||
var pathEl = document.getElementById("upload-path");
|
||||
if(pathEl){
|
||||
var subPath = pathEl.value;
|
||||
if(subPath.lastIndexOf("/") < 1) pathEl.value = path+subPath;
|
||||
else pathEl.value = path.substring(subPath.lastIndexOf("/"))+subPath;
|
||||
}
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var delFile = document.createElement("li");
|
||||
list.appendChild(delFile);
|
||||
delFile.innerHTML = "<span>Delete</span>";
|
||||
delFile.onclick = function(e){
|
||||
httpDelete(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
|
||||
function fillFileMenu(el, path){
|
||||
var list = document.createElement("ul");
|
||||
el.appendChild(list);
|
||||
var action = document.createElement("li");
|
||||
list.appendChild(action);
|
||||
if(isTextFile(path)){
|
||||
action.innerHTML = "<span>Edit</span>";
|
||||
action.onclick = function(e){
|
||||
editor.loadUrl(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
} else if(isImageFile(path)){
|
||||
action.innerHTML = "<span>Preview</span>";
|
||||
action.onclick = function(e){
|
||||
loadPreview(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
var download = document.createElement("li");
|
||||
list.appendChild(download);
|
||||
download.innerHTML = "<span>Download</span>";
|
||||
download.onclick = function(e){
|
||||
loadDownload(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var delFile = document.createElement("li");
|
||||
list.appendChild(delFile);
|
||||
delFile.innerHTML = "<span>Delete</span>";
|
||||
delFile.onclick = function(e){
|
||||
httpDelete(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
|
||||
function showContextMenu(e, path, isfile){
|
||||
var divContext = document.createElement("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 = e.clientX + scrollLeft;
|
||||
var top = e.clientY + scrollTop;
|
||||
divContext.className = 'contextMenu';
|
||||
divContext.style.display = 'block';
|
||||
divContext.style.left = left + 'px';
|
||||
divContext.style.top = top + 'px';
|
||||
if(isfile) fillFileMenu(divContext, path);
|
||||
else fillFolderMenu(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('contextMenu').length > 0) document.body.removeChild(divContext);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createTreeLeaf(path, name, size){
|
||||
var leaf = document.createElement("li");
|
||||
leaf.id = (((path == "/")?"":path)+"/"+name).toLowerCase();
|
||||
var label = document.createElement("span");
|
||||
label.textContent = name.toLowerCase();
|
||||
leaf.appendChild(label);
|
||||
leaf.onclick = function(e){
|
||||
if(isTextFile(leaf.id)){
|
||||
editor.loadUrl(leaf.id);
|
||||
} else if(isImageFile(leaf.id)){
|
||||
loadPreview(leaf.id);
|
||||
}
|
||||
};
|
||||
leaf.oncontextmenu = function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
showContextMenu(e, leaf.id, true);
|
||||
};
|
||||
return leaf;
|
||||
}
|
||||
|
||||
function createTreeBranch(path, name, disabled){
|
||||
var leaf = document.createElement("li");
|
||||
var check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
check.id = (((path == "/")?"":path)+"/"+name).toLowerCase();
|
||||
if(typeof disabled !== "undefined" && disabled) check.disabled = "disabled";
|
||||
leaf.appendChild(check);
|
||||
var label = document.createElement("label");
|
||||
label.for = check.id;
|
||||
label.textContent = name.toLowerCase();
|
||||
leaf.appendChild(label);
|
||||
check.onchange = function(e){
|
||||
if(check.checked){
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, check.id);
|
||||
}
|
||||
};
|
||||
label.onclick = function(e){
|
||||
if(!check.checked){
|
||||
check.checked = true;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, check.id);
|
||||
} else {
|
||||
check.checked = false;
|
||||
}
|
||||
};
|
||||
leaf.oncontextmenu = function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
showContextMenu(e, check.id, false);
|
||||
}
|
||||
return leaf;
|
||||
}
|
||||
|
||||
function addList(parent, path, items){
|
||||
var list = document.createElement("ul");
|
||||
parent.appendChild(list);
|
||||
var ll = items.length;
|
||||
//Сортировка файлов
|
||||
items.sort(function(a,b){return (a.name < b.name) ? 1 : ((b.name < a.name) ? -1 : 0);});
|
||||
for(var i = 0; i < ll; i++){
|
||||
var item = items[i];
|
||||
var itemEl;
|
||||
if(item.type === "file"){
|
||||
itemEl = createTreeLeaf(path, item.name, item.size);
|
||||
} else {
|
||||
itemEl = createTreeBranch(path, item.name);
|
||||
}
|
||||
list.appendChild(itemEl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function isTextFile(path){
|
||||
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "txt":
|
||||
case "htm":
|
||||
case "html":
|
||||
case "js":
|
||||
case "json":
|
||||
case "c":
|
||||
case "h":
|
||||
case "cpp":
|
||||
case "css":
|
||||
case "xml":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isImageFile(path){
|
||||
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "png":
|
||||
case "jpg":
|
||||
case "gif":
|
||||
case "ico":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.refreshPath = function(path){
|
||||
if(path.lastIndexOf('/') < 1){
|
||||
path = '/';
|
||||
treeRoot.removeChild(treeRoot.childNodes[0]);
|
||||
httpGet(treeRoot, "/");
|
||||
} else {
|
||||
path = path.substring(0, path.lastIndexOf('/'));
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
}
|
||||
};
|
||||
|
||||
function delCb(path){
|
||||
return function(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200){
|
||||
alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
} else {
|
||||
if(path.lastIndexOf('/') < 1){
|
||||
path = '/';
|
||||
treeRoot.removeChild(treeRoot.childNodes[0]);
|
||||
httpGet(treeRoot, "/");
|
||||
} else {
|
||||
path = path.substring(0, path.lastIndexOf('/'));
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpDelete(filename){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = delCb(filename);
|
||||
var formData = new FormData();
|
||||
formData.append("path", filename);
|
||||
xmlHttp.open("DELETE", urlXXX+"/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
|
||||
function getCb(parent, path){
|
||||
return function(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
//clear loading
|
||||
if(xmlHttp.status == 200) addList(parent, path, JSON.parse(xmlHttp.responseText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpGet(parent, path){
|
||||
xmlHttp = new XMLHttpRequest(parent, path);
|
||||
xmlHttp.onreadystatechange = getCb(parent, path);
|
||||
//Для отключения кэша random() иначе будут старые данные
|
||||
xmlHttp.open("GET", urlXXX+"/edit?list=" + path +"&rand="+Math.random(), true);
|
||||
xmlHttp.send(null);
|
||||
//start loading
|
||||
}
|
||||
|
||||
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 "txt": lang = "plain"; break;
|
||||
case "htm": lang = "html"; break;
|
||||
case "js": lang = "javascript"; break;
|
||||
case "c": lang = "c_cpp"; break;
|
||||
case "cpp": lang = "c_cpp"; break;
|
||||
case "css":
|
||||
case "scss":
|
||||
case "php":
|
||||
case "html":
|
||||
case "json":
|
||||
case "xml":
|
||||
lang = ext;
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
if(typeof file === "undefined") file = "/index.htm";
|
||||
|
||||
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 xmlHttp = null;
|
||||
var editor = ace.edit(element);
|
||||
|
||||
//post
|
||||
function httpPostProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
}
|
||||
}
|
||||
function httpPost(filename, data, type){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("data", new Blob([data], { type: type }), filename);
|
||||
xmlHttp.open("POST", urlXXX + "/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
//get
|
||||
function httpGetProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
document.getElementById("preview").style.display = "none";
|
||||
document.getElementById("editor").style.display = "block";
|
||||
if(xmlHttp.status == 200) editor.setValue(xmlHttp.responseText);
|
||||
else editor.setValue("");
|
||||
editor.clearSelection();
|
||||
}
|
||||
}
|
||||
function httpGet(theUrl){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpGetProcessRequest;
|
||||
if (theUrl.indexOf("/") == 0)
|
||||
theUrl = urlXXX + theUrl;//bolt
|
||||
xmlHttp.open("GET", theUrl+"?rand="+Math.random(), true);
|
||||
xmlHttp.send(null);
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
httpGet(file);
|
||||
editor.loadUrl = function(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 s = "http://192.168.211.180/edit/index.htm";
|
||||
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
|
||||
// var parts = s.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
|
||||
if (typeof vars.url !== "undefined" && vars.url != "")
|
||||
urlXXX = "http://" + vars.url;/**/
|
||||
var editor = createEditor("editor", vars.file, vars.lang, vars.theme);
|
||||
var tree = createTree("tree", editor);
|
||||
createFileUploader("uploader", tree, editor);
|
||||
};
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
(function() {
|
||||
window.require(["ace/ace"], function(a) {
|
||||
a && a.config.init(true);
|
||||
if (!window.ace)
|
||||
window.ace = a;
|
||||
for (var key in a) if (a.hasOwnProperty(key))
|
||||
window.ace[key] = a[key];
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onBodyLoad();">
|
||||
<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>
|
||||
BIN
data/edit.htm.gz
Normal file
BIN
data/edit.htm.gz
Normal file
Binary file not shown.
@@ -4,27 +4,21 @@ button 3 14 Кухня Реле 0 3
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 4
|
||||
pwm 2 4 Яркость#ванная: Реле 510 5
|
||||
//---------------------------------------------------------------------
|
||||
//analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
|
||||
analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
|
||||
inputDigit digit1 При#скольки#включить? Датчики 10 7
|
||||
inputDigit digit2 При#скольки#выключить? Датчики 0 8
|
||||
button 4 na Нагреватель Датчики 0 9
|
||||
//dallas 2 Водонагреватель,#t°C Датчики any-data 10
|
||||
//dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 11
|
||||
//dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 12
|
||||
//dhtComfort Степень#комфорта: Датчики 12
|
||||
//dhtPerception Восприятие: Датчики 13
|
||||
//dhtDewpoint Точка#росы: Датчики 14
|
||||
//level Вода#в#баке,#% Датчики any-data 125 20 15
|
||||
//---------------------------------------------------------------------
|
||||
button 5 na Вкл#обратный#таймер Таймеры 0 16
|
||||
inputDigit digit3 Через#сколько#секунд#включить? Таймеры 5 17
|
||||
button 6 na Включится#по#таймеру Таймеры 0 18
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20.30 19
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 19
|
||||
button 7 5 Включится#по#таймеру Таймеры 0 20
|
||||
//---------------------------------------------------------------------
|
||||
switch 1 0 20
|
||||
textSet 1 неопределено
|
||||
text 1 Квартира Двери 22
|
||||
text 1 Вход: Охрана 20
|
||||
textSet 1 не#обнаружено-time
|
||||
button 8 na Сбросить Охрана 0 21
|
||||
//---------------------------------------------------------------------
|
||||
button 8 scenario Вкл#выкл#все#сценарии Сценарии 1 23
|
||||
button 9 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
|
||||
button 9 scenario Вкл#выкл#все#сценарии Сценарии 1 23
|
||||
button 10 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
|
||||
@@ -24,9 +24,10 @@ timenow = time1
|
||||
buttonSet 7 1
|
||||
end
|
||||
switch1 = 1
|
||||
textSet 1 закрыто-time
|
||||
push закрыто вход
|
||||
textSet 1 обнаружено#движение-time
|
||||
push Внимание обнаружено#движение!
|
||||
end
|
||||
switch1 = 0
|
||||
textSet 1 открыто-time
|
||||
button8 = 1
|
||||
textSet 1 не#обнаружено-time
|
||||
buttonSet 8 0
|
||||
end
|
||||
@@ -46,6 +46,25 @@
|
||||
"action": "/page.htm?pushingbox",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"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":"Обновить прошивку",
|
||||
"action": "/upgrade",
|
||||
"response":"[[my-block]]",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Скачать приложение IoT Manager для android",
|
||||
|
||||
BIN
data/mode-html.js.gz
Normal file
BIN
data/mode-html.js.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user