import  paho.mqtt.client as mqtt
import  time, random, threading
import  multiprocessing as mp
from decouple import config

serverUrl = "mqtt.cumulocity.com"
clientId = "test_mqtt_python_client"
deviceName = "RaspberryPi 4 MQTT device"
serialNum = "SN12345678"

tenant = config('tenant', default='')
username = config('username', default='')
password = config('password', default='')

task_queue = mp.Queue()

def on_message(client, userdata, message):
    payload = message.payload.decode("utf-8")
    print(" < received message " + payload)
    if payload.startswith("510"):
        task_queue.put(perform_restart)

def perform_restart():
    print("Simulating device restart...")
    publish("s/us", "501,c8y_Restart", wait_for_ack = True);
    print("...restarting")
    time.sleep(3)
    publish("s/us", "503,c8y_Restart", wait_for_ack = True);
    print("...restart completed")

def send_measurement():
    print("Sending emulated measurement")
    temperature = random.randint(15, 30)
    publish("s/us", "211,{}".format(temperature))

def publish(topic, message, wait_for_ack = False):
    QoS = 2 if wait_for_ack else 0
    message_info = client.publish(topic, message, QoS)
    if wait_for_ack:
        print(" > awaiting ACK for {}".format(message_info.mid))
        message_info.wait_for_publish()
        print(" < received ACK for {}".format(message_info.mid))

def on_publish(client, userdata, mid):
    print(" > published message: {}".format(mid))

def device_loop():
    while True:
        task_queue.put(send_measurement)
        time.sleep(10)

client = mqtt.Client(clientId)
client.username_pw_set(tenant + "/" + username, password)
client.on_message = on_message
client.on_publish = on_publish

print("Connecting to the server " + serverUrl)
client.connect(serverUrl)
client.loop_start()
print("Connected to the server, main loop started")
print("Registering the device " + deviceName)

publish("s/us", "100," + deviceName + ", c8y_MQTTDevice", wait_for_ack = True)
publish("s/us", "110," + serialNum + ", MQTT test model,Rev0.1")
publish("s/us", "114,c8y_Restart")
print("Device registered successfully")

client.subscribe("s/ds")
print("Devise subscribed to the channel")

device_loop_thread = threading.Thread(target = device_loop)
device_loop_thread.daemon = True
device_loop_thread.start()
print("Device loop started")

try:
    while True:
        task = task_queue.get()
        task()
except (KeyboardInterrupt, SystemExit):
    print("Received keyboard interrupt, quitting...")
    exit(0)
