from machine import Pin, PWM
from network import WLAN, STA_IF
from time import sleep_ms, localtime
from json import loads, dumps
from umqtt.robust import MQTTClient
# Link do dashboard público
# https://demo.thingsboard.io/dashboard/58b46e60-7b4e-11ef-95bb-f3c5773bc8e3?publicId=b1523ef0-4533-11ee-9079-75f587c23e37
DUTY_MOTOR = 25000
FECHADO = 0
ABERTO = 1
FECHANDO = 2
ABRINDO = 3
PARADOF = 4
PARADOA = 5
sensor_fechado = Pin(14, Pin.IN, Pin.PULL_UP)
sensor_aberto = Pin(27, Pin.IN, Pin.PULL_UP)
botao = Pin(26, Pin.IN, Pin.PULL_UP)
motor_in1 = PWM(Pin(13), freq=500, duty=0)
motor_in2 = PWM(Pin(12), freq=500, duty=0)
net = 'Wokwi-GUEST'
pas = ''
#net = 'Labs-AUTO-02'
#pas = 'ifrsrgautomacao'
clientId = 'crrifrsrg'
broker = 'demo.thingsboard.io'
usuario= 'OiQg8FhqDtpk4QW5NRee'
topico = b'v1/devices/me/telemetry'
topRPCGeral = 'v1/devices/me/rpc/request/'
topRPCResp = 'v1/devices/me/rpc/response/'
def ativaWifi(rede, senha):
# Retorna True se consegue conectar à rede, ou False do contrário
# Faz 10 tentativas, separadas por 1s de tempo
wifi = WLAN(STA_IF)
wifi.active(True)
if not wifi.isconnected():
wifi.connect(rede, senha)
tentativas = 0
while not wifi.isconnected() and tentativas < 10:
sleep_ms(1000)
tentativas += 1
if wifi.isconnected():
return (wifi, True)
else:
return (wifi, False)
def nomeEstado (e):
if e == FECHADO:
return 'Fechado'
elif e == ABRINDO:
return 'Abrindo'
elif e == ABERTO:
return 'Aberto'
elif e == FECHANDO:
return 'Fechando'
elif e in (PARADOF, PARADOA):
return 'Parado'
def mudaEstado(e):
if estado == FECHADO:
return ABRINDO
elif estado == ABERTO:
return FECHANDO
elif estado == FECHANDO:
return PARADOF
elif estado == ABRINDO:
return PARADOA
elif estado == PARADOF:
return ABRINDO
elif estado == PARADOA:
return FECHANDO
def rpc(t, p):
global estado, novoEstado, cliente, inicial
reqid = t.decode().replace(topRPCGeral,'')
try:
acao = loads(p.decode())
print (acao)
if acao['method'] == "getState":
if inicial:
cliente.publish((topRPCResp+reqid).encode(),
b'1' if novoEstado in (ABRINDO, FECHANDO) else b'0', retain=True)
inicial = False
else:
cliente.publish((topRPCResp+reqid).encode(),
b'1' if estado in (ABRINDO, FECHANDO) else b'0', retain=True)
elif acao['method'] == "setState":
novoEstado = mudaEstado(estado)
cliente.publish((topRPCResp+reqid).encode(),
b'1' if novoEstado in (ABRINDO, FECHANDO) else b'0', retain=True)
'''elif acao['method'] == "getAuto":
mqtt.publish((topRPCResp+reqid).encode(),
b'1' if automatico else b'0', retain=True)
#incluir retained
elif acao['method'] == "setAuto":
automatico = acao['params']
print (acao['params'])'''
except Exception as e:
print (p)
print (e)
#-------------------------------------------------------------
# Inicialização de fato
inicial = True
estado = ABERTO
novoEstado = FECHANDO # Inicia o portão como fechado
b = bAnt = botao.value()
dic = {'nomeEstado':''}
# Conectar à rede
net, conectado = ativaWifi(net,pas)
if conectado:
cliente = MQTTClient(clientId, broker, user = usuario, password='')
cliente.set_callback(rpc)
cliente.connect()
cliente.subscribe(b"v1/devices/me/rpc/request/+")
# Loop
while True:
if conectado:
cliente.check_msg()
b = botao.value()
if b != bAnt:
if b == 0:
if estado == FECHADO:
novoEstado = ABRINDO
elif estado == ABERTO:
novoEstado = FECHANDO
elif estado == FECHANDO:
novoEstado = PARADOF
elif estado == ABRINDO:
novoEstado = PARADOA
elif estado == PARADOF:
novoEstado = ABRINDO
elif estado == PARADOA:
novoEstado = FECHANDO
sleep_ms(200)
bAnt = b
if estado != novoEstado:
print (estado, novoEstado)
#fechado
if estado == FECHADO:
if novoEstado == ABRINDO:
motor_in1.duty_u16(0)
motor_in2.duty_u16(DUTY_MOTOR)
sleep_ms(1000)
#aberto
elif estado == ABERTO:
if novoEstado == FECHANDO:
motor_in1.duty_u16(DUTY_MOTOR)
motor_in2.duty_u16(0)
sleep_ms(1000)
#abrindo
elif estado == ABRINDO:
if novoEstado in (ABERTO, PARADOA):
motor_in1.duty_u16(0)
motor_in2.duty_u16(0)
#fechando
elif estado == FECHANDO:
if novoEstado in (FECHADO, PARADOF):
motor_in1.duty_u16(0)
motor_in2.duty_u16(0)
#parado
elif estado in (PARADOA, PARADOF):
if novoEstado == ABRINDO:
motor_in1.duty_u16(0)
motor_in2.duty_u16(DUTY_MOTOR)
elif novoEstado == FECHANDO:
motor_in1.duty_u16(DUTY_MOTOR)
motor_in2.duty_u16(0)
else: #parada
print ('Exceção')
if estado == ABRINDO:
novoEstado = PARADOA
else:
novoEstado = PARADOF
estado = novoEstado
if conectado:
# Publicar
dic['nomeEstado'] = nomeEstado(estado)
cliente.publish(topico, dumps(dic).encode(), retain=True)
else:
if estado == ABRINDO:
if sensor_aberto.value() == 0:
novoEstado = ABERTO
elif estado == FECHANDO:
if sensor_fechado.value() == 0:
novoEstado = FECHADO