#!/home/nestor/.domopy/bin/python
# coding: utf-8

# Python script to read the temperature and humidity data from a DHTXX sensor
# and the CPU temperature and send the results to a Domoticz server. Meant to
# be executed by cron at regular intervals.
#
# Requires: Python 3 and the (deprecated) Adafruit DHT Python library
#           available at https://github.com/adafruit/Adafruit_Python_DHT
#
# Author:  Michel Deslierres
# Version: 1.1
# Date:    2020-01-14
# License: Simplified BSD license
'''
Copyright (c) 2019 and 2020, Michel Deslierres


Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''

# Needed module here because LOG_XXX constants are used in parameters
from syslog import *

# User defined parameters -------------------------------------------------------
DHT_type        = 11  # 0 for none, 11 or 12 for DHT11 or DHT12
DHT_pin         = 24  # Raspeberry Pi GPIO24 which is header pin 18
cpu_zone        = "/sys/class/thermal/thermal_zone0/temp"
room_temp_idx   = 35  # Domoticz device index for ambient temperature and humidity sensor
cpu_temp_idx    = 36  # Domoticz device index for cpu temperature sensor
domoticzJson    = "http://192.168.0.45:9071/json.htm?type=command&param=udevice&idx={}&nvalue=0&svalue={}"
domoticzTimeout = 10        # HTTP request timeout in seconds
verbose         = 1         # 0 quiet, 1 to echo log messages with priority
consoleloglevel = LOG_INFO  #     >= consoleloglevel to the console
sysloglevel     = LOG_ERR   # priority level for messages sent to syslog
# -------------------------------------------------------------------------------

# Needed modules in addition to syslog
import sys
from urllib.request import urlopen  # with python 3.x, use "from urllib2 import urlopen"  with python 2.7
import Adafruit_DHT
if verbose > 0:
  from datetime import datetime

# Routine to send messages to syslog and echo it to the console
def log(level, msg):
  syslog(level, msg)
  if (verbose) and (level <= consoleloglevel):
    print(datetime.now().strftime('%Y-%m-%d %H:%M:%S ') + msg)

# Setup syslog
openlog(ident='nestor')
setlogmask(LOG_UPTO(sysloglevel))

# HTTP Get request
def httpRequest(url):
  log(LOG_DEBUG, 'CPU: Domoticz GET request: {}'.format(url))
  # use context magager which takes care of closing hf
  with urlopen(url, timeout=domoticzTimeout) as hf:
    try:
      # 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))

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

# Get ambient temperature and humidity data from sensor
def ambientTemperature():
  if not ( (DHT_type == 11) or (DHT_type == 12) ):
    log(LOG_DEBUG, 'DHT: sensor not defined')
    return

  bad_data = True;
  delay = 2;

  while (bad_data and (delay <= 8)) :
    humidity, temperature = Adafruit_DHT.read_retry(DHT_type, DHT_pin, 3, delay)
    bad_data = (humidity is None) or (temperature is None)
    if bad_data:
      log(LOG_DEBUG, 'DHT: read error after 3 tries at {} second intervals'.format(delay))
      delay = delay*2

  if bad_data:
    log(LOG_ERR, 'DHT: could not read ambient temperature data')
    return

  log(LOG_INFO, 'DHT: temp = {0:0.1f}°C, humid = {1:0.1f}%'.format(temperature, humidity))

  if humidity > 60:
    HUM_STAT = '3'      # wet
  elif humidity > 25:
    HUM_STAT = '1'      # comfortable
  else:
    HUM_STAT = '2'      # dry

  svalue = '{0:0.1f};{1:0.1f};{2}'.format(temperature, humidity, HUM_STAT)
  httpRequest(domoticzJson.format(room_temp_idx, svalue))


# Read and report ambient temperature and humdity
ambientTemperature()

# Read and report cpu temperature
cputemp = int(open(cpu_zone).read()) / 1000.0
cpuTemp = "{0:0.1f}".format(cputemp)
log(LOG_INFO, 'CPU: temp = {}°C'.format(cpuTemp))
httpRequest(domoticzJson.format(cpu_temp_idx, cpuTemp))
