#!/usr/bin/env python3

import sys
import datetime
import signal
import math

import paho.mqtt.client as mqtt

import urllib.request as request
import json

from signal import *
from time import sleep
from PIL import Image, ImageDraw, ImageFont
from displayhatmini import DisplayHATMini, ST7789

MQTT_SERVER = "removed"
MQTT_PORT = removed
MQTT_TOPIC = "displaypi/data/#"
MQTT_STATUS = "displaypi/state"
MQTT_CONTROL = "displaypi/control"
MQTT_RESPONSE = "displaypi/response"
MQTT_PRESENCE = "displaypi/presence"
MQTT_MONITOR = "monitor/data/#"
MQTT_NEWS = "news/headlines"
MQTT_WEATHER_DAILY = "metweather/daily"
MQTT_WEATHER_CURRENT = "metweather/current"


# Set these to use authorisation
MQTT_USER = "removed"
MQTT_PASS = "removed"

rotation = 180

#disp = ST7789(
#    height=240,
#    width=320,
#    rotation=rotation,
#    port=0,
#    cs=1,
#    dc=9,
#    backlight=13,
#    spi_speed_hz=60 * 1000 * 1000,
#    offset_left=0,
#    offset_top=0
#)

#disp.begin()

WIDTH = DisplayHATMini.WIDTH
HEIGHT = DisplayHATMini.HEIGHT

RP0_IP = "removed"
RP1_IP = "removed"
RP2_IP = "removed"

font30 = ImageFont.truetype('orbitron.ttf', 30)
font28 = ImageFont.truetype('orbitron.ttf', 28)
font24 = ImageFont.truetype('orbitron.ttf', 24)
font20 = ImageFont.truetype('orbitron.ttf', 20)
font18 = ImageFont.truetype('orbitron.ttf', 18)
font14 = ImageFont.truetype('orbitron.ttf', 14)
clockfont = ImageFont.truetype('dig-m.ttf', 64)
tagfont = ImageFont.truetype('FontAwesome6-Free-Solid.otf', 20)
brandfont = ImageFont.truetype('FontAwesome6-Free-Brands.otf', 20)

DISPLAYSCREEN = "clock"
OLDSCREEN = ""
status = "stop"
people = ["removed","removed","removed","removed"]
presence = ["init","init","init","init"]

monitorname = ["removed1", "removed2", "removed3", "removed4", "removed5", "removed6", "removed7", "removed8", "removed9", "Internet"]
monitordevice = ["removed1", "removed2", "removed3", "removed4", "removed5", "removed6", "removed7", "removed8", "removed9", "Internet"]
monitorstatus = ["Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending"]

piname =   ["removed1", "removed2", "removed3", "removed4", "removed5", "removed6", "removed7", "removed8", "removed9", "removed0"]
pidevice = ["removed1", "removed2", "removed3", "removed4", "removed5", "removed6", "removed7", "removed8", "removed9", "removed0"]
pistatus = ["Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending", "Pending"]

newsptr = 0
newslist = ["", "", "", "", "", "", "", "", "", ""]
newswidth = 22

weather = {}
weatherd = {}


def ordinal_suffix(day):
    if 3 < day < 21 or 23 < day < 31:
        return 'th'
    else:
        return {1: 'st', 2: 'nd', 3: 'rd'}[day % 10]

def draw_centred_text(image, text, ypos, font, r, g, b):
    indent = int((WIDTH - int(font.getlength(text)))/2)
    draw = ImageDraw.Draw(image)
    bbox = draw.textbbox((0,0), text, font=font)
    width = bbox[2] - bbox[0]
    height = bbox[3] - bbox[1]
    textimage = Image.new('RGBA', (width, height), (0, 0, 0, 0))
    textdraw = ImageDraw.Draw(textimage)
    textdraw.text((0, 0), text, font=font, fill=(r, g, b))
    rotated = textimage.rotate(0, expand=1)
    position = tuple((indent, ypos))
    image.paste(rotated, position, rotated)
    return

def draw_text(image, text, xpos, ypos, font, r, g, b):
    draw = ImageDraw.Draw(image)
    bbox = draw.textbbox((0,0), text, font=font)
    width = bbox[2] - bbox[0]
    height = bbox[3] - bbox[1]
    textimage = Image.new('RGBA', (width, height), (0, 0, 0, 0))
    textdraw = ImageDraw.Draw(textimage)
    textdraw.text((0, 0), text, font=font, fill=(r, g, b))
    rotated = textimage.rotate(0, expand=1)
    position = tuple((xpos, ypos))
    image.paste(rotated, position, rotated)
    return

def clear_display():
    global img, draw, disp, WIDTH, HEIGHT
    img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
    draw = ImageDraw.Draw(img)
    return

def button_callback(pin):
    global DISPLAYSCREEN, RP0_IP, RP1_IP, RP2_IP, newsptr, newslist, newswidth, rotation

    if rotation == 0:
        btn_TL=display_hat.BUTTON_Y
        btn_TR=display_hat.BUTTON_B
        btn_BL=display_hat.BUTTON_X
        btn_BR=display_hat.BUTTON_A
    elif rotation == 180:
        btn_TL=display_hat.BUTTON_A
        btn_TR=display_hat.BUTTON_X
        btn_BL=display_hat.BUTTON_B
        btn_BR=display_hat.BUTTON_Y

    if not display_hat.read_button(pin):
        return

    if DISPLAYSCREEN == "clock":
        if pin == btn_TL:
            DISPLAYSCREEN = "weather"
            return
        elif pin == btn_TR:
            DISPLAYSCREEN = "clock_2"
            return
        elif pin == btn_BL:
            DISPLAYSCREEN = "radio_0"
            return
        elif pin == btn_BR:
            DISPLAYSCREEN = "blank"
            return
        return

    if DISPLAYSCREEN == "clock_2":
        if pin == btn_TL:
            DISPLAYSCREEN = "news"
            return
        elif pin == btn_TR:
            DISPLAYSCREEN = "clock"
            return
        elif pin == btn_BL:
            DISPLAYSCREEN = "people"
            return
        elif pin == btn_BR:
            DISPLAYSCREEN = "monitor"
            return
        return

    if DISPLAYSCREEN == "weather":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock"
        elif pin == btn_BL:
            DISPLAYSCREEN = "weatherd"
            return
        return

    if DISPLAYSCREEN == "weatherd":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock"
        elif pin == btn_BL:
            DISPLAYSCREEN = "weather"
            return
        return

    if DISPLAYSCREEN == "news":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock_2"
            return
        elif pin == btn_BL:
            newswidth = newswidth + 1
            if newswidth > 26:
                newswidth = 18
            DISPLAYSCREEN = "news_redraw"
            return
        elif pin == btn_TR:
            newsptr = newsptr -1
            if newsptr < 0:
                newsptr = len(newslist) - 1
            DISPLAYSCREEN = "news_redraw"
            return
        elif pin == btn_BR:
            newsptr = newsptr + 1
            if newsptr >= len(newslist):
                newsptr = 0
            DISPLAYSCREEN = "news_redraw"
            return
        return

    if DISPLAYSCREEN == "radio_0":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock"
            return
        elif pin == btn_BL:
            DISPLAYSCREEN = "radio_1"
            return
        elif pin == btn_TR:
            request.urlopen('http://' + RP0_IP + '/api/v1/commands/?cmd=toggle')
            return
        elif pin == btn_BR:
            request.urlopen('http://' + RP0_IP + '/api/v1/commands/?cmd=next')
            return
        return

    if DISPLAYSCREEN == "radio_1":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock"
            return
        elif pin == btn_BL:
            DISPLAYSCREEN = "radio_2"
            return
        elif pin == btn_TR:
            request.urlopen('http://' + RP1_IP + '/api/v1/commands/?cmd=toggle')
            return
        elif pin == btn_BR:
            request.urlopen('http://' + RP1_IP + '/api/v1/commands/?cmd=next')
            return
        return

    if DISPLAYSCREEN == "radio_2":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock"
            return
        elif pin == btn_BL:
            DISPLAYSCREEN = "radio_0"
            return
        elif pin == btn_TR:
            request.urlopen('http://' + RP2_IP + '/api/v1/commands/?cmd=toggle')
            return
        elif pin == btn_BR:
            request.urlopen('http://' + RP2_IP + '/api/v1/commands/?cmd=next')
            return
        return

    if DISPLAYSCREEN == "people":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock_2"
            return
        elif pin == btn_BL:
            DISPLAYSCREEN = "people_refresh"
            return
        return

    if DISPLAYSCREEN == "monitor":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock_2"
            return
#        elif pin == btn_BL:
#            return
        elif pin == btn_TR:
            DISPLAYSCREEN = "monitor_2"
            return
#        elif pin == btn_BR:
#            return
        return


    if DISPLAYSCREEN == "monitor_2":
        if pin == btn_TL:
            DISPLAYSCREEN = "clock_2"
            return
#        elif pin == btn_BL:
#            return
        elif pin == btn_TR:
            DISPLAYSCREEN = "monitor"
            return
#        elif pin == btn_BR:
#            return
        return

    if DISPLAYSCREEN == "blank":
        DISPLAYSCREEN = "clock"
        return

    return

def draw_tags():
    global DISPLAYSCREEN, status

    if DISPLAYSCREEN == "clock":
        draw_tag(img, u"\uf743", "Y", font=tagfont)  # Weather
        draw_tag(img, u"\uf13a", "B", font=tagfont)  # Circle Chevron Down
        draw_tag(img, u"\uf001", "X", font=tagfont)  # Radio
        draw_tag(img, u"\uf00d", "A", font=tagfont)  # Blank
        return

    if DISPLAYSCREEN == "clock_2":
        draw_tag(img, u"\uf1ea", "Y", font=tagfont)  # News
        draw_tag(img, u"\uf139", "B", font=tagfont)  # Circle Chevron Up
        draw_tag(img, u"\uf0c0", "X", font=tagfont)  # People
        draw_tag(img, u"\uf06e", "A", font=tagfont)  # Eye
        return

    elif DISPLAYSCREEN == "weather":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        draw_tag(img, u"\uf185", "X", font=tagfont)  # Sun (Weatherd)
        return

    elif DISPLAYSCREEN == "weatherd":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        draw_tag(img, u"\uf743", "X", font=tagfont)  # Weather
        return

    elif DISPLAYSCREEN == "news":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        draw_tag(img, u"\uf139", "B", font=tagfont)  # Circle Chevron Up
        draw_tag(img, u"\uf035", "X", font=tagfont)  # Text Width
        draw_tag(img, u"\uf13a", "A", font=tagfont)  # Circle Chevron Down
        return

    elif DISPLAYSCREEN == "people":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        draw_tag(img, u"\uf2f1", "X", font=tagfont)  # Refresh (rotate arrows)
        return

    elif DISPLAYSCREEN == "monitor":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        draw_tag(img, u"\uf7bb", "B", font=brandfont)  # Robot (RasPi doesn't work!)
        return

    elif DISPLAYSCREEN == "monitor_2":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        draw_tag(img, u"\uf06e", "B", font=tagfont)  # Eye
        return

    elif DISPLAYSCREEN == "radio_0":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        if status == "play":
            draw_tag(img, u"\uf04c", "B", font=tagfont)  # Pause
        else:
            draw_tag(img, u"\uf04b", "B", font=tagfont)  # Play
        draw_tag(img, u"\u0031", "X", font=tagfont)  # One
        draw_tag(img, u"\uf04e", "A", font=tagfont)  # Forward
        return

    elif DISPLAYSCREEN == "radio_1":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        if status == "play":
            draw_tag(img, u"\uf04c", "B", font=tagfont)  # Pause
        else:
            draw_tag(img, u"\uf04b", "B", font=tagfont)  # Play
        draw_tag(img, u"\u0032", "X", font=tagfont)  # Two
        draw_tag(img, u"\uf04e", "A", font=tagfont)  # Forward
        return

    elif DISPLAYSCREEN == "radio_2":
        draw_tag(img, u"\uf017", "Y", font=tagfont)  # Clock
        if status == "play":
            draw_tag(img, u"\uf04c", "B", font=tagfont)  # Pause
        else:
            draw_tag(img, u"\uf04b", "B", font=tagfont)  # Play
        draw_tag(img, u"\u0030", "X", font=tagfont)  # Zero
        draw_tag(img, u"\uf04e", "A", font=tagfont)  # Forward
        return

    return

def draw_tag(image, text, btn, font):

    if btn == "A":
        position = tuple((295, 160))
    elif btn == "B":
        position = tuple((295, 65))
    elif btn == "X":
        position = tuple((5, 160))
    elif btn == "Y":
        position = tuple((5, 65))

    draw = ImageDraw.Draw(image)
    bbox = draw.textbbox((0,0), text, font=font)
    width = bbox[2] - bbox[0]
    height = bbox[3] - bbox[1]
    textimage = Image.new('RGBA', (width, height), (0, 0, 0, 0))
    textdraw = ImageDraw.Draw(textimage)
    textdraw.text((0, 0), text, font=font, fill=(255, 255, 255))
    rotated = textimage.rotate(0, expand=1)
    image.paste(rotated, position, rotated)
    return

def read_radio(ip):

    global DISPLAYSCREEN, img, status

    try:
        with request.urlopen('http://' + ip + '/api/v1/getState') as response:
            source = response.read()
            data = json.loads(source)
        status = data['status']
        title = data['title'].strip()
        uri = data['uri']
    except:
        status = "offline"
        title = ""
        uri = ""
        station = ""

    if status == "stop":
        song = "Idle"
        artist = ""

    elif status == "offline":
        song = "Offline"
        artist = ""

    elif status == "play" and len(title) > 3:
        try:
            song, artist = title.split(' - ',2)
        except:
            song = ""
            artist = ""
    else:
        song = "Unknown"
        artist = "Unknown"

    if uri != "":
        if uri.count("absolute80s") > 0:
            station = "Absolute 80s"
        elif uri.count("absoluteclassicrock") > 0:
            station = "Absolute Classic Rock"
        elif uri.count("absoluteradio") > 0:
            station = "Absolute Radio"
        elif uri.count("absolutecountry") > 0:
            station = "Absolute Country"
        elif uri.count("Heart80s") > 0:
            station = "Heart 80s"
        else:
            station = "Internet Radio"
    else:
        station = ""

    if len(song) < 17:
        draw_centred_text(img, song, 65, font20, 255, 255, 255)
    else:
        if(song.count(" ")) > 0:
            song = song.strip()[:32]
            song1 = ""
            song2 = ""
            songspace = True
            songlist = song.split()
            songlen = len(songlist)
            count = 0

            while count < songlen:
                next = songlist[count]
                if songspace == True and ((len(next) + len(song1)) < 16):
                    song1 = song1 + " " + songlist[count]
                    song1 = song1.strip()
                    count = count + 1
                else:
                    songspace = False
                    song2 = song2 + " " + songlist[count]
                    song2 = song2.strip()
                    count = count + 1
            draw_centred_text(img, song1, 50, font20, 255, 255, 255)
            draw_centred_text(img, song2, 80, font20, 255, 255, 255)
        else:
            div = math.floor(len(song)/2)
            draw_centred_text(img, song[:16], 50, font20, 255, 255, 255)
            draw_centred_text(img, song[16:32], 80, font20, 255, 255, 255)


    if len(artist) < 17:
        draw_centred_text(img, artist, 135, font20, 255, 255, 255)
    else:
        if(artist.count(" ")) > 0:
            artist = artist.strip()[:32]
            art1 = ""
            art2 = ""
            artspace = True
            artlist = artist.split()
            artlen = len(artlist)
            count = 0
            while count < artlen:
                next = artlist[count]
                if artspace == True and ((len(next) + len(art1)) < 16):
                    art1 = art1 + " " + artlist[count]
                    art1 = art1.strip()
                    count = count + 1
                else:
                    artspace = False
                    art2 = art2 + " " + artlist[count]
                    art2 = art2.strip()
                    count = count + 1
            draw_centred_text(img, art1, 120, font20, 255, 255, 255)
            draw_centred_text(img, art2, 150, font20, 255, 255, 255)
        else:
            div = math.floor(len(artist)/2)
            draw_centred_text(img, artist[:16], 120, font20, 255, 255, 255)
            draw_centred_text(img, artist[16:32], 150, font20, 255, 255, 255)

    draw_centred_text(img, station, 190, font20, 255, 0, 255)
    return

def show_news():
    global newsptr, newslist, newswidth, img
    draw_centred_text(img, "News - " + str(newsptr + 1), 10, font24, 255, 0, 0)
    news_lines = ["", "", "", "", "", ""]
    headline = newslist[newsptr]
    headsplit = headline.split()
    headlen = len(headsplit)
    line = 0

    x = 0
    if len(headsplit) > 1:
        while x < len(headsplit):
            if ( len(headsplit[x]) + len(news_lines[line]) ) < newswidth:
               news_lines[line] = (news_lines[line] + " " +  headsplit[x]).strip()
               x = x + 1
            elif len(headsplit[x]) > (newswidth - 1):
                if line < len(news_lines):
                    line = line + 1
                    news_lines[line] = headsplit[x]
                x = x + 1
            else:
                line = line + 1

    x = 0
    while x < len(news_lines):
        draw_centred_text(img, news_lines[x], (80 + (x * 20)), font18, 255, 255, 255)
        x = x + 1

    draw_centred_text(img, str(newswidth), 190, font14, 255, 0, 255)
    return

def show_weather(): # the current one
    global weather
    draw_centred_text(img, "Current Weather", 10, font24, 255, 0, 0)
    draw_centred_text(img, str(weather['state']), 60, font20, 255, 255, 255)
    draw_centred_text(img, "Temp - " + str(round(weather['temperature'],1)) + " (" + str(round(weather['feels_like'],1)) + ") C", 90, font20, 255, 255, 255)
    draw_centred_text(img, "Wind - " + str(round(weather['wind_speed'],1)) + " m/s ("+ str(weather['wind_dir']) + ")", 120, font20, 255, 255, 255)
    draw_centred_text(img, "Hum - " + str(round(weather['humidity'])) + " %", 150, font20, 255, 255, 255)
    draw_centred_text(img, "UV - " + str(weather['uv_index']), 180, font20, 255, 255, 255)
    draw_centred_text(img, "Rain - " + str(round(weather['prob_precipitation'])) + " % / " +  str(weather['precipitation_rate']), 210, font20, 255, 255, 255)

    return

def show_weatherd(): # the daily summary
    global weatherd
    draw_centred_text(img, "Daily Weather", 10, font24, 255, 0, 0)
    draw_centred_text(img, str(weatherd['weather']), 60, font20, 255, 255, 255)
    draw_centred_text(img, "Temp - " + str(weatherd['temperature']) + " (" + str(weatherd['feels_like']) + ") C", 90, font20, 255, 255, 255)
    draw_centred_text(img, "Wind - " + str(weatherd['wind_speed']) + " m/s ("+ str(weatherd['wind_dir']) + ")", 120, font20, 255, 255, 255)
    draw_centred_text(img, "Hum - " + str(weatherd['humidity']) + " %", 150, font20, 255, 255, 255)
    draw_centred_text(img, "UV - " + str(weatherd['uv_index']), 180, font20, 255, 255, 255)
    draw_centred_text(img, "Rain - " + str(weatherd['prob_precipitation']), 210, font20, 255, 255, 255)
    return

def show_monitor():
    global monitordevice, monitorstatus, monitorname
    draw_centred_text(img, "Monitor", 10, font24, 255, 255, 255)
    x=0
    col1 = 40
    col2 = 170
    width = 10

    while x < 5:
        if monitorstatus[x] == "Online":
            draw_text(img, monitorname[x].center(width), col1, 80 + (x * 20), font20, 0, 255, 0)
        elif monitorstatus[x] == "Offline":
            draw_text(img, monitorname[x].center(width), col1, 80 + (x * 20), font20, 255, 0, 0)
        elif monitorstatus[x] == "Play":
            draw_text(img, monitorname[x].center(width), col1, 80 + (x * 20), font20, 255, 0, 255)
        elif monitorstatus[x] == "Idle":
            draw_text(img, monitorname[x].center(width), col1, 80 + (x * 20), font20, 0, 0, 255)
        x = x +1

    x=5
    while x < 10:
        if monitorstatus[x] == "Online":
            draw_text(img, monitorname[x].center(width), col2, 80 + ((x - 5) * 20), font20, 0, 255, 0)
        elif monitorstatus[x] == "Offline":
            draw_text(img, monitorname[x].center(width), col2, 80 + ((x - 5) * 20), font20, 255, 0, 0)
        elif monitorstatus[x] == "Play":
            draw_text(img, monitorname[x].center(width), col2, 80 + ((x - 5) * 20), font20, 255, 0, 255)
        elif monitorstatus[x] == "Idle":
            draw_text(img, monitorname[x].center(width), col2, 80 + ((x - 5) * 20), font20, 0, 0, 255)
        x = x +1

    return

def show_monitor_2():
    global pidevice, pistatus, piname
    draw_centred_text(img, "Pi Monitor", 10, font24, 255, 255, 255)
    x=0
    col1 = 40
    col2 = 170
    width = 10

    while x < 5:
        if pistatus[x] == "Online":
            draw_text(img, piname[x].center(width), col1, 80 + (x * 20), font20, 0, 255, 0)
        elif pistatus[x] == "Offline":
            draw_text(img, piname[x].center(width), col1, 80 + (x * 20), font20, 255, 0, 0)
        x = x +1

    x=5
    while x < 10:
        if pistatus[x] == "Online":
            draw_text(img, piname[x].center(width), col2, 80 + ((x - 5) * 20), font20, 0, 255, 0)
        elif pistatus[x] == "Offline":
            draw_text(img, piname[x].center(width), col2, 80 + ((x - 5) * 20), font20, 255, 0, 0)
        x = x +1

    return


def clean(*args):
    clear_display()
    display_hat.set_backlight(False)
    display_hat.display(img)
    sys.exit(0)

def on_connect(client, userdata, flags, rc):
    if rc == 0:
      DISPLAYSCREEN = "clock"
      ret = client.publish(MQTT_RESPONSE,"MQTT Connected")
      ret = client.publish(MQTT_STATUS,"clock", qos=0, retain = True)
      client.subscribe(MQTT_TOPIC)
      client.subscribe(MQTT_CONTROL)
      client.subscribe(MQTT_PRESENCE)
      client.subscribe(MQTT_NEWS)
      client.subscribe(MQTT_WEATHER_DAILY)
      client.subscribe(MQTT_WEATHER_CURRENT)
      client.subscribe(MQTT_MONITOR)
      display_hat.set_led(0, 0, 0)
    else:
      display_hat.set_led(0.05, 0, 0)
    return


def on_disconnect(client, userdata, rc):
    display_hat.set_led(0.05, 0, 0)
    return

def on_subscribe(client, userdata, mid, granted_qos):
    ret = client.publish(MQTT_RESPONSE,"MQTT Subscribed")
    return

def on_message(client, userdata, msg):
    global DISPLAYSCREEN, people, presence, newslist, RP0_STATION, RP1_STATION, RP2_STATION, weather, weatherd
    global monitordevice, monitorstatus, pidevice, pistatus
    screenlist = ["clock", "clock_2", "weather", "weatherd", "news", "people", "radio_0", "radio_1", "radio_2", "monitor", "monitor_2", "blank"]
 
    if msg.topic == MQTT_CONTROL:

        data = msg.payload.decode("utf-8").lower()
        if data in screenlist:
            ret = client.publish(MQTT_RESPONSE, data + " displayed", qos=0, retain = True)
            DISPLAYSCREEN = data
            return
        else:
            ret = client.publish(MQTT_RESPONSE, "Unknown screen - " + data, qos=0, retain = True)
        return

    if msg.topic.find("monitor/data/") == 0 and msg.topic != "monitor/data/control":

        jdata = json.loads(msg.payload.decode('utf-8'))
        device = jdata['device']
        status = jdata['status']
        if device in monitordevice:
            x = monitordevice.index(device)
            monitorstatus[x] = status
        if device in pidevice:
            x = pidevice.index(device)
            pistatus[x] = status
        return

    if msg.topic == MQTT_PRESENCE:
        jdata = json.loads(msg.payload.decode('utf-8'))
        person = jdata['person'].lower()
        status = jdata['status'].lower()

        try:
            loc = people.index(person)
            presence[loc] = status
        except:
            ret = client.publish(MQTT_RESPONSE,"Person not found - " + person)
            print("Person not found - " + person)
        return

    if msg.topic == MQTT_NEWS:
        newslist = json.loads(msg.payload.decode('utf-8'))
        return

    if msg.topic == MQTT_WEATHER_CURRENT:
        weather = json.loads(msg.payload.decode('utf-8'))
        return

    if msg.topic == msg.topic == MQTT_WEATHER_DAILY:
        weatherd = json.loads(msg.payload.decode('utf-8'))
        return

    return


for sig in (SIGABRT, SIGILL, SIGINT, SIGSEGV, SIGTERM):
    signal(sig, clean)

display_hat = DisplayHATMini(buffer=None, backlight_pwm=True)
display_hat.on_button_pressed(button_callback)

client = mqtt.Client()
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.on_subscribe = on_subscribe

if MQTT_USER is not None and MQTT_PASS is not None:
    client.username_pw_set(username=MQTT_USER, password=MQTT_PASS)

client.connect(MQTT_SERVER, MQTT_PORT, 60)
client.loop_start()

while True:
    while DISPLAYSCREEN == "clock":
        clear_display()
        display_hat.set_backlight(True)
        x = datetime.datetime.now()
        today = datetime.date.today()
        date_string = today.strftime('%-d{suffix} %B')
        if (x.second / 2) == int(x.second / 2):
            draw_centred_text(img, x.strftime("%H:%M:%S"), 48, clockfont, 255, 255, 255)
        else:
            draw_centred_text(img, x.strftime("%H %M %S"), 48, clockfont, 255, 255, 255)
        draw_centred_text(img, x.strftime('%A'), 144, font28, 255, 255, 255)
        draw_centred_text(img, date_string.format(suffix=ordinal_suffix(today.day)), 192, font28, 255, 255, 255)
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "clock":
            ret = client.publish(MQTT_STATUS,"clock", qos=0, retain = True)
            OLDSCREEN = "clock"
        sleep(0.1)

    while DISPLAYSCREEN == "clock_2":
        clear_display()
        display_hat.set_backlight(True)
        x = datetime.datetime.now()
        today = datetime.date.today()
        date_string = today.strftime('%-d{suffix} %B')
        if (x.second / 2) == int(x.second / 2):
            draw_centred_text(img, x.strftime("%H:%M:%S"), 48, clockfont, 255, 255, 255)
        else:
            draw_centred_text(img, x.strftime("%H %M %S"), 48, clockfont, 255, 255, 255)
        draw_centred_text(img, x.strftime('%A'), 144, font28, 255, 255, 255)
        draw_centred_text(img, date_string.format(suffix=ordinal_suffix(today.day)), 192, font28, 255, 255, 255)
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "clock_2":
            ret = client.publish(MQTT_STATUS,"clock_2", qos=0, retain = True)
            OLDSCREEN = "clock_2"
        sleep(0.1)

    while DISPLAYSCREEN == "people":
        clear_display()
        display_hat.set_backlight(True)
        draw_tags()

        offset = 0
        for x in people:
            loc = people.index(x)
            if presence[loc] == "home":
                draw_centred_text(img, x.capitalize(), ((loc * 40) + 50), font30, 0, 255, 0)
            elif presence[loc] == "not_home":
                draw_centred_text(img, x.capitalize(), ((loc * 40) + 50), font30, 0, 0, 255)
            else:
                draw_centred_text(img, x.capitalize(), ((loc * 40) + 50), font30, 255, 0, 0)

        display_hat.display(img)
        if OLDSCREEN != "people":
            ret = client.publish(MQTT_STATUS,"people", qos=0, retain = True)
            OLDSCREEN = "people"
        sleep(0.1)

    while DISPLAYSCREEN =="people_refresh":
        clear_display()
        display_hat.display(img)
        if OLDSCREEN != "people_refresh":
            ret = client.publish(MQTT_STATUS,"people_refresh", qos=0, retain = True)
            OLDSCREEN = "people_refresh"
        DISPLAYSCREEN = "people"

    while DISPLAYSCREEN == "radio_0":
        clear_display()
        display_hat.set_backlight(True)
        draw_centred_text(img, "Radio Pi Zero", 10, font24, 255, 0, 0)
        read_radio(RP0_IP)
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "radio_0":
            ret = client.publish(MQTT_STATUS,"radio_0", qos=0, retain = True)
            OLDSCREEN = "radio_0"
        sleep(0.1)

    while DISPLAYSCREEN == "radio_1":
        clear_display()
        display_hat.set_backlight(True)
        draw_centred_text(img, "Radio Pi One", 10, font24, 0, 255, 0)
        read_radio(RP1_IP)
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "radio_1":
            ret = client.publish(MQTT_STATUS,"radio_1", qos=0, retain = True)
            OLDSCREEN = "radio_1"
        sleep(0.1)

    while DISPLAYSCREEN == "radio_2":
        clear_display()
        display_hat.set_backlight(True)
        draw_centred_text(img, "Radio Pi Two", 10, font24, 0, 0, 255)
        read_radio(RP2_IP)
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "radio_2":
            ret = client.publish(MQTT_STATUS,"radio_2", qos=0, retain = True)
            OLDSCREEN = "radio_2"
        sleep(0.1)

    while DISPLAYSCREEN == "weather":
        clear_display()
        display_hat.set_backlight(True)
        show_weather()
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "weather":
            ret = client.publish(MQTT_STATUS,"weather", qos=0, retain = True)
            OLDSCREEN = "weather"
        sleep(0.1)

    while DISPLAYSCREEN =="weatherd":
        clear_display()
        display_hat.set_backlight(True)
        show_weatherd()
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "weatherd":
            ret = client.publish(MQTT_STATUS,"weatherd", qos=0, retain = True)
            OLDSCREEN = "weatherd"
        sleep(0.1)

    while DISPLAYSCREEN == "news":
        clear_display()
        display_hat.set_backlight(True)
        show_news()
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "news":
            ret = client.publish(MQTT_STATUS,"news", qos=0, retain = True)
            OLDSCREEN = "news"
        sleep(0.1)

    while DISPLAYSCREEN =="news_redraw":
        clear_display()
        display_hat.display(img)
        if OLDSCREEN != "news_redraw":
            ret = client.publish(MQTT_STATUS,"news_redraw", qos=0, retain = True)
            OLDSCREEN = "news_redraw"
        DISPLAYSCREEN = "news"

    while DISPLAYSCREEN == "monitor":
        clear_display()
        display_hat.set_backlight(True)
        show_monitor()
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "monitor":
            ret = client.publish(MQTT_STATUS,"monitor", qos=0, retain = True)
            OLDSCREEN = "monitor"
        sleep(0.1)

    while DISPLAYSCREEN == "monitor_2":
        clear_display()
        display_hat.set_backlight(True)
        show_monitor_2()
        draw_tags()
        display_hat.display(img)
        if OLDSCREEN != "monitor_2":
            ret = client.publish(MQTT_STATUS,"monitor_2", qos=0, retain = True)
            OLDSCREEN = "monitor_2"
        sleep(0.1)

    while DISPLAYSCREEN =="blank":
        clear_display()
        display_hat.set_backlight(False)
        display_hat.display(img)
        if OLDSCREEN != "blank":
            ret = client.publish(MQTT_STATUS,"blank", qos=0, retain = True)
            OLDSCREEN = "blank"
        sleep(0.1)

    sleep(0.1)
