# ----------------------------------------------------------------------------
#       Copyright (C) 2013-2014 Huynh Vi Lam  <domovilam@gmail.com>
#
#       This file is part of pimucha.
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#	
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ----------------------------------------------------------------------------

import datetime,logging
from piHAlibs import (coroutine,db2dict,majdb3,ralldb3,reqdb3)
from .actions import launchaction
from .sensors2 import (SensorEvent,updatesensorevent)

logger = logging.getLogger()


# ----------------------------------------------------------------------------
# Compare value with limit value 
# for a parameter from sensor events received from 
# Oregon temperature sensor
# Event in : data decoded for one parameter Temperature of the sensor
# item : ['RFX0:RFXCOM', '2013-08-01', '21:46:24', 'sensor', 'oreTemp', '0x1a2d_0xb6', '30.1']
# If result comparison is True :
# Generate an event out
# Send to next targets
# ----------------------------------------------------------------------------
@coroutine
def sensoraction(targets):
    updatesensorevent()
    req = "SELECT rowId,parameter,modaddrId,namelimits,limits,cv2pv,period,script,msg,applied FROM sensorlimits "
    req += " WHERE enabled = 'True'"
    SensorLimits = ralldb3(req,[])
    #SensorLimits:[rowId,parameter,modaddrId,namelimits,limits,cv2pv,period,script,msg,applied]
    #SensorEvent:[namelimits,applied,lastdtevent,lastvalue]
    while True:
        item = (yield)
        logger.debug("Event receive %s",repr(item))
        if item[3] != 'sensor': continue
        for row in SensorLimits:
            if not ((item[4] == row[1]) and (item[5] == row[2])): continue
            namelimits = row[3]
            if SensorEvent[namelimits] == 'False':continue
            pv = SensorEvent[namelimits][3]	#previous value
            cv = float(item[6])			#current value
            if cv == pv:
                logger.debug("No change in value %s",repr(cv))
                continue
            lastime = datetime.datetime.strptime(SensorEvent[namelimits][2],'%Y-%m-%d %H:%M:%S')
            d = item[1] + ' ' + item[2]
            curtime = datetime.datetime.strptime(d,'%Y-%m-%d %H:%M:%S')
            period = curtime - lastime
            try:
                l = eval(row[4])
            except Exception as e:
                logger.error("%s : %s", repr(e.__class__), str(e))
                logger.error("Error evaluating of limits %s with value %s",repr(row[4]),item[6])
                continue
            if not l:
                logger.debug("No new event, value %s not within limits %s",item[6],repr(row[4]))
                continue
            logger.debug("New event, value %s is within limits %s",item[6],repr(row[4]))
            if row[5] != '':
                try:
                    t = eval(row[5])
                except Exception as e:
                    logger.error("%s : %s", repr(e.__class__), str(e))
                    logger.error("Error evaluating of trend %s with values %s",repr(row[5]),repr((pv,cv)))
                    continue
            if period < datetime.timedelta(hours=row[6]):
                if not t:
                    logger.debug("No new event, trend is False within period of %s hours",row[6])
                    continue
                else:
                    logger.debug("Trend %s is True between previous %s and current value %s",repr(row[5]),str(pv),item[6])
                    SensorEvent[namelimits][3] = cv
                    continue
            logger.debug("New period of %s hours",row[6])
            SensorEvent[namelimits][2] = d
            SensorEvent[namelimits][3] = cv
            script = row[7]
            item += [namelimits,row[8]]
            logger.debug("New sensor limits event %s detected at %s",repr(item),curtime)
            for target in targets:
                target.send(item)
        launchaction(['SCRIPT',script])
