6 — Умный дом на Ардуино. Глава I — Теплый пол. Часть 2 — Управление и настройка через web. 2

В предыдущей статье мы сделали «пассивное» управление теплым полом. Когда контроллер с заданными параметрами управляет теплым полом. Также мы рассмотрели как посылать запросы на Ардуино через WEBинтерфейс.

Ниже рассмотрим управление теплым полом через Web-интерфейс, а также его настройку.

Наша схема претерпера изменения. В обмене данными между ардуинками мы использовали Serial, но теперь мы будем использовать протокол VirtualWire, что позволит в будущем по беспроводной связи опрашивать не только ардуинки но и другиеконтроллеры .

Схема умного дома на Ардуино

shema.png

При использовании VirtualWire получение температуры с датчиков невозможно из-за использования одного таймера. Для решения данной проблемы в с скетче прием сообщения по VirtualWire активируется только перед приемом сообщения!!

слейв контроллера №1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//Скетч для 1го контроллера
//управление теплым полом
//температурные датчики ds18b20
//реле, управляемое минусом
 
/*---------------------------------------------------------------------*/
//переменные для связи контроллеров
#include //библиотека
uint8_t buf_in[10];
uint8_t buf_out[10];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
/*---------------------------------------------------------------------*/
//переменные для ds18b20
#include //библиотека опроса по одному проводу
#include //библиотека DS18B20
#define ONE_WIRE_BUS 4//пин датчиков DS18B20
OneWire oneWire(ONE_WIRE_BUS);
 sensors(&oneWire);
/*---------------------------------------------------------------------*/
//переменные теплого пола кухни
DeviceAddress deviceAdress_tp_kitchen = { 0x28, 0xE7, 0x73, 0x82, 0x05, 0x00, 0x00, 0x7A }; // - Адрес датчика температуры в кухни
int temp_kitchen_param[2]={13,0};// 0 0 0 011 0 1//1 при старте контроллера включен режим автомат температура 26-27
float temp_kitchen;//Измеренная температура пола кухни
int pin_kitchen=1;//пин управления реле теплого пола кухни
/*---------------------------------------------------------------------*/
//переменные теплого пола ванной
DeviceAddress deviceAdress_tp_bath = { 0x28, 0xFD, 0x3B, 0x83, 0x05, 0x00, 0x00, 0xB6 }; //Теплый пол - Адрес датчика температуры в ванной
int temp_bath_param[2]={13,0};//00001101 при старте контроллера включен режим автомат температура 26-27
float temp_bath;//Измеренная температура пола ванной
int pin_bath=0; //пин управления реле теплого пола ванной
 
//настройки теплого пола temp_()_param[1]
//режим автомат 1,0 - 1 бит
//режим ручной, включено/выключено 1,0 - 1 бит
//в режиме автомат температура заданная 23..31 - 3 бита
//в режиме автомат +- поддержания температуры 1-2 градуса - 1 бит
//в режиме автомат отключение на ночь по времени 1,0 - 1 бит
 
void setup() {
//настройка vitrualwire
vw_set_tx_pin(7);
vw_set_rx_pin(8);
vw_set_ptt_inverted(true);
vw_setup(9000);
 
/*---------------------------------------------------------------------*/
sensors.begin();//Dallastemperature
/*---------------------------------------------------------------------*/
//настройки теплого пола кухни
sensors.setResolution(deviceAdress_tp_kitchen, 12);//устанавливаем дискретность температур (9-0.5;10-0.25,11-0.125,12-0)
pinMode(pin_kitchen, OUTPUT); //пин управления реле Теплый пол - Датчик на кухне
digitalWrite(pin_kitchen, HIGH); //выключаем теплый пол Датчик на кухне(реле управляется минусом)
/*---------------------------------------------------------------------*/
//настройки теплого пола ванной
sensors.setResolution(deviceAdress_tp_bath, 12);//устанавливаем дискретность температур (9-0.5;10-0.25,11-0.125,12-0)
pinMode(pin_bath, OUTPUT); //пин управления реле Теплый пол - Датчик в ванной
digitalWrite(pin_bath, HIGH); //выключаем теплый пол Датчик в ванной(реле управляется минусом)
/*---------------------------------------------------------------------*/
 
attachInterrupt(0, VWwait, RISING);//прерывание для получение сообщения с главного контроллера
 
}
 
void loop()
{
//опрос температуры пола кухни
if (my_timer(3000,1)==true) get_temp_ds(&deviceAdress_tp_kitchen[0], &temp_kitchen);//используем таймер
//опрос температуры пола ванной
if (my_timer(3000,2)==true) get_temp_ds(&deviceAdress_tp_bath[0], &temp_bath);//используем таймер
//управление теплым полом кухни
set_tp(&temp_kitchen_param[0], temp_kitchen, pin_kitchen);
//управление теплым полом ванной
set_tp(&temp_bath_param[0], temp_bath, pin_bath);
//delay(100);
 
}
 
void get_temp_ds(uint8_t * deviceAdress, float *temp)//получаем температуру с датчика
{
sensors.requestTemperatures();//опрос датчика
float temp_new;//переменная для получения новой температуры
temp_new=sensors.getTempC(deviceAdress);//получаем температуру в градусах Цельсия
if ((temp_new>10) & (temp_new<50)) *temp=temp_new;//если значение реальное то обновляем переменную температуры
}
 
void set_tp(int *temp_param, float temp, int pin)//управляем теплым полом
{
if ((temp_param[0] & 1)==1)//если автоматический режим
{
if (temp<((temp_param[0] & 28)>>2)+23)//если температура ниже заданной
{
digitalWrite(pin, LOW);//включить теплый пол
temp_param[0]=((temp_param[0]>>2)<<2) xor 1;//записываем состояние теплого пола "вкл" }else if (temp>((temp_param[0] & 28)>>2)+23+1+((temp_param[0] & 32)>>5))//если температура выше заданной
{
digitalWrite(pin, HIGH);//выключить теплый пол
temp_param[0]=((temp_param[0]>>2)<<2) xor 3;//записываем состояние теплого пола "выкл" } } else digitalWrite(pin, (temp_param[0] & 2)>0);//если ручной режим, то устанавливаем выставленнное вручную значение вкл/выкл
}
 
void VWwait()//по прерыванию получаем сообщение от главного контроллера
{
 
vw_rx_start();//включаем прием сообщение через virtualwire
detachInterrupt(0);
interrupts();
delay(50);
 
if (vw_get_message(buf_in, &buflen))//если пришло сообщение
{
 
int val;//сообщение с главного контроллера
val=buf_in[0];
 
switch (val){
case 0xf1://запрос состояния датчиков
 
send_vw(val);//отправляем настройки и состояние датчиков
break;
case 0xA1://принимаем параметры управления и настройки контроллера
temp_kitchen_param[0]=buf_in[1];//параметры теплого пола кухни
temp_kitchen_param[1]=buf_in[2];//параметры теплого пола кухни
temp_bath_param[0]=buf_in[3]; //параметры теплого пола ванной
temp_bath_param[1]=buf_in[4];//параметры теплого пола ванной
send_vw(val);//отправляем настройки и состояние датчиков
break;
}
 
}
vw_rx_stop();//прерываем процесс приема сообщений
attachInterrupt(0, VWwait, RISING);
 
}
 
void send_vw(int A)//отправляем настройки и состояние датчиков
{
 
buf_out[0]=0xf1;
uint8_t* buf_;
buf_=temp_float_to_buf(temp_kitchen);//преобразовываем температуру в byte
buf_out[1]=(uint8_t)buf_[0];
buf_out[2]=(uint8_t)buf_[1];
buf_out[3]=(uint8_t)buf_[2];
buf_=temp_float_to_buf(temp_bath);//преобразовываем температуру в byte
buf_out[4]=(uint8_t)buf_[0];
buf_out[5]=(uint8_t)buf_[1];
buf_out[6]=(uint8_t)buf_[2];
buf_out[7]=(uint8_t)temp_kitchen_param[0];//отправляем настройки теплого пола кухни
buf_out[8]=(uint8_t)temp_bath_param[0];//отправляем настройки теплого пола ванной
vw_send(buf_out,sizeof(buf_out));
vw_wait_tx();//ожидаем конца передачи сообщения на главный контроллер
}
//Скетч для 1го контроллера
//управление теплым полом
//температурные датчики ds18b20
//реле, управляемое минусом

/*---------------------------------------------------------------------*/
//переменные для связи контроллеров
#include //библиотека
uint8_t buf_in[10];
uint8_t buf_out[10];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
/*---------------------------------------------------------------------*/
//переменные для ds18b20
#include //библиотека опроса по одному проводу
#include //библиотека DS18B20
#define ONE_WIRE_BUS 4//пин датчиков DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
/*---------------------------------------------------------------------*/
//переменные теплого пола кухни
DeviceAddress deviceAdress_tp_kitchen = { 0x28, 0xE7, 0x73, 0x82, 0x05, 0x00, 0x00, 0x7A }; //Теплый пол - Адрес датчика температуры в кухни
int temp_kitchen_param[2]={13,0};// 0 0 0 011 0 1//1 при старте контроллера включен режим автомат температура 26-27
float temp_kitchen;//Измеренная температура пола кухни
int pin_kitchen=1;//пин управления реле теплого пола кухни
/*---------------------------------------------------------------------*/
//переменные теплого пола ванной
DeviceAddress deviceAdress_tp_bath = { 0x28, 0xFD, 0x3B, 0x83, 0x05, 0x00, 0x00, 0xB6 }; //Теплый пол - Адрес датчика температуры в ванной
int temp_bath_param[2]={13,0};//00001101 при старте контроллера включен режим автомат температура 26-27
float temp_bath;//Измеренная температура пола ванной
int pin_bath=0; //пин управления реле теплого пола ванной

//настройки теплого пола temp_()_param[1]
//режим автомат 1,0 - 1 бит
//режим ручной, включено/выключено 1,0 - 1 бит
//в режиме автомат температура заданная 23..31 - 3 бита
//в режиме автомат +- поддержания температуры 1-2 градуса - 1 бит
//в режиме автомат отключение на ночь по времени 1,0 - 1 бит

void setup() {
//настройка vitrualwire
vw_set_tx_pin(7);
vw_set_rx_pin(8);
vw_set_ptt_inverted(true);
vw_setup(9000);

/*---------------------------------------------------------------------*/
sensors.begin();//Dallastemperature
/*---------------------------------------------------------------------*/
//настройки теплого пола кухни
sensors.setResolution(deviceAdress_tp_kitchen, 12);//устанавливаем дискретность температур (9-0.5;10-0.25,11-0.125,12-0)
pinMode(pin_kitchen, OUTPUT); //пин управления реле Теплый пол - Датчик на кухне
digitalWrite(pin_kitchen, HIGH); //выключаем теплый пол Датчик на кухне(реле управляется минусом)
/*---------------------------------------------------------------------*/
//настройки теплого пола ванной
sensors.setResolution(deviceAdress_tp_bath, 12);//устанавливаем дискретность температур (9-0.5;10-0.25,11-0.125,12-0)
pinMode(pin_bath, OUTPUT); //пин управления реле Теплый пол - Датчик в ванной
digitalWrite(pin_bath, HIGH); //выключаем теплый пол Датчик в ванной(реле управляется минусом)
/*---------------------------------------------------------------------*/

attachInterrupt(0, VWwait, RISING);//прерывание для получение сообщения с главного контроллера

}

void loop()
{
//опрос температуры пола кухни
if (my_timer(3000,1)==true) get_temp_ds(&deviceAdress_tp_kitchen[0], &temp_kitchen);//используем таймер
//опрос температуры пола ванной
if (my_timer(3000,2)==true) get_temp_ds(&deviceAdress_tp_bath[0], &temp_bath);//используем таймер
//управление теплым полом кухни
set_tp(&temp_kitchen_param[0], temp_kitchen, pin_kitchen);
//управление теплым полом ванной
set_tp(&temp_bath_param[0], temp_bath, pin_bath);
//delay(100);

}

void get_temp_ds(uint8_t * deviceAdress, float *temp)//получаем температуру с датчика
{
sensors.requestTemperatures();//опрос датчика
float temp_new;//переменная для получения новой температуры
temp_new=sensors.getTempC(deviceAdress);//получаем температуру в градусах Цельсия
if ((temp_new>10) & (temp_new<50)) *temp=temp_new;//если значение реальное то обновляем переменную температуры
}

void set_tp(int *temp_param, float temp, int pin)//управляем теплым полом
{
if ((temp_param[0] & 1)==1)//если автоматический режим
{
if (temp<((temp_param[0] & 28)>>2)+23)//если температура ниже заданной
{
digitalWrite(pin, LOW);//включить теплый пол
temp_param[0]=((temp_param[0]>>2)<<2) xor 1;//записываем состояние теплого пола "вкл" }else if (temp>((temp_param[0] & 28)>>2)+23+1+((temp_param[0] & 32)>>5))//если температура выше заданной
{
digitalWrite(pin, HIGH);//выключить теплый пол
temp_param[0]=((temp_param[0]>>2)<<2) xor 3;//записываем состояние теплого пола "выкл" } } else digitalWrite(pin, (temp_param[0] & 2)>0);//если ручной режим, то устанавливаем выставленнное вручную значение вкл/выкл
}

void VWwait()//по прерыванию получаем сообщение от главного контроллера
{

vw_rx_start();//включаем прием сообщение через virtualwire
detachInterrupt(0);
interrupts();
delay(50);

if (vw_get_message(buf_in, &buflen))//если пришло сообщение
{

int val;//сообщение с главного контроллера
val=buf_in[0];

switch (val){
case 0xf1://запрос состояния датчиков

send_vw(val);//отправляем настройки и состояние датчиков
break;
case 0xA1://принимаем параметры управления и настройки контроллера
temp_kitchen_param[0]=buf_in[1];//параметры теплого пола кухни
temp_kitchen_param[1]=buf_in[2];//параметры теплого пола кухни
temp_bath_param[0]=buf_in[3]; //параметры теплого пола ванной
temp_bath_param[1]=buf_in[4];//параметры теплого пола ванной
send_vw(val);//отправляем настройки и состояние датчиков
break;
}

}
vw_rx_stop();//прерываем процесс приема сообщений
attachInterrupt(0, VWwait, RISING);

}

void send_vw(int A)//отправляем настройки и состояние датчиков
{

buf_out[0]=0xf1;
uint8_t* buf_;
buf_=temp_float_to_buf(temp_kitchen);//преобразовываем температуру в byte
buf_out[1]=(uint8_t)buf_[0];
buf_out[2]=(uint8_t)buf_[1];
buf_out[3]=(uint8_t)buf_[2];
buf_=temp_float_to_buf(temp_bath);//преобразовываем температуру в byte
buf_out[4]=(uint8_t)buf_[0];
buf_out[5]=(uint8_t)buf_[1];
buf_out[6]=(uint8_t)buf_[2];
buf_out[7]=(uint8_t)temp_kitchen_param[0];//отправляем настройки теплого пола кухни
buf_out[8]=(uint8_t)temp_bath_param[0];//отправляем настройки теплого пола ванной
vw_send(buf_out,sizeof(buf_out));
vw_wait_tx();//ожидаем конца передачи сообщения на главный контроллер
}

Скетч мастер контроллера

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//Мастер-контроллер
int n_c; //номер контроллера с которым мы будем работать, 0 - работаем со всеми
boolean n_t; //тип операции(false - запрос данных, true - передача настроек)
/*---------------------------------------------------------------------*/
//переменные 1 контроллера
String
temp_kitchen_pol, //температура пола кухни
temp_bath_pol;//температура пола ванной
int pin_inter=6;//not 13,12,11,10 //посылаем сигнал прерывание на Slave контроллер
int temp_kitchen_param[2];//параметры теплого пола кухни
int temp_bath_param[2];//параметры теплого пола ванной
/*---------------------------------------------------------------------*/
//переменные для настройки virtualWire
#include
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
uint8_t buf_in1[10];//входящее сообщение 1 контроллера
uint8_t buf_out1[10];//исходящее сообщение 1 контроллера
/*---------------------------------------------------------------------*/
 
void setup() {
//настройка virtualWire
vw_set_tx_pin(7);//пин передачи
vw_set_rx_pin(8);//пин приема
vw_set_ptt_inverted(true);
vw_setup(9000);//скорость передачи данных
vw_rx_start();//ожидание входящего сообщения
/*---------------------------------------------------------------------*/
Serial.begin(19200);
pinMode(pin_inter, OUTPUT);
/*---------------------------------------------------------------------*/
}
 
void loop() {
//читаем сериал - читаем все пакеты и записываем их в переменные
if (get_serial())//если пришел запрос через сериал
{
//обмен данными с контроллером №1 - отправляем все переменные и запрашиваем состояние датчиков
digitalWrite(pin_inter, HIGH);
delay(20);
get_1();
set_1();
delay(50);
digitalWrite(pin_inter, LOW);
//пишем в сериал результат
set_serial();
}
}
 
boolean get_serial()
{
 
if (Serial.available())//Ожидаем опроса
{
int sr;
sr = Serial.read();
delay(20);
n_t = sr-'0'==0x01;
n_c = Serial.read()-'0';
if (!n_t) return true;
if (n_c==1)
{
buf_out1[1]=get_serial_string_bin_to_int();
buf_out1[2]=0x00;
buf_out1[3]=get_serial_string_bin_to_int();
buf_out1[4]=0x00;
}
while (Serial.available())Serial.read();//очистка буфера Serial от мусора, если он есть
return true;
} return false;
}
 
void get_1()//читаем состояние датчиков с 1 контроллера
{
if (n_c!=1 & n_c!=0) return;
if (n_t) return;
synch_1(0xF1);//функция чтения данных с контроллера
}
 
void set_1()//передаем настройки на 1 контроллер
{
if (n_c!=1) return;
if (!n_t) return;
synch_1(0xA1);
}
 
void synch_1(int param)
{
buf_out1[0]=param;
vw_send(buf_out1, sizeof(buf_out1));
delay(60);
int val;
if (vw_get_message(buf_in1, &buflen))
{
val=buf_in1[0];
if (val==0xf1)
{
uint8_t buf_[3];
buf_[0]=buf_in1[1];
buf_[1]=buf_in1[2];
buf_[2]=buf_in1[3];
temp_kitchen_pol=temp_buf_to_string(buf_);// получаем температуру
buf_[0]=buf_in1[4];
buf_[1]=buf_in1[5];
buf_[2]=buf_in1[6];
temp_bath_pol=temp_buf_to_string(buf_);// получаем температуру
temp_kitchen_param[0]=val=buf_in1[7];
temp_bath_param[0]=val=buf_in1[8];
}
}
}
 
void set_serial()//пишем в Сериал то, что получили с контроллеров
{
 
Serial.println("begin");//начало передачи
Serial.println(temp_kitchen_pol);//отправляем температуру теплого пола кухни
Serial.println(temp_bath_pol); //отправляем температуру теплого пола ванной
Serial.println(temp_kitchen_param[0],DEC);//отправляем параметры теплого пола кухни
Serial.println(temp_bath_param[0],DEC);//отправляем параметры теплого пола ванной
 
}
//Мастер-контроллер
int n_c; //номер контроллера с которым мы будем работать, 0 - работаем со всеми
boolean n_t; //тип операции(false - запрос данных, true - передача настроек)
/*---------------------------------------------------------------------*/
//переменные 1 контроллера
String
temp_kitchen_pol, //температура пола кухни
temp_bath_pol;//температура пола ванной
int pin_inter=6;//not 13,12,11,10 //посылаем сигнал прерывание на Slave контроллер
int temp_kitchen_param[2];//параметры теплого пола кухни
int temp_bath_param[2];//параметры теплого пола ванной
/*---------------------------------------------------------------------*/
//переменные для настройки virtualWire
#include
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
uint8_t buf_in1[10];//входящее сообщение 1 контроллера
uint8_t buf_out1[10];//исходящее сообщение 1 контроллера
/*---------------------------------------------------------------------*/

void setup() {
//настройка virtualWire
vw_set_tx_pin(7);//пин передачи
vw_set_rx_pin(8);//пин приема
vw_set_ptt_inverted(true);
vw_setup(9000);//скорость передачи данных
vw_rx_start();//ожидание входящего сообщения
/*---------------------------------------------------------------------*/
Serial.begin(19200);
pinMode(pin_inter, OUTPUT);
/*---------------------------------------------------------------------*/
}

void loop() {
//читаем сериал - читаем все пакеты и записываем их в переменные
if (get_serial())//если пришел запрос через сериал
{
//обмен данными с контроллером №1 - отправляем все переменные и запрашиваем состояние датчиков
digitalWrite(pin_inter, HIGH);
delay(20);
get_1();
set_1();
delay(50);
digitalWrite(pin_inter, LOW);
//пишем в сериал результат
set_serial();
}
}

boolean get_serial()
{

if (Serial.available())//Ожидаем опроса
{
int sr;
sr = Serial.read();
delay(20);
n_t = sr-'0'==0x01;
n_c = Serial.read()-'0';
if (!n_t) return true;
if (n_c==1)
{
buf_out1[1]=get_serial_string_bin_to_int();
buf_out1[2]=0x00;
buf_out1[3]=get_serial_string_bin_to_int();
buf_out1[4]=0x00;
}
while (Serial.available())Serial.read();//очистка буфера Serial от мусора, если он есть
return true;
} return false;
}

void get_1()//читаем состояние датчиков с 1 контроллера
{
if (n_c!=1 & n_c!=0) return;
if (n_t) return;
synch_1(0xF1);//функция чтения данных с контроллера
}

void set_1()//передаем настройки на 1 контроллер
{
if (n_c!=1) return;
if (!n_t) return;
synch_1(0xA1);
}

void synch_1(int param)
{
buf_out1[0]=param;
vw_send(buf_out1, sizeof(buf_out1));
delay(60);
int val;
if (vw_get_message(buf_in1, &buflen))
{
val=buf_in1[0];
if (val==0xf1)
{
uint8_t buf_[3];
buf_[0]=buf_in1[1];
buf_[1]=buf_in1[2];
buf_[2]=buf_in1[3];
temp_kitchen_pol=temp_buf_to_string(buf_);// получаем температуру
buf_[0]=buf_in1[4];
buf_[1]=buf_in1[5];
buf_[2]=buf_in1[6];
temp_bath_pol=temp_buf_to_string(buf_);// получаем температуру
temp_kitchen_param[0]=val=buf_in1[7];
temp_bath_param[0]=val=buf_in1[8];
}
}
}

void set_serial()//пишем в Сериал то, что получили с контроллеров
{

Serial.println("begin");//начало передачи
Serial.println(temp_kitchen_pol);//отправляем температуру теплого пола кухни
Serial.println(temp_bath_pol); //отправляем температуру теплого пола ванной
Serial.println(temp_kitchen_param[0],DEC);//отправляем параметры теплого пола кухни
Serial.println(temp_bath_param[0],DEC);//отправляем параметры теплого пола ванной

}

Для удобной обработки данных в веб интерфейсе добавим в нашу настроенную OpenWRT поддержку JSON

Для этого необходимо установить пакет 5-mod-json и в php.ini раскомментировать строчку

1
extension=json.so
extension=json.so

Код php файла для обмена данными с мастер контроллером

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!--?php    $n_t =$_POST['n_t'];//тип запроса     $tpv=$_POST['tpv'];//настройки теплого пола ванной    $tpk=$_POST['tpk'];//настройки теплого пола кухни  $n_c=$_POST['n_c'];//номер контроллера  //$n_t =$_GET['n_t'];   //$tpv=$_GET['tpv'];    //$tpk=$_GET['tpk'];        if ($n_t != 100){       //// настройки сериал соедиенния       include "php_serial.class.php";         $serial = new phpSerial;                    $serial--->deviceSet("/dev/ttyUSB0");
$serial->confBaudRate(19200);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->deviceOpen();
 
if ($n_t==1){//передаем настройки и читаем данные
if ($n_c==1) $msg=sprintf( "%08d", decbin($tpk)).sprintf( "%08d", decbin($tpv));//передаем настройки в string binnary на первый слейв контроллер
$serial->sendMessage($n_t.$n_c.$msg,0.3);
getserial($serial->readPort(10));//отправляем запрос контроллеру
}
if ($n_t==0){//читаем данные со всех контроллеров
$serial->sendMessage($n_t.'0',0.3);
getserial($serial->readPort(10));//отправляем запрос контроллеру
 
}
$serial->deviceClose();
} else
if ($n_t == 100){//режим эмуляции без контроллера, для отладки
$arr['tpk_temp']=22.4;//Температура ТП кухни
$arr['tpv_temp']=23.5;//Температура ТП ванной
//настройки тп кухни
$value=13;
$arr['tpk_settings_int']= $value;
$arr['tpk_settings']=sprintf( "%08d", decbin( $value));
$arr['tpk_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpk_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpk_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpk_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpk_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
//настройки тп ванной
$arr['tpv_settings_int']= $value;
$arr['tpv_settings']=sprintf( "%08d", decbin( $value ));
$arr['tpv_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpv_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpv_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpv_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpv_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
echo json_encode($arr);
}
 
function getserial($read)
{
 
preg_match_all("/\S+/", $read, $matches);//полученные данные разбиваем на части и записываем их в массив $arr
$a=0;
foreach($matches[0] as $value)
{
$a=$a+1;
 
switch ($a)
{
case 1:
break;
case 2:
$arr['tpk_temp']=$value;//Температура ТП кухни
break;
case 3:
$arr['tpv_temp']=$value;//Температура ТП ванной
break;
case 4://настройки тп кухни
$arr['tpk_settings_int']= $value;
$arr['tpk_settings']=sprintf( "%08d", decbin( $value));
$arr['tpk_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpk_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpk_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpk_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpk_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
break;
case 5://настройки тп ванной
$arr['tpv_settings_int']= $value;
$arr['tpv_settings']=sprintf( "%08d", decbin( $value ));
$arr['tpv_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpv_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpv_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpv_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpv_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
break;
}
}
echo json_encode($arr);
}
?>
<!--?php 	$n_t =$_POST['n_t'];//тип запроса 	$tpv=$_POST['tpv'];//настройки теплого пола ванной 	$tpk=$_POST['tpk'];//настройки теплого пола кухни 	$n_c=$_POST['n_c'];//номер контроллера 	//$n_t =$_GET['n_t']; 	//$tpv=$_GET['tpv']; 	//$tpk=$_GET['tpk']; 	 	if ($n_t != 100){ 		//// настройки сериал соедиенния 		include "php_serial.class.php"; 		$serial = new phpSerial;			 		$serial--->deviceSet("/dev/ttyUSB0");
$serial->confBaudRate(19200);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->deviceOpen();

if ($n_t==1){//передаем настройки и читаем данные
if ($n_c==1) $msg=sprintf( "%08d", decbin($tpk)).sprintf( "%08d", decbin($tpv));//передаем настройки в string binnary на первый слейв контроллер
$serial->sendMessage($n_t.$n_c.$msg,0.3);
getserial($serial->readPort(10));//отправляем запрос контроллеру
}
if ($n_t==0){//читаем данные со всех контроллеров
$serial->sendMessage($n_t.'0',0.3);
getserial($serial->readPort(10));//отправляем запрос контроллеру

}
$serial->deviceClose();
} else
if ($n_t == 100){//режим эмуляции без контроллера, для отладки
$arr['tpk_temp']=22.4;//Температура ТП кухни
$arr['tpv_temp']=23.5;//Температура ТП ванной
//настройки тп кухни
$value=13;
$arr['tpk_settings_int']= $value;
$arr['tpk_settings']=sprintf( "%08d", decbin( $value));
$arr['tpk_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpk_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpk_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpk_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpk_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
//настройки тп ванной
$arr['tpv_settings_int']= $value;
$arr['tpv_settings']=sprintf( "%08d", decbin( $value ));
$arr['tpv_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpv_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpv_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpv_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpv_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
echo json_encode($arr);
}

function getserial($read)
{

preg_match_all("/\S+/", $read, $matches);//полученные данные разбиваем на части и записываем их в массив $arr
$a=0;
foreach($matches[0] as $value)
{
$a=$a+1;

switch ($a)
{
case 1:
break;
case 2:
$arr['tpk_temp']=$value;//Температура ТП кухни
break;
case 3:
$arr['tpv_temp']=$value;//Температура ТП ванной
break;
case 4://настройки тп кухни
$arr['tpk_settings_int']= $value;
$arr['tpk_settings']=sprintf( "%08d", decbin( $value));
$arr['tpk_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpk_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpk_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpk_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpk_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
break;
case 5://настройки тп ванной
$arr['tpv_settings_int']= $value;
$arr['tpv_settings']=sprintf( "%08d", decbin( $value ));
$arr['tpv_settings_auto']=($value & 1);//режим - авто/ручной
$arr['tpv_settings_manual']=($value & 2)>>1;//в ручном режиме вкл\выкл
$arr['tpv_settings_temp_min']=(($value & 28)>>2)+23;//заданная температура min
$arr['tpv_settings_temp_max']=(($value & 32)>>5);//заданная температура max
$arr['tpv_settings_night']=(($value & 64)>>6);//отключение на ночь в авто режиме
break;
}
}
echo json_encode($arr);
}
?>

Web-страница отображения и настройки теплого пола

web.png

Для удобства написания и отладки все скрипты написаны на одной странице.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN" "www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
    <meta charset="UTF-8">
    <link href="css/style.css" type="text/css" rel="stylesheet">
    <link href="css/style_switch.css" type="text/css" rel="stylesheet">
    </head>
 
    <body>
 
    <script type="text/javascript" src="jquery.min.js"></script>
 
    <script>
    //общие переменные
    var
    json,//массив данных с контроллера
    npol,//номер теплого пола 1-кухня/2-ванная для формы f1
    tp_settings_manual,//настройки теплого пола для формы f1
    interval_test,//интервал для обновления данных на странице (интервал опроса датчиков)
    f_noparce_json;//флаг обновления данных на странице
    //нстройки контроллера 1
    var 
    v_tpk_settings, //настройки теплого пола кухни бинарное
    v_tpv_settings, //настройки теплого пола ванной бинарное
    v_tpk_settings_int, //настройки теплого пола кухни целое
    v_tpv_settings_int; //настройки теплого пола ванной целое
    //объекты на странице f1-теплый пол
    var 
    _f1, //форма настроек теплого пола
    _tp_set_legend,//заголовок настроек теплого пола
    _f1_ch0,//авто режим
    _f1_ch1,//ночной режим
    _f1_sel1,//темепратура мин
    _f1_sel2,//температура макс
    _f1_sel2_o1,//значение макс темепатуры 1
    _f1_sel2_o2,//значение макс темепатуры 2
    _f1_chk_manual,//ручное управление теплым полом кухни
    _f1_chv_manual;//ручное управление теплым полом ванной
    //////////////////  
    setTimeout(get_elem_byid,1);//поиск  элементов на странице
    setTimeout(test,10);//запрос данных с контрллера
 
    setinterval_test();//задаем таймер запроса данных с контроллеров
    
    function setinterval_test()//задаем таймер запроса данных с контроллеров
    {
        interval_test=setInterval(test, 3000);
    }
    function get_elem_byid()//поиск  элементов на странице
    {
            //поиск элементов для теплого пола
            _f1=document.getElementById('f1' );
            _tp_set_legend=document.getElementById('tp_set_legend' );
            _f1_ch0=document.getElementById('f1_ch0' );
            _f1_ch1=document.getElementById('f1_ch1' );
            _f1_sel1=document.getElementById("f1_sel1");
            _f1_sel2=document.getElementById("f1_sel2");
            _f1_sel2_o1=document.getElementById('f1_sel2_o1' );
            _f1_sel2_o2=document.getElementById('f1_sel2_o2' );
            _f1_chk_manual=document.getElementById('tpk_settings_manual_ch' );
            _f1_chv_manual=document.getElementById('tpv_settings_manual_ch' );
            ////////
 
    }
    function test ()//запрос данных с контрллера
    {
        //if (f_test_stop)return;
        $(function(){
            $.ajax({
                url: "get.php",
                cashe:false,
                type: "POST",
                data: ({n_t:"0"}),
             success: function(data){
                    json = $.parseJSON(data);
                    parseJson();//полученный массив данных json с контроллера раскидываем по странице
 
                   }
              });
    }); 
    }
    function parseJson()//полученный массив данных json с контроллера раскидываем по странице
    {           
                    if (f_noparce_json) return;
                    //теплый пол
                    $("#tpk_temp").html(json.tpk_temp+"°С");//текущая температура теплого пола кухни
                    $("#tpv_temp").html(json.tpv_temp+"°С");//текущая темепратура теплого пола ванной
                    $("#tpk_settings").html(json.tpk_settings);//настройки теплого пола кухни
                    v_tpk_settings=json.tpk_settings;
                    v_tpk_settings_int=json.tpk_settings_int;
                    
                    $("#tpv_settings").html(json.tpv_settings);//настройки теплого пола ванной    
                    v_tpv_settings=json.tpv_settings;
                    v_tpv_settings_int=json.tpv_settings_int;
                    
                    if (json.tpk_settings_auto==1)//кухня - автоматический режим
                    {
                        $("#tpk_settings_auto").html("<div title=\"Автоматический режим\" id=\"tp_settings_auto_1\">A</div>");
                        _f1_chk_manual.disabled = true;
                        _f1_chk_manual.title="Отключите автоматический режим";
                        
                    } else { //кухня - ручной режим
                        $("#tpk_settings_auto").html("<div title=\"Ручной режим\" id=\"tp_settings_auto_0\">M</div>");
                        _f1_chk_manual.disabled = false;
                        
                    }
                    if (json.tpv_settings_auto==1)//ванная - автоматический режим 
                    {
                        $("#tpv_settings_auto").html("<div  title=\"Автоматический режим\" id=\"tp_settings_auto_1\">A</div>");
                        _f1_chv_manual.disabled = true;
                        _f1_chv_manual.title="Отключите автоматический режим";
                    } else {//ванная - ручной режим
                        $("#tpv_settings_auto").html("<div title=\"Ручной режим\" id=\"tp_settings_auto_0\">M</div>");
                        _f1_chv_manual.disabled = false;
                    }   
                    _f1_chv_manual.checked=!json.tpv_settings_manual;//флаг режима
                    
                    if (json.tpv_settings_manual==1)//ванная - состояние теплого пола вкл/выкл
                    {
                        $("#tpv_settings_manual").html("<div title=\"Охлаждение\" class=\"tp_off\"></div>")
                    } else {
                        $("#tpv_settings_manual").html("<div title=\"Нагрев\" class=\"tp_on\"></div>")
                    }
                    _f1_chk_manual.checked=!json.tpk_settings_manual;//флаг режима
                    
                    if (json.tpk_settings_manual==1)//кухня - состояние теплого пола вкл/выкл
                    {
                        $("#tpk_settings_manual").html("<div title=\"Охлаждение\" class=\"tp_off\"></div>")
                    } else {
                        $("#tpk_settings_manual").html("<div title=\"Нагрев\" class=\"tp_on\"></div>")
                    }
                    $("#tpk_settings_temp_min_max").html("("+(json.tpk_settings_temp_min)+"-"+(json.tpk_settings_temp_min+json.tpk_settings_temp_max+1)+")");//задданая темепратура теплого пола кухни
                    $("#tpv_settings_temp_min_max").html("("+(json.tpv_settings_temp_min)+"-"+(json.tpv_settings_temp_min+json.tpv_settings_temp_max+1)+")");//задданая темепратура теплого пола ванной
                    
    
                    if (json.tpk_settings_night==1)//кухня - ночной режим
                    {
                        $("#tpk_settings_night").html("<div class=\"night2\"><div title=\"Ночной режим\" class=\"night\"></div></div>")
                    }else{
                        $("#tpk_settings_night").html("<div></div>")
                    }
                    if (json.tpv_settings_night==1)//ванная - ночной режим
                    {
                        $("#tpv_settings_night").html("<div class=\"night2\"><div title=\"Ночной режим\" class=\"night\"></div></div>")
                    }else{
                        $("#tpv_settings_night").html("<div></div>")
                    } 
 
                    
 
                    //-теплый пол
    }
    
    function settings_tp(aa,f_show)//открыаем форму настроек и запалняем ее настройками
    {   
 
        if (interval_test) clearInterval(interval_test);
        npol=aa;
        if (aa==1)
        {   
            if (f_show) _f1.style.display = 'block';
            _tp_set_legend.innerHTML = 'Настройки теплого пола Кухни';
            _f1_ch0.checked = json.tpk_settings_auto;
            _f1_ch1.checked = json.tpk_settings_night;
            _f1_sel1.value = json.tpk_settings_temp_min;
            _f1_sel2.value = json.tpk_settings_temp_max;
            _f1_sel2_o1.innerHTML=json.tpk_settings_temp_min+1;
            _f1_sel2_o2.innerHTML=json.tpk_settings_temp_min+2;
            document.getElementById('tp_btn_k').style.display='none';       
            document.getElementById('tp_btn_v').style.display='block';
            tp_settings_manual=json.tpk_settings_manual;
        }
        if (aa==2)
        {
            if (f_show)_f1.style.display = 'block';
            _tp_set_legend.innerHTML = 'Настройки теплого пола Ванной';
            _f1_ch0.checked = json.tpv_settings_auto;
            _f1_ch1.checked = json.tpv_settings_night;
            _f1_sel1.value = json.tpv_settings_temp_min;
            _f1_sel2.value = json.tpv_settings_temp_max;
            _f1_sel2_o1.innerHTML=json.tpv_settings_temp_min+1;
            _f1_sel2_o2.innerHTML=json.tpv_settings_temp_min+2; 
            document.getElementById('tp_btn_v').style.display='none';       
            document.getElementById('tp_btn_k').style.display='block';
            tp_settings_manual=json.tpv_settings_manual;
        }
    }
    function f1_sel1_change()//при изменении минимальной темепратуры изменяем максимально допустимую температуру теплого пола
    {
            _f1_sel2_o1.innerHTML=parseInt(_f1_sel1.value)+1;
            _f1_sel2_o2.innerHTML=parseInt(_f1_sel1.value)+2;
    }
    function save_settings_tp(aa)//сохранение настроек теплого пола и передача настроек на контроллер
    {
 
        v_tp_settings_int=(_f1_sel1.value-23)<<2 | _f1_ch0.checked | (_f1_sel2.value<<5) | (_f1_ch1.checked<<6) | (tp_settings_manual<<1);//формируем значение настроек
        if (aa==1) v_tpk_settings_int=v_tp_settings_int; 
              else v_tpv_settings_int=v_tp_settings_int;
        $(function(){
            $.ajax({
                url: "get.php",
                cashe:false,
                type: "POST",
                data: ({n_t:"1",n_c:"1",tpk:v_tpk_settings_int, tpv:v_tpv_settings_int}),
             success: function(data){
                    json = $.parseJSON(data);
                    f_noparce_json=false;
                    parseJson();//обновляем страницу
                    _f1.style.display = 'none';
                    document.getElementById('tp_btn_v').style.display='block';      
                    document.getElementById('tp_btn_k').style.display='block';
                    setinterval_test();
                   }
              });
        }); 
 
    }
    function cancel_settings_tp()//кнопка отмены в настройках
    {
        _f1.style.display = 'none';
        document.getElementById('tp_btn_v').style.display='block';      
        document.getElementById('tp_btn_k').style.display='block';
        setinterval_test();
    }
    function set_tp(aa)//кнопка ручного управления теплым полом
    {   
        f_noparce_json=true;
        settings_tp(aa,0);
        if (aa==1) tp_settings_manual=!_f1_chk_manual.checked;
        if (aa==2) tp_settings_manual=!_f1_chv_manual.checked;
        save_settings_tp(aa);
 
    }
    </script>
 
    <div id="header">
        smart home
    </div>
        <div id="body2">
            <div id="systems">
                <div id="tp_title">Теплый пол</div>
                <div id="tp_current">
                        <table id="table_tp">
                        <tr>
                            <td class="name_s">Кухня:</td>
                            <td title="Текущая температура" id="tpk_temp" class="tp_temp"></td>
                            <td title="Заданная температура min-max" id="tpk_settings_temp_min_max" class="tp_temp_min_max"></td>
                            <td id="tpk_settings_auto" class="tp_temp_auto"></td>
                            <td id="tpk_settings_manual" class="tp_temp_manual"></td>
                            <td id="tpk_settings_night"></td>
                            <td title="Настроить" id="tpk_set_settings"><input id="tp_btn_k" class="tp_btn"  type="button" name="button1" onclick="settings_tp(1,1)" value="настроить"></td>
                            <td title="Контроль настроек" id="tpk_settings~"></td>  
                            <td>
                                    <label class="switch">
                                      <input  id="tpk_settings_manual_ch" type="checkbox" class="switch-input" onchange ="set_tp(1)">
                                      <span class="switch-label" data-on="вкл" data-off="выкл"></span>
                                      <span class="switch-handle"></span>
                                    </label>
                            </td>
                        </tr>
                        <tr>
                            <td class="name_s">Ванная:</td>
                            <td title="Текущая температура" id="tpv_temp" class="tp_temp"></td>
                            <td title="Заданная температура min-max" id="tpv_settings_temp_min_max" class="tp_temp_min_max"></td>
                            <td id="tpv_settings_auto"  class="tp_temp_auto"></td>
                            <td id="tpv_settings_manual" class="tp_temp_manual"></td>
                            <td id="tpv_settings_night"></td>
                            <td title="Настроить" id="tpv_set_settings"><input id="tp_btn_v" class="tp_btn" type="button" name="button2" onclick="settings_tp(2,1)" value="настроить"></td>
                            <td title="Контроль настроек" id="tpv_settings~"></td>
                            <td>
                                    <label class="switch">
                                      <input id="tpv_settings_manual_ch" type="checkbox" class="switch-input" onchange ="set_tp(2)">
                                      <span class="switch-label" data-on="вкл" data-off="выкл"></span>
                                      <span class="switch-handle"></span>
                                    </label>
                            </td>
                        </tr>
                        </table>
                        
 
                </div>
                <div id="f1">
                    <div id="tp_set_legend"></div>
                    <div id="tp_current_settings">
                        <div ><label class="c_point">Автоматический режим: <input class="c_point" id="f1_ch0" type="checkbox" name="checkbox0" ></label></div>
                        <div ><label class="c_point">Ночной режим: <input class="c_point" id="f1_ch1" type="checkbox" name="checkbox1" ></label></div>
                        <div>Температура min
                            <select onchange="f1_sel1_change()" id="f1_sel1" name="select1">
                                <option value="26">26</option>
                                <option value="27">27</option>
                                <option value="28">28</option>
                                <option value="29">29</option>                                          
                            </select>
                        </div>
                        <div>Температура max
                            <select id="f1_sel2" name="select2">
                                <option id="f1_sel2_o1" value="0"></option>
                                <option id="f1_sel2_o2" value="1"></option>                     
                            </select>
                        </div>
                        <div id="tp_settings_buttons" >
                            <input class="tp_btn"  type="button" name="f1_b1" value="Сохранить" onclick="save_settings_tp(npol)" title="Записать данные в контроллер">
                            <input class="tp_btn"  type="button" name="f1_b2" value="Отмена" onclick="cancel_settings_tp()" title="Отменить изменения">
                        </div>                  
                    </div>
                </div>
            </div>
 
        </div>
        <div id="both"></div>
    </div>
    </body></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span>
 <script type="text/javascript">
 var openstat = { counter: 2082534, next: openstat };
 (function(d, t, p) {
 var j = d.createElement(t); j.async = true; j.type = "text/javascript";
 j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js";
 var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s);
 })(document, "script", document.location.protocol);
 </script></div></div></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span> <script type="text/javascript"> var openstat = { counter: 2082534, next: openstat }; (function(d, t, p) { var j = d.createElement(t); j.async = true; j.type = "text/javascript"; j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js"; var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s); })(document, "script", document.location.protocol); </script></div></div></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span> <script type="text/javascript"> var openstat = { counter: 2082534, next: openstat }; (function(d, t, p) { var j = d.createElement(t); j.async = true; j.type = "text/javascript"; j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js"; var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s); })(document, "script", document.location.protocol); </script></div></div></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span> <script type="text/javascript"> var openstat = { counter: 2082534, next: openstat }; (function(d, t, p) { var j = d.createElement(t); j.async = true; j.type = "text/javascript"; j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js"; var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s); })(document, "script", document.location.protocol); </script></div></div>
</html>
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN" "www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
	<meta charset="UTF-8">
	<link href="css/style.css" type="text/css" rel="stylesheet">
	<link href="css/style_switch.css" type="text/css" rel="stylesheet">
	</head>

	<body>

	<script type="text/javascript" src="jquery.min.js"></script>

	<script>
	//общие переменные
	var
	json,//массив данных с контроллера
	npol,//номер теплого пола 1-кухня/2-ванная для формы f1
	tp_settings_manual,//настройки теплого пола для формы f1
	interval_test,//интервал для обновления данных на странице (интервал опроса датчиков)
	f_noparce_json;//флаг обновления данных на странице
	//нстройки контроллера 1
	var 
	v_tpk_settings, //настройки теплого пола кухни бинарное
	v_tpv_settings, //настройки теплого пола ванной бинарное
	v_tpk_settings_int, //настройки теплого пола кухни целое
	v_tpv_settings_int; //настройки теплого пола ванной целое
	//объекты на странице f1-теплый пол
	var 
	_f1, //форма настроек теплого пола
	_tp_set_legend,//заголовок настроек теплого пола
	_f1_ch0,//авто режим
	_f1_ch1,//ночной режим
	_f1_sel1,//темепратура мин
	_f1_sel2,//температура макс
	_f1_sel2_o1,//значение макс темепатуры 1
	_f1_sel2_o2,//значение макс темепатуры 2
	_f1_chk_manual,//ручное управление теплым полом кухни
	_f1_chv_manual;//ручное управление теплым полом ванной
	//////////////////	
	setTimeout(get_elem_byid,1);//поиск  элементов на странице
	setTimeout(test,10);//запрос данных с контрллера

	setinterval_test();//задаем таймер запроса данных с контроллеров
	
	function setinterval_test()//задаем таймер запроса данных с контроллеров
	{
		interval_test=setInterval(test, 3000);
	}
	function get_elem_byid()//поиск  элементов на странице
	{
			//поиск элементов для теплого пола
			_f1=document.getElementById('f1' );
			_tp_set_legend=document.getElementById('tp_set_legend' );
			_f1_ch0=document.getElementById('f1_ch0' );
			_f1_ch1=document.getElementById('f1_ch1' );
			_f1_sel1=document.getElementById("f1_sel1");
			_f1_sel2=document.getElementById("f1_sel2");
			_f1_sel2_o1=document.getElementById('f1_sel2_o1' );
			_f1_sel2_o2=document.getElementById('f1_sel2_o2' );
			_f1_chk_manual=document.getElementById('tpk_settings_manual_ch' );
			_f1_chv_manual=document.getElementById('tpv_settings_manual_ch' );
			////////

	}
	function test ()//запрос данных с контрллера
	{
		//if (f_test_stop)return;
		$(function(){
			$.ajax({
				url: "get.php",
				cashe:false,
				type: "POST",
				data: ({n_t:"0"}),
			 success: function(data){
					json = $.parseJSON(data);
					parseJson();//полученный массив данных json с контроллера раскидываем по странице

				   }
			  });
	});	
	}
	function parseJson()//полученный массив данных json с контроллера раскидываем по странице
	{			
					if (f_noparce_json) return;
					//теплый пол
					$("#tpk_temp").html(json.tpk_temp+"°С");//текущая температура теплого пола кухни
					$("#tpv_temp").html(json.tpv_temp+"°С");//текущая темепратура теплого пола ванной
					$("#tpk_settings").html(json.tpk_settings);//настройки теплого пола кухни
					v_tpk_settings=json.tpk_settings;
					v_tpk_settings_int=json.tpk_settings_int;
					
					$("#tpv_settings").html(json.tpv_settings);//настройки теплого пола ванной	
					v_tpv_settings=json.tpv_settings;
					v_tpv_settings_int=json.tpv_settings_int;
					
					if (json.tpk_settings_auto==1)//кухня - автоматический режим
					{
						$("#tpk_settings_auto").html("<div title=\"Автоматический режим\" id=\"tp_settings_auto_1\">A</div>");
						_f1_chk_manual.disabled = true;
						_f1_chk_manual.title="Отключите автоматический режим";
						
					} else { //кухня - ручной режим
						$("#tpk_settings_auto").html("<div title=\"Ручной режим\" id=\"tp_settings_auto_0\">M</div>");
						_f1_chk_manual.disabled = false;
						
					}
					if (json.tpv_settings_auto==1)//ванная - автоматический режим 
					{
						$("#tpv_settings_auto").html("<div  title=\"Автоматический режим\" id=\"tp_settings_auto_1\">A</div>");
						_f1_chv_manual.disabled = true;
						_f1_chv_manual.title="Отключите автоматический режим";
					} else {//ванная - ручной режим
						$("#tpv_settings_auto").html("<div title=\"Ручной режим\" id=\"tp_settings_auto_0\">M</div>");
						_f1_chv_manual.disabled = false;
					}	
					_f1_chv_manual.checked=!json.tpv_settings_manual;//флаг режима
					
					if (json.tpv_settings_manual==1)//ванная - состояние теплого пола вкл/выкл
					{
						$("#tpv_settings_manual").html("<div title=\"Охлаждение\" class=\"tp_off\"></div>")
					} else {
						$("#tpv_settings_manual").html("<div title=\"Нагрев\" class=\"tp_on\"></div>")
					}
					_f1_chk_manual.checked=!json.tpk_settings_manual;//флаг режима
					
					if (json.tpk_settings_manual==1)//кухня - состояние теплого пола вкл/выкл
					{
						$("#tpk_settings_manual").html("<div title=\"Охлаждение\" class=\"tp_off\"></div>")
					} else {
						$("#tpk_settings_manual").html("<div title=\"Нагрев\" class=\"tp_on\"></div>")
					}
					$("#tpk_settings_temp_min_max").html("("+(json.tpk_settings_temp_min)+"-"+(json.tpk_settings_temp_min+json.tpk_settings_temp_max+1)+")");//задданая темепратура теплого пола кухни
					$("#tpv_settings_temp_min_max").html("("+(json.tpv_settings_temp_min)+"-"+(json.tpv_settings_temp_min+json.tpv_settings_temp_max+1)+")");//задданая темепратура теплого пола ванной
					
	
					if (json.tpk_settings_night==1)//кухня - ночной режим
					{
						$("#tpk_settings_night").html("<div class=\"night2\"><div title=\"Ночной режим\" class=\"night\"></div></div>")
					}else{
						$("#tpk_settings_night").html("<div></div>")
					}
					if (json.tpv_settings_night==1)//ванная - ночной режим
					{
						$("#tpv_settings_night").html("<div class=\"night2\"><div title=\"Ночной режим\" class=\"night\"></div></div>")
					}else{
						$("#tpv_settings_night").html("<div></div>")
					} 

					

					//-теплый пол
	}
	
	function settings_tp(aa,f_show)//открыаем форму настроек и запалняем ее настройками
	{	

		if (interval_test) clearInterval(interval_test);
		npol=aa;
		if (aa==1)
		{	
			if (f_show) _f1.style.display = 'block';
			_tp_set_legend.innerHTML = 'Настройки теплого пола Кухни';
			_f1_ch0.checked = json.tpk_settings_auto;
			_f1_ch1.checked = json.tpk_settings_night;
			_f1_sel1.value = json.tpk_settings_temp_min;
			_f1_sel2.value = json.tpk_settings_temp_max;
			_f1_sel2_o1.innerHTML=json.tpk_settings_temp_min+1;
			_f1_sel2_o2.innerHTML=json.tpk_settings_temp_min+2;
			document.getElementById('tp_btn_k').style.display='none';		
			document.getElementById('tp_btn_v').style.display='block';
			tp_settings_manual=json.tpk_settings_manual;
		}
		if (aa==2)
		{
			if (f_show)_f1.style.display = 'block';
			_tp_set_legend.innerHTML = 'Настройки теплого пола Ванной';
			_f1_ch0.checked = json.tpv_settings_auto;
			_f1_ch1.checked = json.tpv_settings_night;
			_f1_sel1.value = json.tpv_settings_temp_min;
			_f1_sel2.value = json.tpv_settings_temp_max;
			_f1_sel2_o1.innerHTML=json.tpv_settings_temp_min+1;
			_f1_sel2_o2.innerHTML=json.tpv_settings_temp_min+2;	
			document.getElementById('tp_btn_v').style.display='none';		
			document.getElementById('tp_btn_k').style.display='block';
			tp_settings_manual=json.tpv_settings_manual;
		}
	}
	function f1_sel1_change()//при изменении минимальной темепратуры изменяем максимально допустимую температуру теплого пола
	{
			_f1_sel2_o1.innerHTML=parseInt(_f1_sel1.value)+1;
			_f1_sel2_o2.innerHTML=parseInt(_f1_sel1.value)+2;
	}
	function save_settings_tp(aa)//сохранение настроек теплого пола и передача настроек на контроллер
	{

		v_tp_settings_int=(_f1_sel1.value-23)<<2 | _f1_ch0.checked | (_f1_sel2.value<<5) | (_f1_ch1.checked<<6) | (tp_settings_manual<<1);//формируем значение настроек
		if (aa==1) v_tpk_settings_int=v_tp_settings_int; 
			  else v_tpv_settings_int=v_tp_settings_int;
		$(function(){
			$.ajax({
				url: "get.php",
				cashe:false,
				type: "POST",
				data: ({n_t:"1",n_c:"1",tpk:v_tpk_settings_int, tpv:v_tpv_settings_int}),
			 success: function(data){
					json = $.parseJSON(data);
					f_noparce_json=false;
					parseJson();//обновляем страницу
					_f1.style.display = 'none';
					document.getElementById('tp_btn_v').style.display='block';		
					document.getElementById('tp_btn_k').style.display='block';
					setinterval_test();
				   }
			  });
		});	

	}
	function cancel_settings_tp()//кнопка отмены в настройках
	{
		_f1.style.display = 'none';
		document.getElementById('tp_btn_v').style.display='block';		
		document.getElementById('tp_btn_k').style.display='block';
		setinterval_test();
	}
	function set_tp(aa)//кнопка ручного управления теплым полом
	{	
		f_noparce_json=true;
		settings_tp(aa,0);
		if (aa==1) tp_settings_manual=!_f1_chk_manual.checked;
		if (aa==2) tp_settings_manual=!_f1_chv_manual.checked;
		save_settings_tp(aa);

	}
	</script>

	<div id="header">
		smart home
	</div>
		<div id="body2">
			<div id="systems">
				<div id="tp_title">Теплый пол</div>
				<div id="tp_current">
						<table id="table_tp">
						<tr>
							<td class="name_s">Кухня:</td>
							<td title="Текущая температура" id="tpk_temp" class="tp_temp"></td>
							<td title="Заданная температура min-max" id="tpk_settings_temp_min_max" class="tp_temp_min_max"></td>
							<td id="tpk_settings_auto" class="tp_temp_auto"></td>
							<td id="tpk_settings_manual" class="tp_temp_manual"></td>
							<td id="tpk_settings_night"></td>
							<td title="Настроить" id="tpk_set_settings"><input id="tp_btn_k" class="tp_btn"  type="button" name="button1" onclick="settings_tp(1,1)" value="настроить"></td>
							<td title="Контроль настроек" id="tpk_settings~"></td>	
							<td>
								    <label class="switch">
									  <input  id="tpk_settings_manual_ch" type="checkbox" class="switch-input" onchange ="set_tp(1)">
									  <span class="switch-label" data-on="вкл" data-off="выкл"></span>
									  <span class="switch-handle"></span>
									</label>
							</td>
						</tr>
						<tr>
							<td class="name_s">Ванная:</td>
							<td title="Текущая температура" id="tpv_temp" class="tp_temp"></td>
							<td title="Заданная температура min-max" id="tpv_settings_temp_min_max" class="tp_temp_min_max"></td>
							<td id="tpv_settings_auto"  class="tp_temp_auto"></td>
							<td id="tpv_settings_manual" class="tp_temp_manual"></td>
							<td id="tpv_settings_night"></td>
							<td title="Настроить" id="tpv_set_settings"><input id="tp_btn_v" class="tp_btn" type="button" name="button2" onclick="settings_tp(2,1)" value="настроить"></td>
							<td title="Контроль настроек" id="tpv_settings~"></td>
							<td>
								    <label class="switch">
									  <input id="tpv_settings_manual_ch" type="checkbox" class="switch-input" onchange ="set_tp(2)">
									  <span class="switch-label" data-on="вкл" data-off="выкл"></span>
									  <span class="switch-handle"></span>
									</label>
							</td>
						</tr>
						</table>
						

				</div>
				<div id="f1">
					<div id="tp_set_legend"></div>
					<div id="tp_current_settings">
						<div ><label class="c_point">Автоматический режим: <input class="c_point" id="f1_ch0" type="checkbox" name="checkbox0" ></label></div>
						<div ><label class="c_point">Ночной режим: <input class="c_point" id="f1_ch1" type="checkbox" name="checkbox1" ></label></div>
						<div>Температура min
							<select onchange="f1_sel1_change()" id="f1_sel1" name="select1">
								<option value="26">26</option>
								<option value="27">27</option>
								<option value="28">28</option>
								<option value="29">29</option>											
							</select>
						</div>
						<div>Температура max
							<select id="f1_sel2" name="select2">
								<option id="f1_sel2_o1" value="0"></option>
								<option id="f1_sel2_o2" value="1"></option>						
							</select>
						</div>
						<div id="tp_settings_buttons" >
							<input class="tp_btn"  type="button" name="f1_b1" value="Сохранить" onclick="save_settings_tp(npol)" title="Записать данные в контроллер">
							<input class="tp_btn"  type="button" name="f1_b2" value="Отмена" onclick="cancel_settings_tp()" title="Отменить изменения">
						</div>					
					</div>
				</div>
			</div>

		</div>
		<div id="both"></div>
	</div>
	</body></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span>
 <script type="text/javascript">
 var openstat = { counter: 2082534, next: openstat };
 (function(d, t, p) {
 var j = d.createElement(t); j.async = true; j.type = "text/javascript";
 j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js";
 var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s);
 })(document, "script", document.location.protocol);
 </script></div></div></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span> <script type="text/javascript"> var openstat = { counter: 2082534, next: openstat }; (function(d, t, p) { var j = d.createElement(t); j.async = true; j.type = "text/javascript"; j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js"; var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s); })(document, "script", document.location.protocol); </script></div></div></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span> <script type="text/javascript"> var openstat = { counter: 2082534, next: openstat }; (function(d, t, p) { var j = d.createElement(t); j.async = true; j.type = "text/javascript"; j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js"; var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s); })(document, "script", document.location.protocol); </script></div></div></noscript><div style="text-align: center;"><div style="position:relative; top:0; margin-right:auto;margin-left:auto; z-index:99999"><span id="openstat2082534"></span> <script type="text/javascript"> var openstat = { counter: 2082534, next: openstat }; (function(d, t, p) { var j = d.createElement(t); j.async = true; j.type = "text/javascript"; j.src = ("https:" == p ? "https:" : "http:") + "//openstat.net/cnt.js"; var s = d.getElementsByTagName(t)[0]; s.parentNode.insertBefore(j, s); })(document, "script", document.location.protocol); </script></div></div>
</html>

Ну и на закуску видео

Загрузить все файлы проекта

2 комментс для “6 — Умный дом на Ардуино. Глава I — Теплый пол. Часть 2 — Управление и настройка через web.

  1. Ответить Anton_Kos87 Май 16, 2016 12:44

    не пробовали использовать W5100 и что бы ардуино был сам сервером PHP, что бы с любого устройства можно было открыть страничку не важно на телефоне или на компьютере?? я что то подобное хотел сделать у себя в загородном доме, управление скважиной, и септиком по интерфейсу что бы был обмен данными и настройками и нарисовать мнемосхему что там творится..

Добавить комментарий