Drivers no Hubitat Elevation são os meios pelos quais os usuários e aplicativos se comunicam com os dispositivos. O Hubitat vem com uma variedade de drivers integrados para vários dispositivos Zigbee, Z-Wave, LAN e em nuvem, mas também é possível escrever drivers de usuário (também conhecidos como drivers personalizados) — o foco deste documento.
A maioria dos drivers corresponde a dispositivos do mundo real. Por exemplo, o driver Generic Zigbee RGBW Light é compatível com muitas lâmpadas Zigbee RGBW, tiras de luz, etc. No entanto, alguns drivers são "virtuais", o que significa que eles não representam (necessariamente) ou se comunicam com um dispositivo do mundo real, geralmente apenas simulando o comportamento do dispositivo no hub (por exemplo, relatando um evento "switch: on" imediatamente após executar o comando on()
- em vez de esperar que essas informações retornem do dispositivo, como normalmente é feito com dispositivos reais).
Para adicionar um driver personalizado, navegue até Código dos Drivers na interface web do Hubitat (expanda a seção Ferramentas do Desenvolvedor se você não vir isso na barra lateral). Selecione Novo driver para criar um novo driver ou selecione um driver personalizado existente na lista para modificá-lo. Selecione Salvar para confirmar suas alterações. Observe que apenas o código válido será salvo; quaisquer erros aparecerão em uma barra amarela na parte superior do editor.
Para obter uma visão geral do ambiente de desenvolvimento Hubitat em geral, consulte: Visão geral do desenvolvedor.
O código abaixo é um driver Hubitat totalmente completo, embora seja apenas virtual e represente um switch virtual simples. Ainda assim, demonstra todos os componentes necessários para um dispositivo virtual básico. Tente adicioná-lo a Código de driver e adicionar um dispositivo usando-o em Dispositivos > Adicionar dispositivo > Virtual e escolha o nome do driver para Tipo no novo dispositivo para ver como funciona!
metadados {
definição (nome: "Switch virtual personalizado", namespace: "MyNamespace", autor: "Meu nome") {
capacidade "Atuador"
capacidade "Mudar"
}
preferências {
//nenhum neste driver
}
}
def instalado() {
log.debug "instalado ()"
}
def atualizado() {
log.debug "atualizado ()"
}
def ativado() {
// Com um dispositivo real, você normalmente enviaria um Z-Wave/Zigbee/etc. comando
// para o dispositivo aqui. Para um dispositivo virtual, estamos simplesmente gerando um
//evento para tornar o atributo "switch" "on". Com um dispositivo real, você
// normalmente espera uma resposta do dispositivo em parse() antes de fazer isso.
sendEvent(nome: "switch", valor: "on", descriptionText: "${device.displayName} switch está ativado")
}
def desligado() {
// Mesmas notas de on(), acima, aplicam-se aqui...
sendEvent(nome: "switch", valor: "off", descriptionText: "${device.displayName} switch está desligado")
}
Uma explicação desses componentes é fornecida abaixo.
Observe que este driver demonstra o uso do registrador integrado, log
, disponível para todos os aplicativos e drivers. Isso gera o texto fornecido para Logs, e você verá esta saída quando esses métodos forem chamados (installed()
quando o dispositivo for adicionado pela primeira vez e updated( )
sempre que o usuário seleciona o botão Salvar preferências). Os métodos de registro disponíveis são iguais aos de apps. Por enquanto, estamos simplesmente registrando quando os métodos do driver ceratin são chamados; geralmente, você precisará fazer algo em um ou mais desses métodos.
Ao contrário de um aplicativo, a definição
e as preferências
de um driver estão dentro de um bloco de metadados
.
A definição()
em um driver contém dados sobre o aplicativo, incluindo o nome e o autor. Ele também especifica capacidades, comandos, atributos e/ou impressões digitais aplicáveis ao driver. (Tecnicamente, este é um método que usa dois parâmetros, um Map
com as primeiras informações e um Closure
com as últimas; veja acima um exemplo de como isso normalmente é escrito.)
name
: O nome do driver que será exibido em Type (lista de drivers) na página de detalhes do dispositivo e em outros locaisnamespace
: Um identificador exclusivo para o desenvolvedor (nome do driver mais combinações de namespace devem ser exclusivos), normalmente um nome de usuário associado a esse desenvolvedor (geralmente seu nome de usuário no GitHub)autor
: Uma string que identifica o desenvolvedor, às vezes um nome real ou nome da empresa (ao contrário do nome e do namespace, é usado apenas para fins de exibição)importUrl
- O URL onde o código Groovy para este driver pode ser encontrado (preencherá automaticamente o campo URL quando o usuário selecionar o botão Importar na página de código do driver)singleThreaded
- Se true
(o padrão é false
), a execução simultânea de uma instância específica do driver é evitada. O hub carregará os dados do driver (incluindo state
), executará o método chamado e salvará os dados (incluindo state
) completamente antes de passar para quaisquer chamadas adicionais que possam ter sido enfileiradas nesse meio tempo. Isso se aplica apenas a métodos de "nível superior".O bloco preferências
define o que aparece em Preferências na página de detalhes do dispositivo. Geralmente correspondem a opções que o próprio dispositivo oferece (por exemplo, opções de configuração Zigbee ou Z-Wave) ou como o driver lida com determinado comportamento do dispositivo. (Ao contrário de um aplicativo, não há bloco de página
ou seção
disponível para os motoristas.)
O método input()
permite exibir vários tipos de entradas (listas suspensas, strings ou entradas numéricas, etc.). O formato geral é:
input (nome da string: elementName, tipo de string: elementType, título da string: elementTitle, /* ... opções adicionais */ )
Groovy permite omitir os parênteses, e os rótulos name
e type
podem ser omitidos, permitindo chamadas mais simples como esta:
input "meuNome", "meuTipo", título: "Minha entrada"
Cada input
cria uma configuração com o name
especificado na entrada. Eles podem ser acessados no aplicativo diretamente com o nome, por exemplo, meuNome
(como se fosse um nome de campo/variável), ou com settings["meuNome"]
. O objeto settings
é um mapa com chave sendo o nome de entrada e valor sendo o valor de entrada do usuário. Os nomes de configurações acessados diretamente pelo nome de entrada têm escopo em todo o driver.
Os tipos de entrada incluem:
texto
: Stringnúmero
: inteirodecimal
: Duploenum
: Lista (este tipo requer um parâmetro options do tipo List
com as opções); este é um menu suspenso.bool
: Booleano; este é um controle deslizante liga/desliga.As opções de um enum
podem ser uma Lista de Mapas, onde a chave do elemento do mapa é retornada enquanto o valor da String é exibido no menu suspenso.
Um defaultValue: value
pode ser especificado para uma entrada, que será exibida na UI durante o carregamento, mas não será salva na configuração correspondente até que as preferências sejam salvas. O opcional required: true
força a conclusão de uma entrada antes de salvar a página.
Os drivers devem implementar todos os comandos exigidos pelos recursos especificados. A plataforma Hubitat procurará um método Groovy regular no driver com um nome que corresponda ao comando. Por exemplo, capability "Switch"
requer um comando on()
e off()
, que são implementados como métodos no driver de exemplo acima.
Alguns métodos de driver também serão chamados em momentos específicos e devem ser fornecidos no código do driver:
installed()
: será chamado quando o dispositivo for adicionado pela primeira vezupdated()
: será chamado quando o usuário selecionar Salvar Preferênciasinitialize()
: chamado na inicialização do hub se o driver especificar capability "Initialize"
(caso contrário não é necessário ou é chamado automaticamente se presente)parse(String desc)
: lida com dados brutos recebidos de dispositivos Zigbee, Z-Wave ou LAN e geralmente cria eventos conforme necessário; veja exemplos de drivers para mais informações (dispositivos virtuais geralmente não demonstram esse comportamento, pois não há dados provenientes de um dispositivo real)Para começar a desenvolver drivers Z-Wave, Zigbee, LAN/cloud ou Matter, continue com:
Para obter mais exemplos de drivers virtuais, Zigbee, Z-Wave e Matter, consulte o repositório de exemplos HubitatPublic (veja abaixo).
Para armazenar dados entre execuções, os drivers têm um objeto state
integrado disponível. Este objeto se comporta como um Map
e permite armazenar os tipos de dados mais comuns (strings, números, listas ou mapas de tais objetos, etc. - qualquer coisa que possa ser serializada de/para JSON). Cada dispositivo possui seu próprio objeto state
.
Um objeto semelhante chamado atomicState
também está disponível. Eles funcionam de forma semelhante, exceto que state
grava os dados pouco antes do driver dormir novamente, enquanto atomicState
confirma as alterações assim que elas são feitas. Sugerimos começar com state
e mudar para atomicState
somente se houver preocupações com execução simultânea e dados de estado relacionados a isso. O uso de state
é mais eficiente. Outra alternativa mais eficiente para atomicState
é usar a especificação singleThreaded: true
em definition
, evitando mais de uma ativação sobreposta do código do driver para o mesmo dispositivo.
O objeto atomicState
também fornece um método de conveniência:
atomicState.updateMapValue(Object stateKey, Object key, Object value)
: obtém um Map
de atomicState
, atualiza um valor dentro desse mapa e o grava de voltaOs objetos
state
eatomicState
referem-se aos mesmos dados e podem ser misturados no mesmo driver iÉ necessário, mas a maioria dos desenvolvedores escolhe um ou outro com base nos requisitos do driver.
Exemplo: state.foo = "bar"
Consulte a documentação restante do desenvolvedor. Para os motoristas, o seguinte pode ser particularmente útil:
device
Também pode ser útil ver exemplos de drivers Hubitat. Alguns podem ser encontrados no repositório HubitatPublic GitHub: [https://github.com/hubitat/HubitatPublic/tree/master/examples/drivers](https://github.com/hubitat/HubitatPublic/tree/master/examples /motoristas).