""" humidity and temperature sensor AM2305 """
""" reads humidity and temperature and sends it via LoRaWAN"""

from network import LoRa
import socket
import ubinascii
import struct
import time
import config
from machine import Pin
from machine import WDT
import machine
import pycom
from dth import DTH

SENSOR_PIN = 'P23'
FLASH_PIN = 'P2'

def generate_lora_message():

    th = DTH('P23', 1)
    result = th.read()
    temp = '{:3.2f}'.format(result.temperature / 1.0)
    humi = '{:3.2f}'.format(result.humidity / 1.0)

    __message__ = '/Temp:' + str(temp) + "C/Humi:" + str(humi) + '%'

    print("Generated message: " + str(__message__))

    return __message__



pycom.heartbeat(False)
wdt = WDT(timeout=40000)  # enable it with a timeout of 2 seconds
wdt.feed()
print("Waking up...")

# initialize LoRa in LORAWAN mode.
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
lora.init(mode=LoRa.LORAWAN)

lora.nvram_restore()

# create an OTA authentication params
dev_eui = ubinascii.unhexlify('70B3D5499DB25D35')  # these settings can be found from TTN
app_eui = ubinascii.unhexlify('70B3D57ED000D35F')  # these settings can be found from TTN
app_key = ubinascii.unhexlify('A36F43FF887069841A6C421DC20B574B')  # these settings can be found from TTN

# set the 3 default channels to the same frequency (must be before sending the OTAA join request)
lora.add_channel(0, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5)
lora.add_channel(1, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5)
lora.add_channel(2, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5)

if not lora.has_joined():
    # join a network using OTAA
    print("Joining LoRa network...")
    lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=config.LORA_NODE_DR)

    # wait until the module has joined the network
    retry_cnt = 0
    sleep_cnt = 0
    while not lora.has_joined():
        time.sleep(2.5)
        print('Not joined yet...')
        retry_cnt = retry_cnt + 1

        if retry_cnt > 10:
            lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=config.LORA_NODE_DR)
            print('Sending join request again...')
            retry_cnt = 0
            sleep_cnt = sleep_cnt + 1

        if sleep_cnt > 10:
            sleep_cnt = 0
            print('Could not connect! Entering deep sleep...')
            machine.deepsleep(200000)

    # remove all the non-default channels
    for i in range(3, 16):
        lora.remove_channel(i)
else:
    print("Woke from deepsleep... already joined...")

# create a LoRa socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)

# set the LoRaWAN data rate
s.setsockopt(socket.SOL_LORA, socket.SO_DR, config.LORA_NODE_DR)

# make the socket blocking
s.setblocking(False)

# generate message

lora.nvram_save()

flashing = Pin(FLASH_PIN, mode=Pin.IN, pull=Pin.PULL_UP)
sleep = 1
wdt.feed()

while True:

    if not flashing():
        print("User Button was pressed! No deep sleep anymore...")
        sleep = 0

    # if a message was received we go back to sleep
    rx, port = s.recvfrom(256)
    if rx:
        print('Received: {}, on port: {}'.format(rx, port))
        print('Sleeping is enabled again...')
        sleep = 1

    msg = generate_lora_message()

    s.send(msg)
    time.sleep(10)
    if sleep:
        print("Entering deep sleep....")
        machine.deepsleep(500000)
