from bme680 import *
import machine
from machine import I2C, Pin
from umqtt.simple import MQTTClient
import network
import ubinascii

import time

scl = Pin(26)
sda = Pin(25)
bme = BME680_I2C(I2C(0, scl=scl, sda=sda))

led_err = Pin(18, Pin.OUT)
led_stat = Pin(17, Pin.OUT)

wifi_ssid = "your_ssid"
wifi_password = "your_secret"


broker = "altostratus.tokyo" # example, you can use other public broker!

mqtt_user = "request" # to me
mqtt_password = "request" # to me

topic = b"zikka/sensor/env"

client_id = ubinascii.hexlify(machine.unique_id())

pub_period = 30000

def blink_err_flash(num):
    for n in range(num):
        led_err.on()
        time.sleep(0.1)
        led_err.off()
        time.sleep(0.1)
    if 1.0-0.2*num > 0:
        time.sleep(1.0-0.2*num)
    else:
        time.sleep(1)


def main():
    print("Here we go")

    led_err.on()
    
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    retry_cnt = 0
    if not wlan.isconnected():
        print("Connecting to network...")
        wlan.connect(wifi_ssid, wifi_password)
        while not wlan.isconnected():
            retry_cnt = retry_cnt + 1
            time.sleep(1)
            print("retry...")
            if retry_cnt == 60:
                print("Connection retry period has expired")
                time.sleep(10)
                machine.reset()

        print("Connection successful")
        print("Network config:", wlan.ifconfig())

    try:
        client = MQTTClient(client_id, broker, user=mqtt_user, password=mqtt_password)
        client.connect()
    except:
        for n in range(10):
            blink_err_flash(2)
        machine.reset()

    led_err.off()

    while True:
        tm_start = time.ticks_ms()

        led_stat.on()
        
        if not wlan.isconnected():
            print("disconnected...")
            led_err.on()
            time.sleep(60)
            machine.reset()
        
        msg = b"{},{},{},{}".format(bme.temperature, bme.humidity, bme.pressure, bme.gas)
        print(msg)
        print("publishing to {}...".format(topic))
        try:
            client.publish(topic, msg)
        except:
            for n in range(10):
                blink_err_flash(3)
            machine.reset()

        print("ok")

        led_stat.off()

        # time.sleep(10)

        t2p = time.ticks_diff(time.ticks_ms(), tm_start)
        print("publishing data takes {} ms".format(t2p))
        if pub_period-t2p > 0:
            time.sleep_ms(pub_period-t2p)
        else:
            time.sleep_ms(pub_period)

main()