# code.py
"""
CircuitPython + Home Assistant

This program demonstrates a MQTT device that automatically shows up in Home
Assistant. On power up, it will connect to wifi, register a device, and trigger
its action. Device registrations can be made persistent in MQTT; also,
automations connected to a device may continue to work even when the MQTT
integration has been restarted.
"""

import os
import wifi
import socketpool
import json

import adafruit_minimqtt.adafruit_minimqtt as MQTT

print()
print("Connecting to WiFi")

# Connect to your SSID
# bssid= provides a speedup, wifi.radio.ap_inf.bssid.hex();
# Lets us choose our preferred AP when we have more than one
bssid = os.getenv("WIFI_BSSID")
if bssid:
    bssid = bytes.fromhex(bssid)
wifi.radio.connect(
    os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"), bssid=bssid
)

print("Connected to WiFi")


## Home Assistant discovery message(s)

# See https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery,
# https://www.home-assistant.io/integrations/device_trigger.mqtt/#left-arrow-click-configuration

unique_id = wifi.radio.mac_address.hex()
topic = f"homeassistant/device_automation/{unique_id}/%s/config"

# Home Assistant will listen on "topic" for "payload"
trigger = {
    "automation_type": "trigger",
    "type": "button_short_press",
    "subtype": "button_1",
    "payload": "1",
    "topic": f"circuitpy/{unique_id}/action",
    "device": {
        "identifiers": [f"circuitpy_{unique_id}"],
        "name": unique_id,
        "sw_version": "CircuitPython",
        "model": "ESP32-C3",
    },
}

# Add another button to the same device
trigger_2 = {
    "automation_type": "trigger",
    "type": "button_short_press",
    "subtype": "button_2",
    "payload": "2",
    "topic": trigger["topic"],
    "device": {"identifiers": [trigger["device"]["identifiers"][0]]},
}

default_topic = trigger["topic"]


## MQTT callbacks


def connected(client, userdata, flags, rc):
    # advertise our device to home assistant
    for button in trigger, trigger_2:
        # registration topic must be unique per sensor or button on our device
        client.publish(topic % button["subtype"], json.dumps(button))

    # tell home assistant that our "button" has been pressed
    client.publish(trigger["topic"], trigger["payload"])


def disconnected(client, userdata, rc):
    print("Disconnected from MQTT Broker!")


def message(client, topic, message):
    print(f"New message on topic {topic}: {message}")


## Connect

pool = socketpool.SocketPool(wifi.radio)

# Despair awaits with mosquitto + letsencrypt default RSA configuration, even though we can adafruit_requests.get("https://same-server").
# May be a mosquitto limitation.
# ssl_context = ssl.create_default_context()
# ssl_context.load_verify_locations(cadata=open("isrg-root-x1-cross-signed.pem").read())
# ssl_context.load_verify_locations(cadata=open("isrg-root-x2-cross-signed.pem").read())
# ssl_context.check_hostname=False

# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker=os.getenv("MQTT_BROKER"),
    is_ssl=False,  # or connection errors will occur when port=8883
    port=1883,
    socket_pool=pool,
    # ssl_context=ssl_context,
    username=os.getenv("MQTT_USER"),
    password=os.getenv("MQTT_PASS"),
)

# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message

# Connect the client to the MQTT broker.
mqtt_client.connect()

for i in range(3):
    # Poll the message queue
    mqtt_client.loop(1)
    print("Loop")