#!/usr/bin/env python3
import time
import mqtt_service as mqtt
import datetime
import traceback
from enum import Enum
import logging
import signal
logger = logging.getLogger(__name__)

class stateOfChargeMonitoringService(object):
    def __init__(self, broker            = "127.0.0.1",
                       port              = 1883,
                       user_name         = "",
                       password          = "",
                       customerID        = "",
                       VIN               = "",
                ):

        def inc_level(sig, frame):
            level = logger.getEffectiveLevel()
            if level == logging.CRITICAL:
                logger.setLevel(logging.ERROR)
            elif level == logging.ERROR:
                logger.setLevel(logging.WARNING)
            elif level == logging.WARNING:
                logger.setLevel(logging.INFO)
            elif level == logging.INFO:
                logger.setLevel(logging.DEBUG)
            print(f"Set logging to {logging.getLevelName(logger.getEffectiveLevel())}")

        def dec_level(sig, frame):
            level = logger.getEffectiveLevel()
            if level == logging.NOTSET:
                logger.setLevel(logging.DEBUG)
            elif level == logging.DEBUG:
                logger.setLevel(logging.INFO)
            elif level == logging.INFO:
                logger.setLevel(logging.WARNING)
            elif level == logging.WARNING:
                logger.setLevel(logging.ERROR)
            elif level == logging.ERROR:
                logger.setLevel(logging.CRITICAL)
            print(f"Set logging to {logging.getLevelName(logger.getEffectiveLevel())}")

        signal.signal(signal.SIGUSR2, inc_level)
        signal.signal(signal.SIGUSR1, dec_level)

        if customerID == "":
            self.stateTopic = "ev_charging/charge_state"
            self.percentTopic = "ev_charging/charge_percent"
        else:
            self.stateTopic = customerID + "/" + VIN + "/hanover/ev_charging/charge_state"
            self.percentTopic = customerID + "/" + VIN + "/hanover/ev_charging/charge_percent"

        self.mqttService = mqtt.mqttService("mqtt-monitoring-state-of-charge-service",
                                            broker    = broker,
                                            port      = port,
                                            user_name = user_name,
                                            password  = password)
        
        self.charge_percent_dictionary = {
            "atDateTime":        "",
            "chargeMeasuredAt":  "",
            "chargePercent":     0.0
        }

        self.charge_state_dictionary = {
            "atDateTime":        "",
            "chargingStartedAt": "",
            "chargingStoppedAt": "",
            "chargeState":       "",
            "voltageSeen":       0.0
        }

        self.charging_state = ""
        self.charge_percent = 0.0
    
    def setState(self, state) -> bool:
        if state != self.charging_state:
            self.charge_state = state
            self.charge_state_dictionary["chargeState"] = state
            return True
        else:
            return False

    def setPercent(self, percent) -> bool:
        if percent != self.charge_percent:
            self.charge_percent = percent
            self.charge_percent_dictionary["chargePercent"] = percent
            self.charge_percent_dictionary["chargeMeasuredAt"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
            return True
        else:
            return False

    def publishState(self):
        self.charge_state_dictionary["atDateTime"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
        logger.debug(f"publish - {self.stateTopic}\n{self.charge_state_dictionary}\n")
        self.mqttService.publish(self.stateTopic, self.charge_state_dictionary)

    def publishPercent(self):
        self.charge_percent_dictionary["atDateTime"] = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
        logger.debug(f"publish - {self.percentTopic}\n{self.charge_percent_dictionary}\n")
        self.mqttService.publish(self.percentTopic, self.charge_percent_dictionary)

if __name__ == "__main__":
    logger.info("Stop Request State Monitoring Service running in foreground")

    #use local broker to forward topics
    socMonService = stateOfChargeMonitoringService()
    
    socMonService.setState(ChargingState.CHARGING)
    socMonService.setPercent(90.0)

    #send topics direct to cloud
    #socMonService = stateOfChargeMonitoringService(broker           = "mqtt.ver.hanover.cloud",
    #                                              port              = 2023,
    #                                              user_name         = "1031_300",
    #                                              password          = "z3Qs38jn",
    #                                              customerID        = "1031",
    #                                              VIN               = "0")

    while 1:
        socMonService.publishState()
        socMonService.publishPercent()
        time.sleep(5)
