# chickenrobot - a controller for a coop door and cam controller
# author: <NAME> <<EMAIL>>
# date: Oct 2020
# license: MIT

import config
from comms import Comms
from light import Light
from door import Door
from camera import Camera
from time import sleep
from streamtologger import StreamToLogger
import sys
import logging
import pprint

# General psuedocode
#
# Listen for text/email [comms]
# Respond to text/email [comms]
# 	Send photos [comms]
# 	Report status
# 	Open door
# 	Close door
# Check for sunrise / sunset triggers [chickenrobot]
# 	Sleep in between checks [chickenrobot]
# 	Close door [door]
# 	Open door [door]
# 	Send status [comms]
# 	Send photos [comms]
# Open door [door]
# Close door [door]
# Take photo [cam]
# Get sunrise / sunset times [light]

class Chickenrobot(object):
    """controller class for a coop door and cam controller"""
    def __init__(self):
        #
        # instantiate all our classes
        self.comms = Comms(config.ORIGIN_NUM, config.TARGET_NUMS)
        self.light = Light(config.CITY_NAME, config.LATITUDE, config.LONGITUDE, config.SUNRISE_DELAY, config.SUNSET_DELAY)
        self.door = Door(config.REVS)
        self.camera = Camera(config.MAX_HORZ, config.MAX_VERT)

    def on_duty(self):
        while(1):
            #
            # Should the door be closed?
            #
            # Note: We don't test here if door is already closed
            # (door.is_closed()), because though it may take no action
            # with the doors, it might have to reset AUTO/MANUAL mode
            if self.light.is_dark():
                result = self.door.close_door_auto()
                # It will only return something if it moved the doors
                if result:
                    logging.info("Robot:Door status:%s", result)
                    # self.comms.send_text(result)
                    self.send_report_and_photos()
            #
            # Should the door be open?
            #
            # Note: We don't test here if door is already open
            # (door.is_open()), because though it may take no action
            # with the doors, it might have to reset AUTO/MANUAL mode
            elif self.light.is_light():
                result = self.door.open_door_auto()
                # It will only return something if it moved the doors
                if result:
                    logging.info("Robot:Door status:%s", result)
                    # self.comms.send_text(result)
                    self.send_report_and_photos()
            #
            # Check for messages
            #
            command_list = self.comms.check_for_commands()
            # print("command list:", command_list)
            logging.debug("Robot:Received from Comms:Command list:%s", pprint.pformat(command_list, indent=4))
            if command_list:
                for request_num, cmd in command_list:
                    logging.info("Robot:Handling command from %s:%s ", request_num, cmd)
                    if cmd == "photo" or cmd == "image" or cmd == "picture":
                        self.send_photos(request_num)
                    elif cmd == "close":
                        self.comms.send_text(self.door.close_door_manual(), request_num)
                    elif cmd == "open":
                        self.comms.send_text(self.door.open_door_manual(), request_num)
                    elif cmd == "status" or cmd == "report":
                        self.send_report_and_photos(request_num)
                    elif cmd == "door":
                        self.comms.send_text(self.door.report(), request_num)
                    elif cmd == "sun" or cmd == "light":
                        self.comms.send_text(self.light.report(), request_num)
                    elif cmd == "cam":
                        self.comms.send_text(self.camera.report(), request_num)
                    else:
                        txt = "Hi! I'm on duty. Helpful commands are status, photo, open, close, doors, sunset, sunrise, cameras."
                        self.comms.send_text(txt, request_num)
            sleep(5)
                # print('.')

    def report(self):
        msg_text = ""
        msg_text += "Hi! I'm on duty. "
        msg_text += self.door.report()
        msg_text += self.camera.report()
        msg_text += self.light.report()
        return(msg_text)

    def send_report(self, passed_num=None):
        status = self.report()
        self.comms.send_text(status, passed_num)

    def send_photos(self, passed_num=None):
        filename_array = self.camera.take_and_upload_images()
        self.comms.send_text_and_photos("Here's photos of the coop. ", filename_array, passed_num)

    def send_report_and_photos(self, passed_num=None):
        status_text = self.report()
        self.comms.send_text(status_text, passed_num)
        filename_array = self.camera.take_and_upload_images()
        image_text = "Here's photos of the coop. "
        self.comms.send_text_and_photos(image_text, filename_array, passed_num)
        self.comms.upload_status(status_text, image_text, filename_array)

def main():
    logging.basicConfig(
        filename=config.LOG_FILENAME,
        # encoding='utf-8',
        filemode='a',
        format='%(asctime)s %(levelname)s:%(message)s',
        level=config.LOG_LEVEL
    )
    logger = logging.getLogger("chickenrobot")
    # redirect stdout and stderr to log file
    sys.stdout = StreamToLogger(logger,logging.INFO)
    sys.stderr = StreamToLogger(logger,logging.ERROR)
    # logging.debug('This message should go to the log file')
    # logging.info('So should this')
    # logging.warning('And this, too')
    # logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
    logging.info("Robot:Starting")
    logging.info("Robot:I'm on duty.")

    # nuthin here yet
    chickenrobot = Chickenrobot()
    try:
        chickenrobot.on_duty()
    except KeyboardInterrupt:
        logging.info("Robot:I'm off duty.")
        logging.info("Robot:Finishing")
    except:
        logging.exception('Got exception on main handler')
        raise

if __name__ == '__main__':
    main()

# chickenrobot - a controller for a coop door and cam controller
# author: <NAME> <<EMAIL>>
# date: Oct 2020
# license: MIT

import config
from comms import Comms
from light import Light
from door import Door
from camera import Camera
from time import sleep
from streamtologger import StreamToLogger
import sys
import logging
import pprint

# General psuedocode
#
# Listen for text/email [comms]
# Respond to text/email [comms]
# 	Send photos [comms]
# 	Report status
# 	Open door
# 	Close door
# Check for sunrise / sunset triggers [chickenrobot]
# 	Sleep in between checks [chickenrobot]
# 	Close door [door]
# 	Open door [door]
# 	Send status [comms]
# 	Send photos [comms]
# Open door [door]
# Close door [door]
# Take photo [cam]
# Get sunrise / sunset times [light]

class Chickenrobot(object):
    """controller class for a coop door and cam controller"""
    def __init__(self):
        #
        # instantiate all our classes
        self.comms = Comms(config.ORIGIN_NUM, config.TARGET_NUMS)
        self.light = Light(config.CITY_NAME, config.LATITUDE, config.LONGITUDE, config.SUNRISE_DELAY, config.SUNSET_DELAY)
        self.door = Door(config.REVS)
        self.camera = Camera(config.MAX_HORZ, config.MAX_VERT)

    def on_duty(self):
        while(1):
            #
            # Should the door be closed?
            #
            # Note: We don't test here if door is already closed
            # (door.is_closed()), because though it may take no action
            # with the doors, it might have to reset AUTO/MANUAL mode
            if self.light.is_dark():
                result = self.door.close_door_auto()
                # It will only return something if it moved the doors
                if result:
                    logging.info("Robot:Door status:%s", result)
                    # self.comms.send_text(result)
                    self.send_report_and_photos()
            #
            # Should the door be open?
            #
            # Note: We don't test here if door is already open
            # (door.is_open()), because though it may take no action
            # with the doors, it might have to reset AUTO/MANUAL mode
            elif self.light.is_light():
                result = self.door.open_door_auto()
                # It will only return something if it moved the doors
                if result:
                    logging.info("Robot:Door status:%s", result)
                    # self.comms.send_text(result)
                    self.send_report_and_photos()
            #
            # Check for messages
            #
            command_list = self.comms.check_for_commands()
            # print("command list:", command_list)
            logging.debug("Robot:Received from Comms:Command list:%s", pprint.pformat(command_list, indent=4))
            if command_list:
                for request_num, cmd in command_list:
                    logging.info("Robot:Handling command from %s:%s ", request_num, cmd)
                    if cmd == "photo" or cmd == "image" or cmd == "picture":
                        self.send_photos(request_num)
                    elif cmd == "close":
                        self.comms.send_text(self.door.close_door_manual(), request_num)
                    elif cmd == "open":
                        self.comms.send_text(self.door.open_door_manual(), request_num)
                    elif cmd == "status" or cmd == "report":
                        self.send_report_and_photos(request_num)
                    elif cmd == "door":
                        self.comms.send_text(self.door.report(), request_num)
                    elif cmd == "sun" or cmd == "light":
                        self.comms.send_text(self.light.report(), request_num)
                    elif cmd == "cam":
                        self.comms.send_text(self.camera.report(), request_num)
                    else:
                        txt = "Hi! I'm on duty. Helpful commands are status, photo, open, close, doors, sunset, sunrise, cameras."
                        self.comms.send_text(txt, request_num)
            sleep(5)
                # print('.')

    def report(self):
        msg_text = ""
        msg_text += "Hi! I'm on duty. "
        msg_text += self.door.report()
        msg_text += self.camera.report()
        msg_text += self.light.report()
        return(msg_text)

    def send_report(self, passed_num=None):
        status = self.report()
        self.comms.send_text(status, passed_num)

    def send_photos(self, passed_num=None):
        filename_array = self.camera.take_and_upload_images()
        self.comms.send_text_and_photos("Here's photos of the coop. ", filename_array, passed_num)

    def send_report_and_photos(self, passed_num=None):
        status_text = self.report()
        self.comms.send_text(status_text, passed_num)
        filename_array = self.camera.take_and_upload_images()
        image_text = "Here's photos of the coop. "
        self.comms.send_text_and_photos(image_text, filename_array, passed_num)
        self.comms.upload_status(status_text, image_text, filename_array)

def main():
    logging.basicConfig(
        filename=config.LOG_FILENAME,
        # encoding='utf-8',
        filemode='a',
        format='%(asctime)s %(levelname)s:%(message)s',
        level=config.LOG_LEVEL
    )
    logger = logging.getLogger("chickenrobot")
    # redirect stdout and stderr to log file
    sys.stdout = StreamToLogger(logger,logging.INFO)
    sys.stderr = StreamToLogger(logger,logging.ERROR)
    # logging.debug('This message should go to the log file')
    # logging.info('So should this')
    # logging.warning('And this, too')
    # logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
    logging.info("Robot:Starting")
    logging.info("Robot:I'm on duty.")

    # nuthin here yet
    chickenrobot = Chickenrobot()
    try:
        chickenrobot.on_duty()
    except KeyboardInterrupt:
        logging.info("Robot:I'm off duty.")
        logging.info("Robot:Finishing")
    except:
        logging.exception('Got exception on main handler')
        raise

if __name__ == '__main__':
    main()

# chickenrobot - a controller for a coop door and cam controller # author: <NAME> <<EMAIL>> # date: Oct 2020 # license: MIT # General psuedocode # # Listen for text/email [comms] # Respond to text/email [comms] # 	Send photos [comms] # 	Report status # 	Open door # 	Close door # Check for sunrise / sunset triggers [chickenrobot] # 	Sleep in between checks [chickenrobot] # 	Close door [door] # 	Open door [door] # 	Send status [comms] # 	Send photos [comms] # Open door [door] # Close door [door] # Take photo [cam] # Get sunrise / sunset times [light] controller class for a coop door and cam controller # # instantiate all our classes # # Should the door be closed? # # Note: We don't test here if door is already closed # (door.is_closed()), because though it may take no action # with the doors, it might have to reset AUTO/MANUAL mode # It will only return something if it moved the doors # self.comms.send_text(result) # # Should the door be open? # # Note: We don't test here if door is already open # (door.is_open()), because though it may take no action # with the doors, it might have to reset AUTO/MANUAL mode # It will only return something if it moved the doors # self.comms.send_text(result) # # Check for messages # # print("command list:", command_list) # print('.') # encoding='utf-8', # redirect stdout and stderr to log file # logging.debug('This message should go to the log file') # logging.info('So should this') # logging.warning('And this, too') # logging.error('And non-ASCII stuff, too, like Øresund and Malmö') # nuthin here yet