# Path: braubuddy/output/base.py
# class IOutput(object):
#     """
#     Interface for creating an output for use with :mod:`braubuddy`.
# 
#     :param units: Temperature units to output.
#     :type units: :class:`str`
#     """
# 
#     __metaclass__ = abc.ABCMeta
# 
#     def __init__(self, units='celsius'):
# 
#         self.set_units(units)
# 
#     def set_units(self, new_units):
#         """
#         Set units to output.
# 
#         :param units: Temperature units to output.
#         :type units: :class:`str`
#         """
# 
#         try:
#             self.units = utils.map_temp_units_to_symbol(new_units)
#         except:
#             raise OutputError('Unrecognised units: {0}'.format(new_units))
# 
#     @abc.abstractmethod
#     def publish_status(self, target, temp, heater_percent, cooler_percent):
#         """
#         Publish braubuddy status
# 
#         :param target: Target temperature.
#         :type target: :class:`float`
#         :param temp: Current temperature.
#         :type temp: :class:`float`
#         :param heater_percent: Current heater power level as percentage.
#         :type heater_percent: :class:`float`
#         :param cooler_percent: Current cooler power level as percentage.
#         :type coolerer_percent: :class:`float`
#         """
# 
# Path: braubuddy/output/base.py
# class OutputError(Exception):
#     """
#     Raised whenever an output fails
#     """


import json
import time
from os.path import expanduser
from cherrypy import log
from braubuddy.output import IOutput
from braubuddy.output import OutputError
        super(JSONFileOutput, self).__init__(units)

    def publish_status(self, target, temp, heater_percent, cooler_percent):

        # Load status history from JSON
        try:
            with open(self._out_file, 'r') as fh:
                status_history = json.loads(fh.read())
        except (IOError, ValueError):
            # No existing file or invalid JSON so start with no datapoints
            status_history = []
        # Get timestamp in epoch seconds
        timestamp = int(time.time())
        # Create new status
        status = [target, temp, heater_percent, cooler_percent, timestamp]
        # Add new status to previous data
        status_history.append(status)
        # Drop datapoints if limit exceeded
        if self._datapoint_limit != 0:
            while len(status_history) > self._datapoint_limit:
                # Discard oldest status datapoint
                log('Datapoint limit exceeded - dropping earliest datapoint: '
                    '{0!r}'.format(status_history[0]))
                status_history.pop(0)
        # Write status history JSON to file
        new_json = json.dumps(status_history)
        try:
            with open(self._out_file, 'w+') as fh:
                fh.write(new_json)
        except (IOError, ValueError) as err:

# Path: braubuddy/output/base.py
# class IOutput(object):
#     """
#     Interface for creating an output for use with :mod:`braubuddy`.
# 
#     :param units: Temperature units to output.
#     :type units: :class:`str`
#     """
# 
#     __metaclass__ = abc.ABCMeta
# 
#     def __init__(self, units='celsius'):
# 
#         self.set_units(units)
# 
#     def set_units(self, new_units):
#         """
#         Set units to output.
# 
#         :param units: Temperature units to output.
#         :type units: :class:`str`
#         """
# 
#         try:
#             self.units = utils.map_temp_units_to_symbol(new_units)
#         except:
#             raise OutputError('Unrecognised units: {0}'.format(new_units))
# 
#     @abc.abstractmethod
#     def publish_status(self, target, temp, heater_percent, cooler_percent):
#         """
#         Publish braubuddy status
# 
#         :param target: Target temperature.
#         :type target: :class:`float`
#         :param temp: Current temperature.
#         :type temp: :class:`float`
#         :param heater_percent: Current heater power level as percentage.
#         :type heater_percent: :class:`float`
#         :param cooler_percent: Current cooler power level as percentage.
#         :type coolerer_percent: :class:`float`
#         """
# 
# Path: braubuddy/output/base.py
# class OutputError(Exception):
#     """
#     Raised whenever an output fails
#     """


# Path: braubuddy/output/jsonfile.py
import json
import time
from os.path import expanduser
from cherrypy import log
from braubuddy.output import IOutput
from braubuddy.output import OutputError

        super(JSONFileOutput, self).__init__(units)

    def publish_status(self, target, temp, heater_percent, cooler_percent):

        # Load status history from JSON
        try:
            with open(self._out_file, 'r') as fh:
                status_history = json.loads(fh.read())
        except (IOError, ValueError):
            # No existing file or invalid JSON so start with no datapoints
            status_history = []
        # Get timestamp in epoch seconds
        timestamp = int(time.time())
        # Create new status
        status = [target, temp, heater_percent, cooler_percent, timestamp]
        # Add new status to previous data
        status_history.append(status)
        # Drop datapoints if limit exceeded
        if self._datapoint_limit != 0:
            while len(status_history) > self._datapoint_limit:
                # Discard oldest status datapoint
                log('Datapoint limit exceeded - dropping earliest datapoint: '
                    '{0!r}'.format(status_history[0]))
                status_history.pop(0)
        # Write status history JSON to file
        new_json = json.dumps(status_history)
        try:
            with open(self._out_file, 'w+') as fh:
                fh.write(new_json)
        except (IOError, ValueError) as err:

            raise OutputError(err)