#!/usr/bin/python3
# coding: utf-8

from syslog import *
import smtplib, ssl
from email.mime.text import MIMEText
from urllib.request import urlopen
from urllib.parse import quote_plus


#################################
### <user defined parameters> ###

alertTemp       = 63     # Hot cpu core temperature threshold

domoticzUrl     = ''     # Domoticz server address such as 'http://192.168.0.22:8080'
tempSensorIdx   = 0      # Domoticz idx of temperature sensor, if 0 only logs temperature
tempAlertIdx    = 0      # Domoticz idx of alert sensor, if 0 then ignored
thermalZone     = 0      # Read temp in /sys/class/thermal/thermal_zone{thermalZone}/temp
domoticzTimeout = 10     # timeout in seconds on http requests to Domoticz

logIdent        = ''         # syslog programname, if empty then default program name used
loglevel        = LOG_ERR    # log messages of tht urgency or above will be sent to syslog
logAlertLevel   = LOG_ALERT  # Use LOG_ALERT to send the temperature alert to syslog

alertTitle      = 'Surchauffe HA-Bridge'
alertMsg        = 'La température de l\'Orange Pi Zero est de {}° C ce qui dépasse le niveau d\'alarme de {}°C'

emailTarget     = 'your.destination@email.com'  
emailSender     = 'your@email.address'
smtpServer      = 'your.smtp.server'
smtpPort        = 465
smtpUser        = emailSender
smtpPwd         = 'your_smpt_password'

verbose         = 1   # = 0 nothing sent to console
                      # = 1 log messages up to loglevel are echoed to console
                      # = 2 all log messages are sent to the console
                            # If loglevel= LOG_DEBUG this is the same as
                            # verbose = 1

### </user defined parameters> ###
##################################


# Json formatted Domoticz http query for setting a temperature sensor value
domoticzQuery = '/json.htm?type=command&param=udevice&idx={}&nvalue={}&svalue={}'


# Routine to send messages to syslog and echo it to the console
def log(level, msg):
  if (verbose == 2) or (verbose and (level <= loglevel)): print(msg)
  syslog(level, msg)


# Routine to send alert to log and send email notification
def alert(title, message):
  log(LOG_DEBUG, 'Alert, title: \'{}\', message \'{}\''.format(title, message))

  log(logAlertLevel, message)

  log(LOG_DEBUG, 'Sending email notification')
  # Create the message
  msg = MIMEText(message)
  msg['Subject'] = title
  msg['From'] = emailSender
  msg['To'] = emailTarget

  # Send it
  context = ssl.create_default_context()
  with smtplib.SMTP_SSL(smtpServer, smtpPort, context=context) as server:
    server.login(smtpUser, smtpPwd)
    server.sendmail(emailSender, emailTarget, msg.as_string())
  log(LOG_DEBUG, 'Alert completed')

# Routine to send HTTP request to Domoticz
def sendQuery(query):
  url = domoticzUrl + query
  log(LOG_DEBUG, 'Domoticz url: {}'.format(url))
  try:

    # send the request with a timeout
    hf = urlopen(url, timeout=domoticzTimeout)

    # get Domoticz' response and broadcast it
    response = hf.read().decode('utf-8')
    if ('"ERR"') in response:
      llevel = LOG_ERR
    else:
      llevel = LOG_DEBUG
    log(llevel, 'Domoticz response: {}'.format(response))
    hf.close

  except Exception as e:
    log(LOG_ERR, 'Exception: {}'.format(e))


## starting script!

log(LOG_DEBUG, 'Starting {}, reading thermal_zone {}'.format(__file__, thermalZone))

if logIdent:
  openlog(ident=logIdent)
  log(LOG_DEBUG, 'openlog(ident={})'.format(logIdent))

setlogmask(LOG_UPTO(loglevel))

# Read cpu temperature
cputemp = int(open('/sys/class/thermal/thermal_zone{}/temp'.format(thermalZone)).read()) / 1000.0
cpuTemp = "{0:0.1f}".format(cputemp)

# Send the information message to syslog
log(LOG_INFO, 'CPU temperature: {}° C'.format(cpuTemp))

# Send the alert message if necessary to syslog and email
if cputemp > alertTemp:
  alert(alertTitle, alertMsg.format(cpuTemp, alertTemp))

if not domoticzUrl:
  log(LOG_DEBUG, 'No Domoticiz URL defined')
else:
  # Send the temperature to Domoticz temperature sensor if idx given
  if tempSensorIdx <= 0:
    log(LOG_DEBUG, 'No Domoticiz temperature sensor idx defined')
  else:
    sendQuery(domoticzQuery.format(tempSensorIdx, 0, cpuTemp))

  # Send the colour value and text to Domoticz alert sensor if idx given
  if tempAlertIdx <= 0:
    log(LOG_DEBUG, 'No Domoticiz temperature alert sensor idx defined')
  else:
    if cputemp > alertTemp:
      value = 4 # red
    elif cputemp > int(0.9*alertTemp):
      value = 3 # orange
    elif cputemp > int(0.8*alertTemp):
      value = 2 # yellow
    else:
      value = 1 # green
    sendQuery(domoticzQuery.format(tempAlertIdx, value, quote_plus('Température de l\'Orange Pi Zero temperature: {}° C'.format(cpuTemp))))
