Índice:

Complemento do operador de porta controlada do WebApp (IoT): 20 etapas (com imagens)
Complemento do operador de porta controlada do WebApp (IoT): 20 etapas (com imagens)

Vídeo: Complemento do operador de porta controlada do WebApp (IoT): 20 etapas (com imagens)

Vídeo: Complemento do operador de porta controlada do WebApp (IoT): 20 etapas (com imagens)
Vídeo: Developer Keynote: Get to the Fun Part (Cloud Next '19) 2024, Julho
Anonim
Complemento do operador de porta controlada do WebApp (IoT)
Complemento do operador de porta controlada do WebApp (IoT)
Complemento do operador de porta controlada do WebApp (IoT)
Complemento do operador de porta controlada do WebApp (IoT)
Complemento do operador de porta controlada do WebApp (IoT)
Complemento do operador de porta controlada do WebApp (IoT)

Tenho um cliente que tinha uma área fechada onde muitas pessoas precisavam entrar e sair. Eles não queriam usar um teclado externo e tinham apenas um número limitado de transmissores de chaveiro. Encontrar uma fonte acessível para keyfobs adicionais foi difícil. Achei que seria uma grande oportunidade de atualizar este operador de porta Liftmaster para ser compatível com IoT com hardware personalizado, API da web e interface de aplicativo da web. Isso não apenas resolveu o problema de acesso em massa, mas também abriu funcionalidades adicionais!

Na última foto acima está a unidade de teste que eu usei por quase um ano em uma bolsa ziplock. Achei que era hora de um upgrade!

Esta é uma solução totalmente funcional com todo o código, informações de hardware e designs listados aqui.

Todos os arquivos de projetos também estão hospedados no GitHub: github.com/ThingEngineer/IoT-Gate-Operator-Addon

Um exemplo da interface CodeIgniter WebApp está hospedado aqui: projects.ajillion.com/gate Esta instância não está conectada a um portal ativo, mas é a interface exata e o código que está sendo executado nos portões (sem alguns recursos de segurança).

--

Para uma integração ainda maior, você pode usar a biblioteca IFTTT para Electric Imp.

Etapa 1: Reúna as peças

Reúna as peças
Reúna as peças
  • Você precisará de um IMP elétrico com pelo menos 4 GPIOs disponíveis. Estou usando o IMP001 com uma placa auxiliar de abril.
  • Um regulador para reduzir a tensão da fonte para 5V. Estou usando um módulo de redução do conversor DC-DC Buck. Versão MP1584EN do eBoot da Amazon.
  • Um módulo de relé duplo (ou mais) ou dispositivo de comutação semelhante que funcionará com a saída IMPs. Estou usando este módulo de relé JBtek 4 Channel DC 5V da Amazon.
  • Um terminal de parafuso de 4 fios. Estou usando este 5pcs 2 linhas 12P Wire Conector parafuso Terminal Barrier Block 300V 20A da Amazon.

Etapa 2: suprimentos

Suprimentos
Suprimentos

Você também precisará de:

  • Acesso a uma impressora 3D ou uma pequena caixa de projeto
  • 4 pequenos parafusos de cerca de 4 mm x 6 mm para a tampa da caixa
  • Fio de conexão
  • Cortadores de arame
  • Decapantes de arame
  • Chaves de fenda pequenas
  • Ferro de solda
  • Cola quente ou silicone
  • Gravatas zip

Etapa 3: dimensionar a caixa

Dimensione o caso
Dimensione o caso

Faça o layout de suas peças para determinar o tamanho da caixa de que você precisará. Com o layout da foto, vou precisar de uma caixa com cerca de 140 mm de largura, 70 mm de profundidade e 30 mm de altura.

Etapa 4: Fio Conversor DC-DC

Conversor de fio DC-DC
Conversor de fio DC-DC

Corte 3 pares de fio vermelho e preto para conexões de energia dentro e fora da placa conversora DC-DC.

  • Entrada: 100mm
  • Saída para IMP: 90 mm
  • Saída para Módulo de Relé: 130 mm

Solde-os em sua placa conforme mostrado.

Etapa 5: conecte a alimentação aos dispositivos

Ligue a energia aos dispositivos
Ligue a energia aos dispositivos
  • Conecte a entrada do conversor DC-DC a dois dos pontos no bloco de terminais de parafuso.
  • Solde os fios curtos de saída de 5 V ao IMP.
  • Solde os fios de saída de 5 V mais longos ao módulo de relé.

Etapa 6: Entradas do módulo de relé de fiação

Entradas do Módulo de Relé de Fio
Entradas do Módulo de Relé de Fio
  • Corte 4 fios de 90 mm para as conexões de entrada do módulo de relé. Usei 4 cores separadas para fácil referência mais tarde durante a codificação.
  • Solde os fios nas entradas do módulo de relé 1-4 e, em seguida, nos primeiros 4 pontos IMP GPIO (Pino 1, 2, 5 e 7), respectivamente.

Etapa 7: IMP Power Jumper

IMP Power Jumper
IMP Power Jumper

Pode ser necessário usar a alimentação USB durante a programação e o teste inicial do IMP. Quando terminar, certifique-se de mover o jumper de alimentação para o lado BAT.

Etapa 8: Entradas de status da porta de fiação

Entradas de status da porta de fiação
Entradas de status da porta de fiação
  • Corte 2 fios de 80 mm para as entradas de status de estado.
  • Conecte os fios aos 2 terminais de parafuso restantes.
  • Solde os fios para o próximo aos pontos IMP GPIO (Pin8 e 9), respectivamente.

Etapa 9: imprimir ou comprar uma caixa

Imprimir ou comprar uma caixa
Imprimir ou comprar uma caixa

Você pode baixar meu. STL ou. F3D para este caso no GitHub ou Thingiverse

Se você não tiver acesso a uma impressora 3D, um pequeno caso de projeto genérico funcionará.

Etapa 10: Decore sua capa

Decore sua capa
Decore sua capa

Porque!

Eu coloquei algum texto recuado no meu e apenas o pintei com um marcador preto. Se você se sentir aventureiro, pode usar tinta acrílica, esmalte de unha ou qualquer outra coisa para torná-la ainda mais lisa.

Etapa 11: Perfure o orifício para os fios

Orifício de perfuração para fios
Orifício de perfuração para fios

Faça um pequeno orifício de 10-15 mm na lateral perto do meio de onde todos os fios se juntam.

Usei um Unibit para fazer um orifício limpo e liso no plástico.

Etapa 12: preparar e instalar os fios de conexão

Preparar e instalar fios de conexão
Preparar e instalar fios de conexão
Preparar e instalar fios de conexão
Preparar e instalar fios de conexão

Corte fios de 9 x 5-600mm para conectar nosso dispositivo à placa de operação do portão.

  • 2 para a entrada de energia 24V
  • 3 para o status da porta (2 entradas e um terra comum)
  • 2 para o sinal de portão aberto
  • 2 para o sinal de portão fechado

Torça cada um dos grupos listados acima usando uma furadeira. Isso tornará tudo mais fácil e terá uma aparência melhor.

Desencape e conecte cada um dos fios aos respectivos terminais, conforme mostrado.

Etapa 13: direcionar os fios de conexão

Fios de conexão de rota
Fios de conexão de rota

Passe os fios de conexão pelo orifício conforme mostrado.

Etapa 14: montar componentes

Componentes de montagem
Componentes de montagem

Coloque e monte os componentes com uma pequena gota de cola quente ou silicone. Não use muito caso precise remover alguma peça, use apenas o suficiente para prendê-la.

Originalmente, eu queria imprimir o caso com clipes / guias para segurar as placas no lugar, mas precisava instalá-lo e não tive tempo. Adicionar clipes de placa ao seu caso seria um toque legal.

Etapa 15: Selar os fios de conexão

Fios de conexão de vedação
Fios de conexão de vedação

Sele os fios de conexão com cola quente ou silicone.

Etapa 16: feche o caso

Fechar o caso
Fechar o caso

Usei parafusos pequenos de ~ 4 mm na lista desta caixa impressa em 3D. Se você estiver preocupado com a sujeira ou umidade, coloque uma gota de silicone ou cola quente ao redor da junta da tampa antes de fechá-la.

Etapa 17: instalar no operador do portão

Instalar no Gate Operator
Instalar no Gate Operator
Instalar no Gate Operator
Instalar no Gate Operator

Na placa principal:

  • Prenda os dois fios conectados à saída de relé 1 ao terminal Open Gate. (vermelho / marrom nas fotos)
  • Prenda os dois fios conectados à saída de relé 2 ao terminal Fechar Gate. (amarelo / azul nas fotos)
  • Prenda os dois fios conectados à entrada do conversor DC-DC aos terminais de parafuso de alimentação do acessório de 24 V (vermelho / preto nas fotos)

Na placa de expansão

  • Ligue os terminais de parafuso comuns do relé com um pequeno pedaço de fio
  • Conecte o aterramento comum a um dos terminais de parafuso comuns do relé (verde nas fotos)
  • Conecte as 2 entradas de status da porta (IMP Pin 8 e 9) aos terminais de parafuso normalmente abertos (NO) do relé (cinza / amarelo nas fotos)

Passe os fios, prenda-os com zíper para parecerem arrumados e encontre um lugar para montar ou arrumar sua capa.

Existem fotos adicionais de resolução total, hospedadas no repositório GitHub.

Etapa 18: definir o modo de relé auxiliar

Definir modo de relé auxiliar
Definir modo de relé auxiliar

Defina as chaves do relé auxiliar como mostrado na foto.

Isso dará ao IMP os sinais de que precisa para determinar se o portão está fechado, abrindo, abrindo ou fechando.

Etapa 19: Agente IMP e código do dispositivo

Agente IMP e código do dispositivo
Agente IMP e código do dispositivo

Código do agente de impacto elétrico:

  • Crie um novo modelo no Electric Imp IDE:
  • Substitua o URL para apontar para o seu servidor

// função de manipulador

função httpHandler (req, resp) {try {local d = http.jsondecode (req.body); //server.log(d.c); if (d.c == "btn") {//server.log(d.val); device.send ("btn", d.val); resp.send (200, "OK"); }} catch (ex) {// Se houve um erro, envie-o de volta na resposta server.log ("error:" + ex); resp.send (500, "Erro interno do servidor:" + ex); }} // Registrar o manipulador HTTP http.onrequest (httpHandler); // GateStateChange handler function function gateStateChangeHandler (data) {// URL para serviço da web local url = "https://projects.ajillion.com/save_gate_state"; // Defina o cabeçalho Content-Type como json local headers = {"Content-Type": "application / json"}; // Codifica os dados recebidos e registra o corpo local = http.jsonencode (dados); server.log (corpo); // Envia os dados para o seu serviço web http.post (url, cabeçalhos, corpo).sendsync (); } // Registra o manipulador gateStateChange device.on ("gateStateChange", gateStateChangeHandler);

Código do agente de impacto elétrico:

  • Atribua um dispositivo Imp ao seu modelo
  • Verifique se os pinos de hardware têm aliases quando conectados

// Biblioteca de debouce

#require "Button.class.nut: 1.2.0" // Alias para gateOpen GPIO pin (ativo baixo) gateOpen <- hardware.pin2; // Alias para controle de gateClose GPIO pin (ativo baixo) gateClose <- hardware.pin7; // Configure 'gateOpen' para ser uma saída digital com um valor inicial de digital 1 (alto) gateOpen.configure (DIGITAL_OUT, 1); // Configure 'gateClose' para ser uma saída digital com um valor inicial de digital 1 (alto) gateClose.configure (DIGITAL_OUT, 1); // Alias para o pino GPIO que indica que a porta está se movendo (N. O.) gateMovingState <- Botão (hardware.pin8, DIGITAL_IN_PULLUP); // Alias para o pino GPIO que indica que a porta está totalmente aberta (N. O.) gateOpenState <- Botão (hardware.pin9, DIGITAL_IN_PULLUP); // Variável global para manter o estado do portão (Aberto = 1 / Fechado = 0) local lastGateOpenState = 0; // Objeto Latch Timer local latchTimer = null agent.on ("btn", function (data) {switch (data.cmd) {case "open": gateOpen.write (0); if (latchTimer) imp.cancelwakeup (latchTimer); latchTimer = imp.wakeup (1, releaseOpen); server.log ("Comando de abertura recebido"); caso de quebra "latch30m": gateOpen.write (0); if (latchTimer) imp.cancelwakeup (latchTimer); latchTimer = imp.wakeup (1800, releaseOpen); server.log ("Comando Latch30m recebido"); caso de quebra "latch8h": gateOpen.write (0); if (latchTimer) imp.cancelwakeup (latchTimer); latchTimer = imp.wakeup (28800, releaseOpen); server.log ("comando Latch8h recebido"); caso de quebra "fechar": if (latchTimer) imp.cancelwakeup (latchTimer); gateOpen.write (1); gateClose.write (0); latchTimer = imp.wakeup (1, releaseClose); server.log ("Comando Fechar agora recebido"); quebra padrão: server.log ("Comando de botão não reconhecido");}}); função releaseOpen () {if (latchTimer) imp.cancelwakeup (latchTimer); gateOpen.write (1); //server.log("Timer lançou o contato do switch gateOpen "); } function releaseClose () {if (latchTimer) imp.cancelwakeup (latchTimer); gateClose.write (1); //server.log("Timer lançado gateClose switch contact "); } gateMovingState.onPress (function () {// O relé está ativado, o portão está se movendo //server.log("Gate is abrindo "); local data = {" gatestate ": 1," timer ": hardware.millis ()}; agent.send ("gateStateChange", data);}). onRelease (function () {// O relé é liberado, o portão está em repouso //server.log("Gate is closed "); local data = {"gatestate": 0, "timer": hardware.millis ()}; agent.send ("gateStateChange", data);}); gateOpenState.onPress (function () {// O relé está ativado, o portão está totalmente aberto //server.log("Gate is open "); local data = {" gatestate ": 2," timer ": hardware.millis ()}; agent.send ("gateStateChange", data);}). onRelease (function () {// O relé foi liberado, o portão não está totalmente aberto //server.log("Gate está fechando "); dados locais = {"gatestate": 3, "timer": hardware.millis ()}; agent.send ("gateStateChange", data);});

Etapa 20: Código PHP do serviço da web

Código PHP de serviço da web
Código PHP de serviço da web

Escrevi este código para o framework CodeIgniter porque o adicionei a um projeto antigo existente. O controlador e o código de visualização podem ser facilmente adaptados à estrutura de sua escolha.

Para manter as coisas simples, salvei os dados JSON em um arquivo simples para armazenamento de dados. Se você precisar de registro ou funções relacionadas a dados mais complexos, use um banco de dados.

A biblioteca ajax que escrevi e usei neste projeto pode ser baixada do repositório GitHub: ThingEngineer / Codeigniter-jQuery-Ajax

Código do controlador PHP:

  • app / controllers / projects.php
  • Certifique-se de que o caminho dos dados seja acessível por seu script PHP, tanto de localização quanto de privilégios de leitura / gravação.

load-> helper (array ('arquivo', 'data'));

$ data = json_decode (read_file ('../ app / logs / gatestate.data'), TRUE); switch ($ data ['gatestate']) {case 0: $ view_data ['gatestate'] = 'Fechado'; pausa; caso 1: $ view_data ['gatestate'] = 'Abrindo…'; pausa; caso 2: $ view_data ['gatestate'] = 'Abrir'; pausa; caso 3: $ view_data ['gatestate'] = 'Fechando…'; pausa; } $ last_opened = json_decode (read_file ('../ app / logs / projects / gateopened.data'), TRUE); $ view_data ['last_opened'] = timespan ($ last_opened ['last_opened'], time ()). ' atrás'; // Carregar visualização $ t ['data'] = $ view_data; $ this-> load-> view ('gate_view', $ t); } function save_gate_state () {$ this-> load-> helper ('arquivo'); $ data = file_get_contents ('php: // input'); write_file ('../ app / logs / projects / gatestate.data', $ data); $ data = json_decode ($ data, TRUE); if ($ data ['gatestate'] == 1) {$ last_opened = array ('last_opened' => time ()); write_file ('../ app / logs / projects / gateopened.data', json_encode ($ last_opened)); }} function get_gate_state () {$ this-> load-> helper (array ('arquivo', 'data')); $ this-> load-> library ('ajax'); $ data = json_decode (read_file ('../ app / logs / projects / gatestate.data'), TRUE); $ last_opened = json_decode (read_file ('../ app / logs / projects / gateopened.data'), TRUE); $ data ['last_opened'] = timespan ($ last_opened ['last_opened'], time ()). ' atrás'; $ this-> ajax-> output_ajax ($ data, 'json', FALSE); // enviar dados json, não impor a solicitação ajax}} / * Fim do arquivo projects.php * / / * Localização:./application/controllers/projects.php * /

Código de visualização de PHP:

Usei o Bootstrap para o front-end porque é rápido, fácil e responsivo. Você pode baixá-lo aqui: https://getbootstrap.com (jQuery está incluído)

  • app / controllers / gate_view.php
  • Substitua YOUR-AGENT-CODE pelo código do agente Electric Imp

IoT Gate Opperator Addon IoT Gate Opperator Addon

  • Casa
  • Admin

Porta aberta trava aberta por 30 min. Trava aberta por 8 horas Fechar agora Status da porta: última abertura $ (document).ready (function () {resetStatus ();}) function sendJSON (JSONout) {var url = 'https:// agent.electricimp.com/YOUR-AGENT-CODE '; $.post (url, JSONout); } $ ("# open_gate"). click (function () {var JSONout = '{"c": "btn", "val": {"cmd": "open"}}'; sendJSON (JSONout); $ ("#status"). text ("Abrindo …");}); $ ("# latch30m_gate"). click (function () {var JSONout = '{"c": "btn", "val": {"cmd": "latch30m"}}'; sendJSON (JSONout); $ ("#status"). text ("Abrindo…");}); $ ("# latch8h_gate"). click (function () {var JSONout = '{"c": "btn", "val": {"cmd": "latch8h"}}'; sendJSON (JSONout); $ ("#status"). text ("Abrindo…");}); $ ("# close_gate"). click (function () {var JSONout = '{"c": "btn", "val": {"cmd": "close"}}'; sendJSON (JSONout); $ ("#status"). text ("Fechando…");}); function resetStatus () {// URL de destino var target = 'https://projects.ajillion.com/get_gate_state'; // Solicitar var data = {agent: 'app'}; // Enviar ajax post request $.ajax ({url: target, dataType: 'json', type: 'POST', data: data, success: function (data, textStatus, XMLHttpRequest) {switch (data.gatestate) {case 0: $ ("# status"). Text ('Fechado'); break; case 1: $ ("# status"). Text ('Abrindo…'); break; case 2: $ ("# status").text ('Open'); break; case 3: $ ("# status"). text ('Closing…'); break; default: $ ("# status"). text ('Error');} $ ("#last_opened"). text (data.last_opened);}, erro: função (XMLHttpRequest, textStatus, errorThrown) {// Mensagem de erro $ ("# status"). text ('Erro do servidor');}}); setTimeout (resetStatus, 3000); }

Recomendado: