Começamos assumindo alguma familiaridade com o ambiente de desenvolvimento Hubitat Elevation e com a linguagem de programação Groovy que ele usa, embora a proficiência especializada não seja de forma alguma necessária. Leia a Visão geral do desenvolvedor, caso ainda não o tenha feito.
Ao contrário dos dispositivos Zigbee, Z-Wave e Matter – que geralmente são padronizados em termos de como o hub pode interagir com eles – os dispositivos LAN e em nuvem variam muito em se ou como podem se comunicar com o seu hub. Alguns dispositivos possuem APIs documentadas que você pode usar para integração (por exemplo, Philips Hue — nossa integração integrada usa sua API local bem documentada). Naturalmente, APIs documentadas oferecem a melhor chance de desenvolver um driver funcional. Além disso, preferimos APIs locais sempre que possível, embora interfaces em nuvem também possam funcionar.
Dispositivos de LAN e de nuvem podem exigir métodos diferentes de comunicação com seu hub, dependendo de como funciona o dispositivo ou serviço para o qual você está escrevendo um driver.
Hubitat oferece vários métodos para comunicação com dispositivos via HTTP. Ações HTTP GET, PUT ou POST síncronas ou assíncronas podem ser executadas usando métodos como httpGet()
ou asynchttpGet()
conforme descrito em Métodos comuns. Os métodos assíncronos são recomendados sempre que possível. Aqui está um trecho demonstrando um possível uso:
// dentro de algum aplicativo ou método de driver:
Parâmetros do mapa = [
uri: "http://example.com,
requestContentType: "aplicativo/json",
contentType: "aplicativo/json",
caminho: "/meuCaminho",
corpo: [minhaChave: "meuValor"],
tempo limite: 15
]
asynchttpPost("meuCallback", parâmetros)
// ...
void meuCallback(resp, dados) {
// Normalmente você também desejaria verificar se há erros e realmente
// use os dados, mas para este exemplo, apenas registraremos:
def json = resp.json
log.trace "json=$json"
}
Os drivers podem se conectar a dispositivos ou serviços externos usando uma conexão websocket. Consulte: Interface Websocket.
Os drivers podem se conectar a dispositivos ou serviços externos usando uma conexão eventstream (ou eventos enviados pelo servidor). Consulte: Interface Eventstream).
##MQTT
Os drivers podem se conectar a corretores MQTT (o hub em si não é um corretor MQTT). Consulte: Interface MQTT
Os drivers podem se conectar a servidores Telnet. Consulte: Interface Telnet.
Aplicativos ou drivers podem criar um objeto HubAction
e enviar o comando que esse objeto cria. Assim como os comandos Z-Wave ou Zigbee, este comando só será realmente enviado se for retornado de um método que implementa um comando de dispositivo Hubitat ou se você fizer isso "manualmente" via sendHubCommand()
.
Um objeto HubAction
pode enviar HTTP, TCP "bruto", UDP e mensagens semelhantes (incluindo WOL ou UPnP SSDP).
Para obter mais informações e exemplos, consulte Objeto HubAction.
O tráfego de entrada para a porta 39501 no hub será roteado para um dispositivo com um DNI correspondente ao endereço IP ou endereço MAC do dispositivo de origem (convertido para hexadecimal, tudo em letras maiúsculas, sem separadores). Esta é uma maneira de lidar com o tráfego de entrada não solicitado de dispositivos LAN que podem ser configurados para enviar dados para um endereço IP e porta específicos. (Para alguns exemplos de uso: alguns usuários da comunidade desenvolveram drivers para estações meteorológicas locais, dispositivos ESP8266/ESP32 "caseiros" e uma variedade de outros dispositivos que usam esse recurso.)
Este tráfego de entrada será enviado para o método parse()
no driver. Os dados (passados como o primeiro e único parâmetro) podem então ser processados posteriormente (por exemplo, com parseLanMessage()
) ou tratados conforme necessário.
Os aplicativos podem ser configurados para lidar com o tráfego HTTP de entrada (GET, PUT, POST ou DELETE) definindo mappings
no código do aplicativo; especificando um caminho, ação(ões) e método manipulador para cada ação; e implementar a funcionalidade desejada dentro deste manipulador. Isso pode incluir simplesmente executar uma ação, retornar JSON ou outros dados, ou até mesmo retornar conteúdo HTML para veiculação.
definição( /* ... */)
preferências() {
// ...
}
// ...
mapeamentos {
// exemplo simples:
path("/myPath") { ação: [POST: "myPathHandler"]}
// prefixo de dois pontos para parâmetros de caminho:
path("/otherPath/:param1/:param2") { ação: [GET: "otherPathHandler"]}
// Outras ações possíveis: PUT e DELETE
}
def meuPathHandler() {
// objeto `request` implícito, por exemplo, para obter parâmetros do corpo:
dados def = solicitação.JSON
log.debug "request.JSON = ${dados}"
// Não foi possível fazer nada para retornar JSON ou outros dados,
// ou para retornar HTML, retorne o valor de render():
/*
String html = "<html><body><p>Olá, mundo!</p></body></html>"
renderizar contentType: "text/html", dados: html, status: 200
*/
}
def outroPathHandler() {
// objeto `params` implícito para parâmetros de caminho:
log.trace "param1 = ${params.param1}"
log.trace "param2 = ${params.param2}"
}
Para usar mappings
, você precisará ativar o OAuth para seu aplicativo usando o botão OAuth no editor de código deste aplicativo (conforme acessado pela página Código de aplicativos). Você também deve gerar um token de acesso, que será necessário para autenticar todas as solicitações aos endpoints definidos. Isso pode ser feito chamando createAccessToken()
em algum lugar do código do seu aplicativo, geralmente apenas se state.accessToken
(que a chamada deste método criará automaticamente) ainda não existir , geralmente no início da configuração do aplicativo.
No exemplo acima, enviar um HTTP GET para http://<yourHubIP>/apps/api/<installedAppID>/otherPath/abc/def?access_token=<yourAccessToken>
imprimirá "abc" e "def" para [ Logs](/interface do usuário/recursos avançados/logs).
Você pode usar métodos como
getFullLocalApiServerUrl()
para facilitar a construção desses endpoints.
Os aplicativos reais, é claro, muitas vezes farão algo mais útil nesses manipuladores.
Conforme mencionado acima, os dispositivos e serviços de LAN e nuvem variam muito na forma como funcionam. O texto acima resume abordagens que podem funcionar para muitos deles. Qual é o melhor – ou se algum dos métodos fornecidos funciona para seu dispositivo ou serviço específico – depende exatamente de como esse dispositivo ou serviço funciona.
Alguns dispositivos LAN ou em nuvem podem ser melhor atendidos apenas com um driver. Outros usam uma combinação de aplicativo e driver, seja para facilitar a configuração (por exemplo, para que os usuários não precisem criar manualmente dispositivos "virtuais" com o driver) ou porque é a única opção possível (por exemplo, integrações em nuvem que podem ser configuradas para enviar dados para endpoints específicos que apenas um aplicativo pode manipular com mapeamentos
- um driver não pode fazer isso). Os aplicativos geralmente criam "dispositivos filhos" (do aplicativo) para representar quaisquer dispositivos reais com os quais eles lidam.
Para obter mais informações sobre métodos necessários em aplicativos ou drivers, consulte a documentação restante do desenvolvedor. O seguinte pode ser particularmente útil:
Para obter um exemplo simples de driver de LAN que envia um HTTP GET quando seu próprio switch (efetivamente virtual) é ativado ou desativado, consulte:
https://github.com/hubitat/HubitatPublic/blob/master/examples/drivers/httpGetSwitch.groovy