Controlador de ar condicionado doméstico sem fio do OpenHAB via Modbus via RF24Network


Depois do meu primeiro artigo sobre como controlar o ar condicionado com um controlador, passaram-se pouco mais de 2 anos. Durante esse período, a idéia de controlar o ar condicionado remotamente não me deixou e teve vários renascimentos. A principal condição era a ausência de fios no ar condicionado.

Ou seja, o controle do controlador deve ser sem fio.

fundo


O primeiro protótipo foi o Arduino UNO. Ela aceitou equipes no UART e sabia como ligar e desligar o ar condicionado. Porque havia pouco senso prático do arduinka conectado ao computador de trabalho, a cabeça procurava constantemente a oportunidade de conectar o último ao servidor doméstico. Não havia visibilidade direta do servidor para o culpado de todos os quebra-cabeças. O máximo é um soquete com uma LAN no mesmo computador de trabalho - já que fica quase em frente ao ar condicionado. Um escudo Ethernet não estava disponível. Mas lembrando que em algum lugar do zashashnik existe um modem DSL-2500U dsl d-link que não é usado há muito tempo, com apenas uma porta a bordo. O desejo de dar uma segunda vida ao pedaço de ferro levou à pesquisa, que, por sua vez, miraculosamente levou ao artigo Transformando um modem ADSL em um escudo Ethernet para o Arduino / CraftDuino .

Avançando e pulando o interessante processo de criação de firmware personalizado, ainda consegui fazer o modem escutar na porta desejada e "encaminhar" o UART através dele. Assim, no servidor doméstico, eu poderia enviar um comando para ativar / desativar a porta para o endereço do modem local, que irá para o arduino conectado a ela.

Mas este artigo não é sobre isso. A solução definitiva usa o protocolo Modbus e a rede sem fio RF24Network . E tudo é controlado no OpenHAB.


Durante esses dois anos, consegui encomendar muitos de todos os nishtyaks da China e a maioria deles estava esperando nos bastidores. Esta lista incluía o módulo NRF24L01 +, comprado por um punhado para experimentação. E ele teria ido mais longe em algum lugar do armário ocioso, se um dia eu não tivesse encontrado uma série de artigos:

de BorichObrigado por isso!

Graças a eles, me familiarizei com o protocolo Modbus. Mas o mais importante, eu descobri o OpenHAB para mim - o que venho procurando há muito tempo. Isso me levou a começar a implementar idéias de longa data.

Tendo brincado com exemplos dos artigos, decidi tentar separar o controlador e o servidor usando a blindagem Ethernet do modem descrito acima. Essa solução nos permitiu realizar a tarefa proposta - o escudo e o controlador estavam localizados na área de trabalho, sem usar um computador em funcionamento, ao mesmo tempo, o escudo está sempre conectado à rede local e acessível a partir do servidor doméstico.

Mas essa decisão estava fadada ao fracasso.
ModbusRtu over TCP . modpoll, Arduino & Modbus . — 192.168.1.110 3000 !

OpenHAB. , , Modbus Binding «RTU over TCP». — ModbusRtu c TCP. OpenHAB-(ethernet)--(UART)-.

, ? Item . 1 Item . — . , , TCP Modbus Binding. .. .

Modbus Binding Item' host-port-slaveID .

, . . , .


Idéia


E então finalmente me estabeleci que precisava criar um controlador acessível por via aérea. Os módulos NRF24L01 + não devem desaparecer! .. É verdade que isso requer pelo menos dois controladores - um desempenha um papel direto, o segundo desempenha o papel de um roteador. O segundo deve estar conectado ao servidor e é através dele que é realizada a comunicação sem fio com os outros. Ao conectar-se a ele, especificamos o ID do subordinado a quem o pacote se destina. Acontece que muitos escravos estão disponíveis em uma porta serial. Sim - esta é uma rede sem fio baseada em Modbus.

O Modbus, aliás, permitiu que um mestre construísse uma rede - muitos subordinados. E a biblioteca RF24Network - para tornar tudo sem fio e até com roteamento automático entre nós da rede.

Desenvolvimento de bibliotecas para Arduino


Para implementar essa solução, demorou um pouco para modificar a biblioteca Modbus-Master-Slave-for-Arduino para poder herdar dela e sobrecarregar alguns métodos. Minha implementação também é atualizada (library.properties é adicionada, o arquivo da biblioteca é dividido em cabeçalho e corpo) para o Arduino IDE 1.6.5 mais recente.

A biblioteca Modbus-over-RF24Network-for-Arduino permite implementar dois comportamentos possíveis - Proxy e Escravo. Exemplo O ModbusRF24Proxy é na verdade uma implementação de um “roteador” e não requer outras modificações além da configuração dos pinos necessários.
Exemplo de ModbusRF24Proxy
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <ModbusRtu.h>
#include <ModbusRtuRF24.h>

#define stlPin  13  //     (   Arduino)

// nRF24L01(+) radio attached using Getting Started board 
RF24 radio(9, 10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 0;

//  ,   TX
ModbusRF24 proxy(network, 0, 0);
int8_t state = 0;
unsigned long tempus;

void setup() {
    //    
    io_setup();
    //    

    proxy.begin(57600);

    SPI.begin();
    radio.begin();
    network.begin(/*channel*/ 90, /*node address*/ this_node);

    //    100 
    tempus = millis() + 100;
    digitalWrite(stlPin, HIGH);
}

void io_setup() {
    digitalWrite(stlPin, HIGH);
    pinMode(stlPin, OUTPUT);
}

void loop() {

    // Pump the network regularly
    network.update();

    //  
    state = proxy.proxy();

    //      -    50  
    if (state > 4) {
        tempus = millis() + 50;
        digitalWrite(stlPin, HIGH);
    }
    if (millis() > tempus) digitalWrite(stlPin, LOW);
}


Um roteador ou proxy usa um formato especial de construtor:
//  ,   TX
ModbusRF24 proxy(network, 0, 0);

e função
proxy.proxy();

para processar pacotes recebidos na porta serial, envie-os para a RF24Network, receba uma resposta da rede, envie o resultado de volta para a porta serial.

Nesta implementação, o proxy tem um endereço RF24Network zero:
// Address of our node
const uint16_t this_node = 0;

- ou seja, este é o dispositivo raiz da rede. Se necessário, a posição na topologia do controlador proxy pode ser alterada.

Exemplo de Modbus RF24Slave
Arduino & Modbus:
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <ModbusRtu.h>
#include <ModbusRtuRF24.h>

#define ID   1      //  
#define btnPin  2   //  ,   
#define ledPin  7  //   

// nRF24L01(+) radio attached using Getting Started board 
RF24 radio(9, 10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = ID;

//  
ModbusRF24 slave(network, ID);

//   modbus
uint16_t au16data[11];

void io_setup() {
    digitalWrite(ledPin, LOW);
    pinMode(ledPin, OUTPUT);
    pinMode(btnPin, INPUT);
}

void io_poll() {
    // Coil[1]  Discrete[0]
    au16data[0] = au16data[1];
    //   1.3   
    digitalWrite(ledPin, bitRead(au16data[1], 3));
    //     0.3
    bitWrite(au16data[0], 3, digitalRead(btnPin));
    // Holding[5,6,7]  Input[2,3,4]
    au16data[2] = au16data[5];
    au16data[3] = au16data[6];
    au16data[4] = au16data[7];
    //    
    au16data[8] = slave.getInCnt();
    au16data[9] = slave.getOutCnt();
    au16data[10] = slave.getErrCnt();
}

void setup() {
    //    
    io_setup();

    Serial.begin(57600);
    Serial.println("RF24Network/examples/modbus_slave/");

    SPI.begin();
    radio.begin();
    network.begin(/*channel*/ 90, /*node address*/ this_node);
}

void loop() {

    // Pump the network regularly
    network.update();

    if (network.available()) {
        slave.poll(au16data, 11);
    }
    //    Modbus    
    io_poll();
}



O construtor neste caso já é diferente:
//  
ModbusRF24 slave(network, ID);


Estrutura de Registro Modbus


Após as primeiras tentativas bem-sucedidas de controlar o ar condicionado, a capacidade de ligar e desligar apenas meu apetite aumentou. Agora isso já não era suficiente e, como tenho a funcionalidade OpenHAB no meu aplicativo móvel, ele deve fazer no mínimo toda a funcionalidade do painel de controle nativo.
Isso significa que aqui está uma lista de recursos pelo menos:
  • indicação de status atual
  • ligar e desligar o ar condicionado, modos individuais (O 2 , ionização, modo silencioso);
  • seleção do modo atual (automático, aquecimento, refrigeração, drenagem, ventilador);
  • indicação de temperatura e velocidade do ventilador para cada modo. Para o modo de ventilador, apenas velocidade;
  • ajuste da cortina vertical (automático, 0 °, 15 °, 30 °, 45 °, 60 °);
  • configuração de cortina horizontal (automático, "| |", "/ /", "/ |", "| \", "\ \");
  • ajuste de hora (hora, minuto);
  • na configuração do temporizador;
  • configuração de desligamento do timer;
  • configuração no horário (hora, minuto);
  • configuração do tempo de desligamento (hora, minuto);

Durante o processo de desenvolvimento, a estrutura dos registros mudou muitas vezes comigo. A versão atual está abaixo do spoiler.
Registradores Modbus
TypeByteBitName
Bit RO00CFG_OXYGEN1 —
Bit RO1CFG_ION1 —
Bit RO2CFG_QUIET1 —
Bit RO3CFG_TIMER1 — /
Bit RO4CFG_DELAY1 — /
Bit RO5CFG_SWING1 —
Bit RO6CFG_SWINGH1 —
Bit RO7CFG_SWINGV1 —
Bit RO8CFG_CLOCK1 —
Bit RO9
Bit RO10
Bit RO11CFG_AUTO1 — AUTO
Bit RO12CFG_COOL1 — COOL
Bit RO13CFG_HEAT1 — HEAT
Bit RO14CFG_DRY1 — DRY
Bit RO15CFG_FAN1 — FAN
Integer RO1CFG_TEMP. . : Min + Max*256
Integer RO2CFG_FAN_SPEEDFAN
Bit RO30STATE_POWER:0 — , 1 —
Bit RO1STATE_OXYGEN:0 — , 1 —
Bit RO2STATE_ION:0 — , 1 —
Bit RO3STATE_QUIET:0 — , 1 —
Bit RO4STATE_TIMER:0 — , 1 —
Bit RW8CONTROL_POWER
Bit RW9CONTROL_OXYGEN
Bit RW10CONTROL_ION
Bit RW11CONTROL_QUIET
Integer RO4RTC_HR_MI0x1308
Integer RW5RTCW_HR_MI0x1308
Integer RO6TEMPERATURE1. INT16,
Integer RO7TEMPERATURE2. INT16,
Bit RW80MODE_AUTO
Bit RW1MODE_COOL
Bit RW2MODE_HEAT
Bit RW3MODE_DRY
Bit RW4MODE_FAN
Integer RW9TEMP_AUTOAUTO
Integer RW10TEMP_COOLCOOL
Integer RW11TEMP_HEATHEAT
Integer RW12TEMP_DRYDRY
Integer RW13FAN_AUTOAUTO. 0: Auto
Integer RW14FAN_COOLCOOL. 0: Auto
Integer RW15FAN_HEATHEAT. 0: Auto
Integer RW16FAN_DRYDRY. 0: Auto
Integer RW17FAN_SPEEDFAN. 0: Auto
Bit RW180SWING_AUTO
Bit RW1SWINGV_0
Bit RW2SWINGV_1515°
Bit RW3SWINGV_3030°
Bit RW4SWINGV_4545°
Bit RW5SWINGV_6060°
Bit RW190SWINGH_AUTO
Bit RW1SWINGH_VV|  |
Bit RW2SWINGH_LL/  /
Bit RW3SWINGH_LV/  |
Bit RW4SWINGH_VR|  \
Bit RW5SWINGH_RR\  \
Bit RW200TIMER_ON
Bit RW1TIMER_OFF
Integer RW21TIME_ON_HOUR
Integer RW22TIME_ON_MINUTE
Integer RW23TIME_OFF_HOUR
Integer RW24TIME_OFF_MINUTE
Integer RW25DS18B20_ENV.
Integer RW26DS18B20_NOZ.


Os registradores são organizados de tal maneira que toda a matriz de dados é inicializada na EEPROM quando o controlador é iniciado.
Os três primeiros registros (CFG_ *) contêm a configuração dos recursos, nunca mudam e são inicializados pelo firmware da EEPROM.
Os registros 3-7 sempre exibem o estado atual do controlador. Os bits altos do registro 3 são usados ​​para mudar de estado. Suas alterações iniciam a ativação / desativação do ar condicionado e modos especiais. Depois que o comando é executado, os bits de baixa ordem deste registrador são copiados para os de alta ordem.
O registro 4 contém o tempo atual do controlador, que é lido no RTC. O valor é salvo no formato BCD, de modo que, quando o registro é exibido em notação hexadecimal, a hora é lida como está - 12:34 é 0x1234.
O registro 5 é usado para alterar o horário do RTC.
Os registros 6-7 contêm a temperatura dos sensores DS18B20. O valor contém um número inteiro assinado e é igual a T * 100, ou seja, 25,67 ° C = 2567. É fornecido um máximo de 2 sensores, mas o número pode ser facilmente alterado expandindo a tabela de registros para armazenar os endereços dos sensores e suas temperaturas.
Os últimos 2 bytes do endereço do sensor são armazenados nos registros 25-26. Ao trocar de sensor, redefina o registro de endereço correspondente. Quando um novo sensor é detectado, seu endereço é verificado quanto à presença nos registros 25-26. Se o endereço estiver na tabela, o valor da temperatura do sensor é inserido no registro correspondente 6-7. Se o endereço não estiver na tabela e a tabela tiver zero células, o endereço atual do sensor será gravado em uma célula livre.
Os registros 8 a 26, quando modificados pelo usuário, são salvos na EEPROM.

Glândulas


O hardware consiste nos seguintes componentes:
  1. Arduino Pro Mini.
    Arduino Pro Mini NEW
  2. NRF24L01+ — 2.4
  3. LM1117-3.3 — 3.3 NRF24L01+
  4. DS1302 — RTC
  5. 32768 RTC
  6. DS18B20 — . 2
  7. — , ,











O feedback com o ar condicionado é realizado conectando os acopladores ópticos aos LEDs correspondentes. Assim, é garantido o isolamento galvânico com o circuito elétrico do ar condicionado. A corrente das entradas para os acopladores ópticos foi selecionada experimentalmente usando resistores, para que a saída do acoplador óptico se abra e o brilho do LED principal no ar condicionado não diminua.

Um LED de infravermelho foi instalado próximo ao receptor de infravermelho do ar condicionado.

O controlador é alimentado por carregamento mini-USB de algum tipo de milagre chinês. Os contatos de tensão da rede chinesa foram removidos do estojo de carregamento e os fios foram removidos. O carregamento se instalou nas entranhas do gabinete do ar-condicionado, conectado à entrada 220 em paralelo. O controlador se conecta ao carregamento com um cabo USB AB comum.

O controlador "roteador" é baseado no Arduino Mega2560 e NRF24L01 + com um LM1117-3.3 separado. Além de uma fonte de alimentação 3.3 separada, um eletrólito é conectado ao módulo sem fio (eu o encontrei em 470uf * 16v) ​​nas pernas de energia. Como você sabe, o barramento de energia interno Mega2560 3.3V é muito barulhento e o módulo se recusou a transmitir dados, embora tenha respondido corretamente. Mas mesmo com uma fonte de alimentação separada sem capacitor, a conexão era muito instável.
Para que o mega2560 não seja redefinido ao abrir a porta via USB, um eletrólito de 10μf é conectado ao pino de redefinição.

Openhab


O artigo Arduino e OpenHAB descreve um recurso do plug-in Modbus Binding, que a cada pesquisa do controlador, o plug-in envia um evento ao barramento, mesmo que nada tenha mudado. Eu segui o exemplo e finalizei o plugin.

Configuração do plugin de ligação Modbus
#
modbus:serial.ac_hall_state.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_state.id=1
modbus:serial.ac_hall_state.start=48
modbus:serial.ac_hall_state.length=5
modbus:serial.ac_hall_state.type=discrete

#
modbus:serial.ac_hall_power.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_power.id=1
modbus:serial.ac_hall_power.start=56
modbus:serial.ac_hall_power.length=4
modbus:serial.ac_hall_power.type=coil

#
modbus:serial.ac_hall_rtc.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_rtc.id=1
modbus:serial.ac_hall_rtc.start=4
modbus:serial.ac_hall_rtc.length=1
modbus:serial.ac_hall_rtc.type=holding

#
modbus:serial.ac_hall_temperature.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_temperature.id=1
modbus:serial.ac_hall_temperature.start=6
modbus:serial.ac_hall_temperature.length=2
modbus:serial.ac_hall_temperature.type=holding
modbus:serial.ac_hall_temperature.valuetype=int16

#
modbus:serial.ac_hall_mode.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_mode.id=1
modbus:serial.ac_hall_mode.start=8
modbus:serial.ac_hall_mode.length=1
modbus:serial.ac_hall_mode.type=holding

#
modbus:serial.ac_hall_temp.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_temp.id=1
modbus:serial.ac_hall_temp.start=9
modbus:serial.ac_hall_temp.length=4
modbus:serial.ac_hall_temp.type=holding

#
modbus:serial.ac_hall_fan.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_fan.id=1
modbus:serial.ac_hall_fan.start=13
modbus:serial.ac_hall_fan.length=5
modbus:serial.ac_hall_fan.type=holding

#
modbus:serial.ac_hall_swing.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_swing.id=1
modbus:serial.ac_hall_swing.start=18
modbus:serial.ac_hall_swing.length=2
modbus:serial.ac_hall_swing.type=holding

#
modbus:serial.ac_hall_timer.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_timer.id=1
modbus:serial.ac_hall_timer.start=320
modbus:serial.ac_hall_timer.length=2
modbus:serial.ac_hall_timer.type=coil

#
modbus:serial.ac_hall_timer_time.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_timer_time.id=1
modbus:serial.ac_hall_timer_time.start=21
modbus:serial.ac_hall_timer_time.length=4
modbus:serial.ac_hall_timer_time.type=holding

# DS18B20
modbus:serial.ac_hall_ds18b20.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_ds18b20.id=1
modbus:serial.ac_hall_ds18b20.start=25
modbus:serial.ac_hall_ds18b20.length=2
modbus:serial.ac_hall_ds18b20.type=holding

Configurações de itens
Contact AC_HALL_STATE_POWER             "AC_HALL_STATE_POWER [MAP(air_cond.map):%s]"    (){modbus="ac_hall_state:0"}
Contact AC_HALL_STATE_OXYGEN            "AC_HALL_STATE_OXYGEN [MAP(air_cond.map):%s]"   (){modbus="ac_hall_state:1"}
Contact AC_HALL_STATE_ION               "AC_HALL_STATE_ION [MAP(air_cond.map):%s]"      (){modbus="ac_hall_state:2"}
Contact AC_HALL_STATE_QUIET             "AC_HALL_STATE_QUIET [MAP(air_cond.map):%s]"    (){modbus="ac_hall_state:3"}
Contact AC_HALL_STATE_TIMER             "[MAP(air_cond.map):%s]"                  (){modbus="ac_hall_state:4"}

Switch  AC_HALL_CONTROL_POWER           ""                   <climate>       (){modbus="ac_hall_power:0"}
Switch  AC_HALL_CONTROL_OXYGEN          " O2"                                  (){modbus="ac_hall_power:1"}
Switch  AC_HALL_CONTROL_ION             ""                                     (){modbus="ac_hall_power:2"}
Switch  AC_HALL_CONTROL_QUIET           " "                                   (){modbus="ac_hall_power:3"}

Number  AC_HALL_RTC                     "RTC[%x]"                                       (){modbus="ac_hall_rtc:0"}
String  AC_HALL_RTC_S                   " [%s]"         <clock>         ()

Group   gAC_HALL_TEMPERATURE            "Living Room temp"

Number  AC_HALL_TEMPERATURE_ENV         "[%d]"                                   (){modbus="ac_hall_temperature:0"}
Number  AC_HALL_TEMPERATURE_NOZ         "[%d]"                                     (){modbus="ac_hall_temperature:1"}
Number  AC_HALL_TEMPERATURE_ENVF        " [%.2f °C]"     <temperature>           (gAC_HALL_TEMPERATURE)
Number  AC_HALL_TEMPERATURE_NOZF        " [%.2f °C]"       <temperature>           (gAC_HALL_TEMPERATURE)

Number  AC_HALL_DS18B20_ENV             "ENV[%x]"                                       (){modbus="ac_hall_ds18b20:0"}
Number  AC_HALL_DS18B20_NOZ             "NOZZLES[%x]"                                   (){modbus="ac_hall_ds18b20:1"}

Number  AC_HALL_MODE                    ""                                              (){modbus="ac_hall_mode:0"}

Number  AC_HALL_TEMP_AUTO               "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:0"}
Number  AC_HALL_TEMP_COOL               "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:1"}
Number  AC_HALL_TEMP_HEAT               "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:2"}
Number  AC_HALL_TEMP_DRY                "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:3"}

Number  AC_HALL_FAN_AUTO                "[%d]"                                  (){modbus="ac_hall_fan:0"}
Number  AC_HALL_FAN_COOL                "[%d]"                                  (){modbus="ac_hall_fan:1"}
Number  AC_HALL_FAN_HEAT                "[%d]"                                  (){modbus="ac_hall_fan:2"}
Number  AC_HALL_FAN_DRY                 "[%d]"                                  (){modbus="ac_hall_fan:3"}
Number  AC_HALL_FAN_SPEED               "[%d]"                                  (){modbus="ac_hall_fan:4"}

Number  AC_HALL_SWINGV                  ""                                              (){modbus="ac_hall_swing:0"}
Number  AC_HALL_SWINGH                  ""                                              (){modbus="ac_hall_swing:1"}

Switch  AC_HALL_TIMER_ON                " "              <clock>         (){modbus="ac_hall_timer:0"}
Switch  AC_HALL_TIMER_OFF               " "             <clock>         (){modbus="ac_hall_timer:1"}

Number  AC_HALL_TIME_ON_HR              "[%02d]"                                     (){modbus="ac_hall_timer_time:0"}
Number  AC_HALL_TIME_ON_MI              "[%02d]"                                  (){modbus="ac_hall_timer_time:1"}
Number  AC_HALL_TIME_OFF_HR             "[%02d]"                                     (){modbus="ac_hall_timer_time:2"}
Number  AC_HALL_TIME_OFF_MI             "[%02d]"                                  (){modbus="ac_hall_timer_time:3"}


As regras são usadas para converter temperaturas inteiras em reais, bem como para formatar o tempo do controlador no formato HH: MM.
Configurações de regras
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import java.io.File

rule "Update AC_HALL ENV temp"
        when
                Item AC_HALL_TEMPERATURE_ENV received update
        then
                var Number T = AC_HALL_TEMPERATURE_ENV.state as DecimalType
                var Number H = T/100
                postUpdate(AC_HALL_TEMPERATURE_ENVF, H)
end
rule "Update AC_HALL NOZZLES temp"
        when
                Item AC_HALL_TEMPERATURE_NOZ received update
        then
                var Number T = AC_HALL_TEMPERATURE_NOZ.state as DecimalType
                var Number H = T/100
                postUpdate(AC_HALL_TEMPERATURE_NOZF, H)
end
rule "Update AC_HALL_RTC clock"
        when
                Item AC_HALL_RTC received update
        then
                var Number T = AC_HALL_RTC.state as DecimalType
                var H = T.intValue / 256
                var M = T.intValue % 256
                var S = String::format("%02x:%02x",H,M)
                postUpdate(AC_HALL_RTC_S, S)
end


Configurações de Sitemaps
sitemap demo label="Demo House"{
        Frame label="HOME"{
                Text label=" " icon="ac_cond"{
                        Frame label="" {
                                Switch item= AC_HALL_CONTROL_POWER labelcolor=[AC_HALL_STATE_POWER==OPEN="blue"]
                                Switch item= AC_HALL_CONTROL_OXYGEN labelcolor=[AC_HALL_STATE_OXYGEN==OPEN="blue"]
                                Switch item= AC_HALL_CONTROL_ION labelcolor=[AC_HALL_STATE_ION==OPEN="blue"]
                                Switch item= AC_HALL_CONTROL_QUIET labelcolor=[AC_HALL_STATE_QUIET==OPEN="blue"]
                                Text item=AC_HALL_STATE_TIMER labelcolor=[AC_HALL_STATE_TIMER==OPEN="blue"] icon="clock-on"
                                Text item=AC_HALL_RTC_S
                                Text item=AC_HALL_TEMPERATURE_ENVF
                                Text item=AC_HALL_TEMPERATURE_NOZF
                        }

                        Frame label=""{
                                Selection item=AC_HALL_MODE label="" mappings=[1=AUTO, 2=COOL, 4=HEAT, 8=DRY, 16=FAN]
                                Text item=AC_HALL_TEMP_AUTO visibility=[AC_HALL_MODE==1]
                                Text item=AC_HALL_TEMP_COOL visibility=[AC_HALL_MODE==2]
                                Text item=AC_HALL_TEMP_HEAT visibility=[AC_HALL_MODE==4]
                                Text item=AC_HALL_TEMP_DRY visibility=[AC_HALL_MODE==8]

                                Text item=AC_HALL_FAN_AUTO visibility=[AC_HALL_MODE==1]
                                Text item=AC_HALL_FAN_COOL visibility=[AC_HALL_MODE==2]
                                Text item=AC_HALL_FAN_HEAT visibility=[AC_HALL_MODE==4]
                                Text item=AC_HALL_FAN_DRY visibility=[AC_HALL_MODE==8]
                                Text item=AC_HALL_FAN_SPEED visibility=[AC_HALL_MODE==16]

                                Selection item=AC_HALL_SWINGV label="" mappings=[1=AUTO, 2="0°", 4="15°", 8="30°", 16="45°", 32="60°"]
                                Selection item=AC_HALL_SWINGH label="" mappings=[1=AUTO, 4="/   /", 8="/   |", 2="|   |", 16="|   \\", 32="\\   \\"]

                                Text label="" icon="settings"{
                                        Frame label="AUTO"{
                                                Setpoint item=AC_HALL_TEMP_AUTO minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_AUTO mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="COOL"{
                                                Setpoint item=AC_HALL_TEMP_COOL minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_COOL mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="HEAT"{
                                                Setpoint item=AC_HALL_TEMP_HEAT minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_HEAT mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="DRY"{
                                                Setpoint item=AC_HALL_TEMP_DRY minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_DRY mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="FAN"{
                                                Switch item=AC_HALL_FAN_SPEED mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label=""{
                                                Text item=AC_HALL_DS18B20_ENV
                                                Text item=AC_HALL_DS18B20_NOZ
                                        }
                                }
                        }
                        Frame label="" {
                                Switch item= AC_HALL_TIMER_ON labelcolor=[AC_HALL_STATE_TIMER==OPEN="blue"]
                                Setpoint item=AC_HALL_TIME_ON_HR minValue=0 maxValue=23 step=1
                                Setpoint item=AC_HALL_TIME_ON_MI minValue=0 maxValue=50 step=5

                                Switch item= AC_HALL_TIMER_OFF labelcolor=[AC_HALL_STATE_TIMER==OPEN="blue"]
                                Setpoint item=AC_HALL_TIME_OFF_HR minValue=0 maxValue=23 step=1
                                Setpoint item=AC_HALL_TIME_OFF_MI minValue=0 maxValue=50 step=5
                        }
                }
                Text item=AC_HALL_RTC_S
                Text item=AC_HALL_TEMPERATURE_ENVF{
                        Frame label=" "{
                                Chart item=gAC_HALL_TEMPERATURE period=h refresh=60000
                        }
                        Frame label=" 4 " {
                                Chart item=gAC_HALL_TEMPERATURE period=4h refresh=600000
                        }
                }
        }
}



O resultado é mais ou menos assim através de um navegador:

Conclusão


Estou satisfeito com o resultado como um elefante. O controle do ar condicionado está agora disponível para mim onde quer que haja Internet móvel ou Wi-Fi. Usando um cliente VPN em um smartphone, o OpenHAB no meu servidor doméstico se torna acessível para mim por meio de um navegador e de um aplicativo móvel.
A solução sem fio tornou possível integrar estreitamente o controlador ao ar condicionado.
A presença de feedback garante que o comando enviado foi recebido pelo ar condicionado e os sensores de temperatura demonstram isso claramente - após alguns segundos, é possível observar uma alteração na leitura da temperatura na saída do ar condicionado. Bem, depois de alguns minutos - e a temperatura ambiente.
Foi interessante observar o perfil do ar condicionado ao se aproximar das condições dadas.

Sem dúvida, este não será o único controlador sem fio que pretendo usar.

Há planos de usar o receptor de infravermelho do próprio ar condicionado para ler os comandos do controle remoto nativo para atualizar as configurações no controlador. Além disso, o próprio receptor de infravermelho já está conectado por meio de um acoplador óptico ao controlador.

Leia até o final um agradecimento especial!

Referências


  1. Biblioteca Arduino ModbusRtu Modbus-Master-Slave-for-Arduino
  2. Biblioteca Arduino ModbusRtuRF24 Rede Modbus-over-RF24 para Arduino

Source: https://habr.com/ru/post/pt384243/


All Articles