import time
import machine
import utime
from umqtt.simple import MQTTClient
from machine import RTC,I2C, Pin
import micropython
import esp
import uasyncio
import gc
import ubinascii
import sys
import onewire, dht
import mqtt_cfg
import ujson
try:
  import urequests as requests
except:
  import requests
bStartup = True
gc.collect()
esp.osdebug(None)
sensor = dht.DHT22(Pin(15))
sensor.measure()
def get_id():
    return 'Azerty'
    url = 'https://www.uuidtools.com/api/generate/v4'
    response = requests.get(url)
    if response.status_code == 200:
        uid = response.text[2:-2]
        print("UID = %s" % uid)
        return uid
    else:
        print('Error')
        print(response.text)  
        return '_n_a'
def get_localtime(bFromNtp=False):
    if bFromNtp:
        import ntptime
        ntptime.settime()
    else:
        url = 'http://worldtimeapi.org/api/timezone/Europe/Brussels.txt'
        response = requests.get(url)
        if response.status_code == 200:
            dtDict = response.text.split('\n')
            now = dtDict[2].split(':',1)[1].strip()
            dow = dtDict[3].split(':')[1].strip()
            datePart, timePart = now.split('T')
            year = int(datePart.split('-')[0])
            month = int(datePart.split('-')[1])
            day = int(datePart.split('-')[2])
            hour = int(timePart.split(':')[0])
            minute = int(timePart.split(':')[1])
            second = int(timePart.split(':')[2].split('.')[0])
            subsecond = int(timePart.split('.')[1].split('+')[0])    
            rtc = RTC()
            rtc.init((year,month,day,dow,hour,minute,second,subsecond))
        else:
            print('Error')
            print(response.text)
def restart_and_reconnect():
    print('Failed to connect to InfluxDB. Reconnecting...')
    utime.sleep_ms(15)
    #machine.reset()
def connect_mqtt(client_id, host, port, user, password):
    pub_client = MQTTClient(client_id, host, port=port,user=user,password=password,keepalive=60 )
    pub_client.connect()
    print('Connected to public %s MQTT broker' % (host))
    return pub_client
async def run():
    last_message = 0
    message_interval = mqtt_cfg.message_interval
    print("Syncing local time...", end='')
    try:
        get_localtime(bFromNtp=True)
    except:
        try:
            get_localtime(bFromNtp=False)
        except:
            restart_and_reconnect()
    print("done.")
    print("Generating client ID...", end='')
    pub_client_id = 'FamClaes_%s_%s' % (get_id(),ubinascii.hexlify(machine.unique_id()).decode())
    print(pub_client_id)
    print('Start publishing...')
    bStartup = True
    dctClients={}
    connected = False
    while (not connected):
        for srvMosq in mqtt_cfg.activeServers:
            try:
                cMqtt = mqtt_cfg.MQTTServers[srvMosq]
                pub_client = connect_mqtt(client_id=pub_client_id, host=cMqtt['host'], port=cMqtt['port'],user=cMqtt['user'] ,password=cMqtt['passwd'])
                dctClients[srvMosq] = pub_client
                connected = True
            except  Exception as e :
                print("Cannot get connected to: %s...please wait" % cMqtt['host'])
                utime.sleep(1)
                print ("Encountered error ", e.args, "...rebooting")
                sys.print_exception(e)    
    now = utime.localtime()
    ts = "{:02d}/{:02d}/{} {:02d}:{:02d}:{:02d}".format(now[2],now[1],now[0],now[3],now[4],now[5])
    while True:
        if (time.time() - last_message) > message_interval or bStartup == True:
            if bStartup:
                bStartup = False
            ts = "{:02d}/{:02d}/{} {:02d}:{:02d}:{:02d}".format(now[2],now[1],now[0],now[3],now[4],now[5])
            sensor.measure()
            for srvMosq in mqtt_cfg.activeServers:
                topic_pub = b"%s/%s" % (cMqtt['topic'],'DHT22_001')
                msg = ujson.dumps({"temp": sensor.temperature(),"humidity": sensor.humidity(),"timestamp":ts })
                dctClients[srvMosq].publish(topic=topic_pub, msg=msg, retain=True, qos=0 )
                print ("Published %s" % msg)
            last_message = time.time()  
        else:
            print('Waiting for next insterval...')                     
        utime.sleep(2)
if __name__ == '__main__':
    try:
        uasyncio.run(run())
        oled.poweroff()
    except KeyboardInterrupt:
        os.exit(250)
    except Exception as e:
        print ("Encountered error ", e.args, "...rebooting")
        sys.print_exception(e)    
        restart_and_reconnect()