Cliente MQTT para Driver CmControl v1.00 (MQTT + MQTT+REST + OAuth2) com QoS=0 e retained=false
Project description
pycmcontrol-mqtt
Biblioteca Python para integração com o Driver Dispositivo CmControl v1.00 via MQTT, implementando o protocolo oficial do sistema.
Permite que aplicações Python atuem como um dispositivo CmControl totalmente compatível, suportando comunicação MQTT nativa, proxy MQTT+REST e autenticação OAuth2.
Recursos
-
Comunicação MQTT conforme especificação oficial do driver
-
Subscrição automática em
.../get/# -
Publicação com QoS = 0 e retained = false
-
Handlers automáticos obrigatórios:
- PING → PONG
- STATE → status online
-
Suporte completo ao proxy MQTT+REST
-
Autenticação OAuth2 (Basic → Bearer JWT)
-
Execução de endpoints REST via MQTT
-
Apontamentos (
setup.apontamento) -
Envio de seriais e evidências
-
Tratamento robusto de erros de rede e negócio
-
Cliente context manager (
with) -
Debug detalhado opcional
-
Tipagem estática (PEP 561)
-
Compatível com TLS
Instalação
pip install pycmcontrol-mqtt
Uso rápido
from pycmcontrol_mqtt import CmControlClient, CmControlConfig
cfg = CmControlConfig(
device_addr="device001",
broker_host="cmcontrol.example.com",
broker_port=1883,
mqtt_user="usuario",
mqtt_pass="senha",
api_user="api_user",
api_pass="api_pass",
)
with CmControlClient(cfg, debug=True) as cmc:
cmc.ensure_login()
Autenticação OAuth2 (MQTT+REST)
O cliente executa automaticamente:
- Login BASIC
- Recebimento de token JWT
- Uso de Bearer Token nas chamadas REST
with CmControlClient(cfg) as cmc:
cmc.ensure_login()
Logout opcional:
cmc.logout_oauth2()
Eventos obrigatórios do driver
Quando conectado, o cliente responde automaticamente:
| Evento recebido | Resposta enviada |
|---|---|
/get/ping |
/set/pong com timestamp |
/get/state |
/set/state {"state":"1"} |
Também envia state=1 ao conectar.
O que você pode fazer com CmControlClient
Ciclo de vida
Criação do cliente (sem conectar):
cmc = CmControlClient(cfg, debug=True)
Opções importantes:
debug=True→ log detalhado de trocas MQTTrequest_timeout_s_default→ timeout padrãostrict_business_errors→ transforma erros de negócio em exceção
Conexão
connect()→ conecta e enviastate=1disconnect()→ enviastate=0e desconecta
Uso recomendado com context manager:
with CmControlClient(cfg) as cmc:
...
Comunicação MQTT direta
publish_set(endpoint, payload)request(endpoint, payload, timeout_s=None)ping(timeout_s=None)
Implementa o padrão RPC do driver:
SET → GET correspondente
OAuth2
login_oauth2()ensure_login()logout_oauth2()token()is_token_valid()
Apontamento
setup_apontamento(setup)apontar_serial(serial, evidencias=None)validar_rota(serial)apontar_lote_1porreq(seriais)
Debug e diagnóstico
print(cmc.last_exchange())
Retorna a última troca MQTT completa.
Apontamento simples
with CmControlClient(cfg) as cmc:
cmc.ensure_login()
resp = cmc.apontar_serial("00000203030300")
print(resp)
Payload equivalente:
{
"enderecoDispositivo": "device001",
"apontamentos": [
{
"ok": true,
"seriais": [
{ "codigo": "00000203030300" }
]
}
]
}
Apontamento com evidência
Evidência a partir de texto
from pycmcontrol_mqtt import Evidence
evi = Evidence.from_text(
nome="log_teste",
extensao="txt",
texto="Conteúdo da evidência",
descricao="Log de teste"
)
cmc.apontar_serial("00000203030300", evidencias=[evi])
Evidência a partir de arquivo
evi = Evidence.from_file("foto.png")
cmc.apontar_serial("00000203030300", evidencias=[evi])
Validação de rota
resp = cmc.validar_rota("00000203030300")
Apontamento em lote
Um serial por requisição:
seriais = ["001", "002", "003"]
cmc.apontar_lote_1porreq(seriais)
Debug detalhado
Ative logs de comunicação:
with CmControlClient(cfg, debug=True) as cmc:
cmc.ensure_login()
Exemplo:
[pycmcontrol] -> SET .../set/rest/oauth2/login
[pycmcontrol] <- GET .../get/rest/oauth2/login status=200 log=OK
Tratamento de erros
Exceções específicas:
from pycmcontrol_mqtt.errors import (
CmcConnectionError,
CmcLoginError,
CmcApontamentoError,
CmcTimeout,
)
try:
with CmControlClient(cfg) as cmc:
cmc.ensure_login()
cmc.apontar_serial("00000203030300")
except CmcConnectionError as e:
print("Falha de conexão:", e)
except CmcLoginError as e:
print("Falha de login:", e)
except CmcApontamentoError as e:
print("Erro de negócio:", e.status, e.log)
except CmcTimeout:
print("Timeout aguardando resposta")
Inspeção da última troca MQTT
print(cmc.last_exchange())
Retorno:
{
"last_request": {...},
"last_response": {...},
"disconnect_rc": None
}
TLS (opcional)
Para brokers seguros (porta 8883):
from pycmcontrol_mqtt import BrokerTLS
tls = BrokerTLS(
ca_certs="ca.pem",
certfile="client.crt",
keyfile="client.key",
)
with CmControlClient(cfg, tls=tls) as cmc:
cmc.ensure_login()
Estrutura do pacote
pycmcontrol_mqtt/
├── client.py
├── config.py
├── models.py
├── errors.py
└── utils.py
Requisitos
- Python ≥ 3.9
- Broker MQTT compatível com CmControl
- Dispositivo previamente cadastrado no sistema
Licença
Distribuído sob licença MIT. Acesse LICENSE para mais informações.
Autor
Marcos Tullio Silva de Souza
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pycmcontrol_mqtt-0.2.0.tar.gz.
File metadata
- Download URL: pycmcontrol_mqtt-0.2.0.tar.gz
- Upload date:
- Size: 2.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f95455f0004413920ddcd4f184e12eaa2ca6db19c99c3d72c353bea020162c50
|
|
| MD5 |
8947e3e12c73366334e374192dabe0cf
|
|
| BLAKE2b-256 |
b1c8f814f665ab780030fd1f2a0a655a90626e5f08a72b105757645328bcb124
|
File details
Details for the file pycmcontrol_mqtt-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pycmcontrol_mqtt-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
356aeff32f0253b9de64c7055bbab842eaf428cd28fc936e2fbad7e554a2ecc7
|
|
| MD5 |
39d3416945a6ca3392f6161ded7d7f52
|
|
| BLAKE2b-256 |
6543c67bf4e7d881031df758545028463466b2831f3c6e60a63c25894f6d30db
|