예제 #1
0
    def generate(self, lower_t, upper_t) -> None:
        """Randomly generates home

        :param lower_t: lower temperature gradient (used for determining temperature color of home)
        :type lower_t: int
        :param upper_t: higher temperature gradient (used for determining temperature color of home)
        :type upper_t: int
        :return: Nothing
        """

        # convert sizes to m
        self.length = ft2m(self.length)
        self.width = ft2m(self.width)
        self.height = ft2m(self.height)

        self._lower_temp_grad = lower_t
        self._upper_temp_grad = upper_t

        # select wall material properties
        wall_type = random.randint(1, 3)
        if wall_type == 1:
            self.walls = material.LowEfficiency()
        elif wall_type == 2:
            self.walls = material.MedEfficiency()
        elif wall_type == 3:
            self.walls = material.HighEfficiency()
        else:
            self.walls = material.BrickWall()

        self.sharedInfo[0] = self.outside_temp.value
        self.sharedInfo[1] = 101325  # internal pressure, PA
        self.temp_history.append(self.sharedInfo[0])

        sizes = [self.length, self.width, self.height]
        self.thermostat = Thermostat(sizes, self.sharedInfo, self.world_clock, self.logger)
예제 #2
0
class Extender:
    def __init__(self, thermostatName, target):
        logger.info("Initializing extender")
        self.sensor = Sensor()
        self.thermostat = Thermostat(thermostatName)
        self.reporter = Reporter()
        self.target = target

    def startPoller(self, interval):
        logger.info("Starting poller")
        while True:
            try:
                self.poll()
            except Exception as e:
                logger.error("Could not complete run: {}".format(e.message))
            logger.info("Sleeping for {} seconds".format(interval))
            sleep(interval)

    def poll(self):
        temperature = self.sensor.getCurrentTemp()
        thermostatTarget = self.thermostat.thermostat.target
        thermostatTemp = self.thermostat.thermostat.temperature
        self.reporter.send('thermostat_target', thermostatTarget)
        self.reporter.send('thermostat_temp', thermostatTemp)
        self.reporter.send('sensor_temp', temperature)
        if temperature == -1:
            logger.info("Got a bad reading from the sensor, try again later")
            pass
        elif temperature >= self.target:
            logger.info("Temperature was hot enough")
            self.thermostat.heatOff()
        else:
            logger.info("Temperature was too cold")
            self.thermostat.heatOn()
예제 #3
0
 def test_dont_keep_heater_on_forever(self):
     # use the real heater controller, not the test heater
     self.heater = HeaterCycleProtection(self.clock)
     self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)
     self.thermostat.set_mode('on')
     # advance to just before time limit
     self.clock.advance(minutes=59)
     self.thermostat.iterate()
     self.assertTrue(self.heater.is_on())
     # advance past limit, heater should go off
     self.clock.advance(minutes=1)
     self.thermostat.iterate()
     self.assertFalse(self.heater.is_on())
예제 #4
0
def main():
    home_thermostat = Thermostat(update_server)
    thermostat_server = create_server(home_thermostat.update_set_temperature)
    try:
        thermostat_thread = Thread(target=home_thermostat.run)
        #server_thread.daemon = True
        thermostat_thread.start()
        thermostat_server.run(host='0.0.0.0')
    except Exception as e:
        print('An Exception Occured!')
        print(e.message)
    finally:
        home_thermostat.shutdown()
예제 #5
0
def open_thermostat(config):
    ip = config.get(
        'secret', {
            "ip": "192.168.0.100"}).get(
        'ip', '192.168.0.100')
    tempVariableId = int(
        config.get(
            'global', {
                "tempvariable": "28"}).get(
            'tempvariable', '28'))
    setpointDayVariableId = config.get(
        'global', {
            "setpointdayvariable": "29"}).get(
        'setpointdayvariable', '29')
    setpointNightVariableId = config.get(
        'global', {
            "setpointnightvariable": "29"}).get(
        'setpointnightvariable', '30')
    modeVariableId = config.get(
        'global', {
            "modevariable": "29"}).get(
        'modevariable', '31')
    stateVariableId = config.get(
        'global', {
            "statevariable": "13"}).get(
        'statevariable', '13')
    thermostatScenarioId = config.get(
        'global', {
            "thermostatscenario": "17"}).get(
        'thermostatscenario', '17')
    thermostatProbeId = config.get(
        'global', {
            "thermostatprobeid": "13"}).get(
        'thermostatprobeid', '13')
    thermostat = Thermostat(
        ip,
        int(tempVariableId),
        int(setpointDayVariableId),
        int(setpointNightVariableId),
        int(modeVariableId),
        int(stateVariableId),
        int(thermostatScenarioId),
        int(thermostatProbeId))

    logger.debug(" Address ip zibase:{}".format(ip))
    logger.debug(" Indoor Temperature:{}".format(
        thermostat.tempStr(thermostat.getTemp() / 10.0)))
    logger.debug(" Thermostat Mode:{}".format(thermostat.getModeString()))
    logger.debug(" Thermostat State:{}".format(thermostat.getStateString()))
    logger.debug(" Thermostat runMode:{}".format(
        thermostat.getRunModeString()))
    logger.debug(" setpoint Day:  {}°C".format(
        thermostat.getSetpointDay() / 10.0))
    logger.debug(" setpoint Night:{}°C".format(
        thermostat.getSetpointNight() / 10.0))
    return thermostat
예제 #6
0
파일: server.py 프로젝트: ostlerc/webpy
    def PATCH(self, ID):
        thermostat = Thermostat.find(int(ID))
        if thermostat is None:
            raise web.notfound()

        # parse and validate patch input data
        try:
            fields = json.loads(web.data())
        except ValueError:
            raise BadRequest("invalid JSON")

        if not isinstance(fields, dict):
            raise BadRequest("invalid JSON")

        # validate all keys are correct before mutating
        for field in fields:
            if not isinstance(field, basestring):
                raise BadRequest("invalid JSON")
            if not hasattr(thermostat, field) or field in ["temperature", "ID"]:
                raise UnprocessableEntity("invalid field {}".format(field))

        try:
            for field in fields:
                setattr(thermostat, field, fields[field])
        except TypeError:
            raise UnprocessableEntity("invalid type for field {}".format(field))
        except ValueError:
            raise UnprocessableEntity("invalid value for field {}".format(field))

        return ""
    def add_thermostat(self, location_id, location_name, thermostat, update):
        t_name = location_name + ' - ' + thermostat['userDefinedDeviceName']
        t_device_id = thermostat['deviceID']
        t_addr = thermostat['macID'].lower()
        use_celsius = thermostat['units'].lower() != 'fahrenheit'

        LOGGER.debug('Adding thermostat with id {0} and name {1} and addr {2}'.format(t_device_id, t_name, t_addr))
        self.addNode(Thermostat(self, t_addr, t_addr, t_name, self._api, location_id, t_device_id, use_celsius), update)

        if 'groups' not in thermostat:
            return

        for group in thermostat['groups']:
            group_id = group['id']

            sensors = self._api.get_sensors(location_id, t_device_id, group_id)
            for sensor in sensors.rooms:
                if len(sensor.accessories) == 0:
                    continue

                # TODO: Do we ever have to care about multiple accessory blocks?
                sensor_type = sensor.accessories[0].accessory_attribute.type
                sensor_name = sensor.name
                sensor_addr = t_addr + str(group_id) + str(sensor.id)

                if sensor_type == 'IndoorAirSensor' or sensor_type == 'Thermostat':
                    LOGGER.debug('Adding IndoorAirSensor with name {0} and addr {1} for thermostat {2}'.format(sensor_name, sensor_addr, t_addr))
                    self.addNode(IndoorAirSensor(self, t_addr, sensor_addr, sensor_name, self._api, location_id, t_device_id, group_id, sensor.id, use_celsius))
예제 #8
0
    def setUp(self):
        # create instances
        self.heater = TestHeater()
        self.thermometer = TestThermometer()
        self.clock = TestClock()
        self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)

        # setup testing environment
        # in the beginning, temperature is above threshold, heater is off, both exceptions are on
        self.clock.set_clock(0)
        self.thermometer.temperature = 68
        self.heater._is_turned_on = False
        self.heater.exception_if_turned_on = True
        self.heater.exception_if_turned_off = True

        # start thermostat in target mode with target=68 (thresholds of 67/69)
        self.thermostat.set_target_temperature(68)
        self.thermostat.set_mode('target')
예제 #9
0
파일: server.py 프로젝트: ostlerc/webpy
    def GET(self, ID):
        params = web.input(fields=None)
        try:
            thermostat = Thermostat.find(int(ID))
            if thermostat is None:
                raise web.notfound()

            return json.dumps(thermostat, default=lambda o: o.json(params.fields), indent=4)
        except KeyError as e:
            raise UnprocessableEntity("invalid field {}".format(e))
예제 #10
0
 def test_dont_keep_heater_on_forever(self):
     # use the real heater controller, not the test heater
     self.heater = HeaterCycleProtection(self.clock)
     self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)
     self.thermostat.set_mode('on')
     # advance to just before time limit
     self.clock.advance(minutes=59)
     self.thermostat.iterate()
     self.assertTrue(self.heater.is_on())
     # advance past limit, heater should go off
     self.clock.advance(minutes=1)
     self.thermostat.iterate()
     self.assertFalse(self.heater.is_on())
예제 #11
0
    def test_should_heat(self):
        mock_temp_sensor_reader = MockTempSensorReader("")
        mock_temp_sensor_reader.set_temperature(10.0)
        thermostat = Thermostat(mock_temp_sensor_reader)

        thermostat.set_target_temperature(20.0)

        self.assertTrue(thermostat.should_heat())

        mock_temp_sensor_reader.set_temperature(25.0)
        self.assertFalse(thermostat.should_heat())
예제 #12
0
    def setUp(self):
        # create instances
        self.heater = TestHeater()
        self.thermometer = TestThermometer()
        self.clock = TestClock()
        self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)

        # setup testing environment
        # in the beginning, temperature is above threshold, heater is off, both exceptions are on
        self.clock.set_clock(0)
        self.thermometer.temperature = 68
        self.heater._is_turned_on = False
        self.heater.exception_if_turned_on = True
        self.heater.exception_if_turned_off = True

        # start thermostat in target mode with target=68 (thresholds of 67/69)
        self.thermostat.set_target_temperature(68)
        self.thermostat.set_mode('target')
예제 #13
0
class TestThermostat(unittest.TestCase):
    def setUp(self):
        self.thermostat = Thermostat("Upstairs")

    def test_heatOn(self):
        self.thermostat.heatOn()
        sleep(10)
        self.assertEqual(self.thermostat.getThermostatByName("Upstairs").hvac_state, 'heating')

    def test_heatOff(self):
        self.thermostat.heatOff()
        sleep(10)
        self.assertEqual(self.thermostat.getThermostatByName("Upstairs").hvac_state, 'off')
예제 #14
0
 def initFromDataFile(self):
     data = self.fileService.getComponents(self.dataFileName)
     if "components" not in data:
         raise BadHomeDataFileFormatError(
             "Home data JSON file missing key \"{0}\"".format("components"))
     for comp in data["components"]:
         if comp["name"] in self.data:
             raise BadHomeDataFileFormatError(
                 "Duplicate component name \"{0}\" found in file".format(
                     comp["name"]))
         if comp["type"] == "Thermostat":
             self.data[comp["name"]] = Thermostat(comp["name"],
                                                  comp["temperature"])
         elif comp["type"] == "Light":
             self.data[comp["name"]] = Light(comp["name"], comp["status"])
         else:
             logging.warning(
                 "InMemoryRepository.initFromDataFile - Component with name \"{0}\" not recognized, will not be included in initial data"
                 .format(comp["name"]))
예제 #15
0
파일: main.py 프로젝트: Munken/eco2mqtt
def _load_settings(settings, guess_mode):
    with open(settings) as f:
        raw = safe_load(f)

        parsed = {}
        for thermo in raw["thermostats"]:
            name = thermo["name"]
            addr = thermo["address"]
            secret = bytes.fromhex(thermo["secret"])
            set_point = thermo["set_point"]
            offset = float(thermo["offset"])
            remote_topic = thermo.get("remote")

            parsed[addr] = Thermostat(name=name,
                                      addr=addr,
                                      secret=secret,
                                      set_points=set_point,
                                      offset=offset,
                                      remote_topic=remote_topic,
                                      guess_mode=guess_mode)
        return parsed
예제 #16
0
from config import Config

from LCD_1602 import LCD_1602
from ds1820 import DS1820
from thermostat import Thermostat
from thermometre import Thermometre

import time

ECO = 1
CONF = 2


if __name__ == '__main__':
    config = Config()
    consigne = Thermostat(config)
    GPIO.setwarnings = False
    thermometre = Thermometre()
    lcd = LCD_1602(config.pin['rs'], config.pin['e'], config.pin['db'], config.pin['GPIO'])
    sondes = DS1820("/sys/bus/w1/devices/", ("28-011561577dff", "28-0115615a35ff"))
    channel = 23
    GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    try:
        GPIO.add_event_detect(channel, GPIO.BOTH, callback=thermometre.change_mode, bouncetime=75)
        while True:
            now = time.localtime()
            thermometre.read_temp(sondes)
            thermometre.save_temp(now, 1)
            (mode, temp_consigne) = consigne.get_tranche_infos(config.conf, now)
            status = consigne.get_status(thermometre.get_temp(1), temp_consigne)
            lcd.clear()
예제 #17
0
파일: server.py 프로젝트: ostlerc/webpy
 def GET(self):
     params = web.input(fields=None)
     try:
         return json.dumps(Thermostat.all(), default=lambda o: o.json(params.fields), indent=4)
     except KeyError as e:
         raise UnprocessableEntity("invalid field {}".format(e))
예제 #18
0
from PySide2 import QtWidgets
from thermostat import Room, Sensor, Actuator, Thermostat, OutsideTemperature
from thermostat_gui import MyWidget
from test_framework import TestCase, TestRunner
import threading
import time
import sys

outside_temperature = 20.
target_temperature = 22.

room = Room(outside_temperature)
sensor = Sensor(room)
actuator = Actuator(room)
thermostat = Thermostat(sensor, actuator, target_temperature)
outside_temperature_mod = OutsideTemperature(room, outside_temperature)

tc0 = TestCase(name="Heat if current temperature is below target",
         preconditions=[
           lambda: actuator.state == "OFF",
           lambda: room.temperature < thermostat.target - thermostat.slack
         ],
         invariants=[
           lambda: actuator.state == "HEATING"
         ],
         invariants_at_least_once=True,
         postconditions=[
           lambda: actuator.state == "OFF",
           lambda: room.temperature >= thermostat.target - thermostat.slack,
           lambda: room.temperature <= thermostat.target + thermostat.slack
         ])
예제 #19
0
def format_date(d):
    return "%d/%d" % (d[1], d[2])


def format_datetime_short(t):
    return time.strftime("%Y%m%dT%H%M%S", time.localtime(t))


logging.basicConfig(level="INFO")

app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

thermostat = Thermostat(pref_file="prefs/thermostat.json",
                        schedule_file="prefs/schedule.json",
                        runhistory_file="prefs/usage.csv",
                        activitydata_file="prefs/activity.csv",
                        tempdata_file="prefs/stats.csv")

dayNames = [
    "Every Day", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
    "Saturday", "Sunday"
]
timeCommandRE = re.compile(
    "(deleteTime|ignoreTime)([0-7])([0-2][0-9])([0-5][0-9])")


def simpleStats():
    (last_temp, last_humi) = thermostat.getLastReading()
    if last_temp != None:
        last_temp = round(last_temp, 2)
예제 #20
0
 def test_read_temperature(self):
     self.home.repository.get = MagicMock(
         return_value=Thermostat("Thermostat", temp=68))
     self.assertEqual(self.home.getTemperature(), 68)
예제 #21
0
파일: main.py 프로젝트: stormaaja/thermopy
    "{0}.csv".format(datetime.datetime.now().strftime("%Y%m%d%H%M%S"))
BASE_DIR = '/sys/bus/w1/devices/'
DEVICE_FOLDER = glob.glob(BASE_DIR + '28*')[0]
DEVICE_FILE = DEVICE_FOLDER + '/w1_slave'
RELAY_PIN = 17

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

heating_relay = HeatingRelay(RELAY_PIN)


def signal_handler(signal, frame):
    heating_relay.cleanup()
    sys.exit(0)


signal.signal(signal.SIGINT, signal_handler)

thermostat = Thermostat(TempSensorReader(DEVICE_FILE))
thermostat.set_target_temperature(thermostat.read_current_temperature() +
                                  TARGET_TEMPERATURE_CHANGE)

thermo_logger = ThermoLogger()

thermo_logger.set_csv_logger(CSVLogger(LOG_FILENAME))
thermo_logger.set_thermostat(thermostat)
thermo_logger.set_heating_relay(heating_relay)

thermo_logger.run()
예제 #22
0
 def __init__(self, name, addr):
     Thermostat.__init__(self, name, addr, 0x0fff)
예제 #23
0
 def __init__(self, thermostatName, target):
     logger.info("Initializing extender")
     self.sensor = Sensor()
     self.thermostat = Thermostat(thermostatName)
     self.reporter = Reporter()
     self.target = target
예제 #24
0
class Building(ABC):
    """Abstract Class for Building Types"""

    @abstractmethod
    def __init__(self, n_id_, i, amb_t, world_clock_, logger_=None) -> None:
        """Constructor for homes

        :param n_id_: ID of neighborhood containing home
        :type n_id_: int
        :param i: ID of home
        :type i: int
        :param amb_t: Ambient temperature
        :type amb_t: multiprocessing variable
        :param world_clock_: World Clock
        :type world_clock_: multiprocessing variable
        :param logger_: log file to write log messages to
        :type: logger_: log object
        :return: Nothing
        """

        self._length = -1
        self._width = -1
        self._height = -1
        self._num_floors = -1
        self._n_id = n_id_
        self._h_id = i

        self._lower_temp_grad = None
        self._upper_temp_grad = None

        self.outside_temp = amb_t
        self.world_clock = world_clock_
        self.logger = logger_

        self.thermostat = None
        self.walls = None
        self.battery = None
        self.pv = None

        self.devices = dict()
        self.temp_history = list()

        self.sharedInfo = mp.Array('d', range(4))

    @property
    def n_id(self):
        """Get neighborhood ID"""
        return self._n_id

    @n_id.setter
    def n_id(self, value):
        """Set neighborhood ID"""
        self._n_id = value

    @property
    def h_id(self):
        """Get house ID"""
        return self._h_id

    @h_id.setter
    def h_id(self, value):
        """Set house ID"""
        self._h_id = value

    @property
    def length(self):
        """Get house length"""
        return self._length

    @length.setter
    def length(self, value):
        """Set house length"""
        self._length = value

    @property
    def width(self):
        """Get house width"""
        return self._width

    @width.setter
    def width(self, value):
        """Set house width"""
        self._width = value

    @property
    def height(self):
        """Get house height"""
        return self._height

    @height.setter
    def height(self, value):
        """Set house height"""
        self._height = value

    @property
    def num_floors(self):
        """Get number of floors in house"""
        return self._num_floors

    @num_floors.setter
    def num_floors(self, value):
        """Set number of floors in house"""
        self._num_floors = value

    @abstractmethod
    def generate(self, lower_t, upper_t) -> None:
        """Randomly generates home

        :param lower_t: lower temperature gradient (used for determining temperature color of home)
        :type lower_t: int
        :param upper_t: higher temperature gradient (used for determining temperature color of home)
        :type upper_t: int
        :return: Nothing
        """

        # convert sizes to m
        self.length = ft2m(self.length)
        self.width = ft2m(self.width)
        self.height = ft2m(self.height)

        self._lower_temp_grad = lower_t
        self._upper_temp_grad = upper_t

        # select wall material properties
        wall_type = random.randint(1, 3)
        if wall_type == 1:
            self.walls = material.LowEfficiency()
        elif wall_type == 2:
            self.walls = material.MedEfficiency()
        elif wall_type == 3:
            self.walls = material.HighEfficiency()
        else:
            self.walls = material.BrickWall()

        self.sharedInfo[0] = self.outside_temp.value
        self.sharedInfo[1] = 101325  # internal pressure, PA
        self.temp_history.append(self.sharedInfo[0])

        sizes = [self.length, self.width, self.height]
        self.thermostat = Thermostat(sizes, self.sharedInfo, self.world_clock, self.logger)

    @abstractmethod
    def step(self) -> None:
        """Proceeds the house a single step.

        Calculates next temperature and energy consumption of all devices.

        :return: Nothing
        """

        self.battery.charge(self.pv.produce())

        # approach ambient temperature if HVAC is off
        if not self.thermostat.running():
            self.approach_amb()

        else:
            # determine if the HVAC should be turned off
            if self.world_clock.value > self.thermostat.get_end_time():
                self.thermostat.fan_off()
                self.approach_amb()

            else:
                self.thermostat.step(self.thermostat.calc_temp_delta())

                if self.logger is not None:
                    self.logger.debug("\t\tInner Temperature: {:.3f}, end_time: {}".format(self.sharedInfo[0],
                                                                                        self.thermostat.get_end_time()))

        self.consume_energy()
        self.temp_history.append(self.sharedInfo[0])

    def consume_energy(self) -> int:
        """Calculates consumption of all devices and systems within a house

        :return: Energy consumption
        """

        hvac_consumption = 0
        device_consumption = 0

        if self.thermostat.running():
            hvac_consumption = self.thermostat.get_power()

        for key, device in self.devices.items():
            if device.check_run_time(self.world_clock.value) is True:
                device.turn_off(self.world_clock.value)

            device_consumption += device.consumption

        total_consumption = device_consumption + hvac_consumption

        # if the total consumption is greater than the current charge
        # held by the house's battery, then fully discharge the battery and
        # return the amount of energy needed from the grid. Else, return 0
        if total_consumption > self.battery.current_charge():
            energy_needed = total_consumption - self.battery.current_charge()

            self.battery.discharge(total_consumption - energy_needed)
            return energy_needed

        else:
            self.battery.discharge(total_consumption)
            return 0

    # TO-DO: Calculate heat loss through roof conduction
    def approach_amb(self) -> None:
        """Approach the ambient temperature.

        If the HVAC fan is off, approach the ambient world temperature at a rate dependent on the wall materials.

        :return: Nothing
        """

        if self.logger is not None:
            self.logger.debug("\t\tApproaching Ambient Temperature ({:.3f}) (off since {})".format(
                self.outside_temp.value, self.thermostat.get_end_time()))

        air_specific_r = 287.058  # J/(kg * K) based on mean molar mass for dry air (28.96 g/mol)
        air_heat_cap = 0.718  # J/(kg * K) based on c_v value for dry air @ 300 K
        air_density = self.sharedInfo[1] / (air_specific_r * (self.sharedInfo[0] + 273))  # kg/m^3

        w_area = 2 * ((self.length * self.height) + (self.width * self.height))
        r_volume = self.length * self.width * self.height

        # constants
        sun_temp = 5800  # K
        sun_radius = 6.96 * (10 ** 5)  # km
        o = (5.6703 * (10 ** -8))  # W/(m^2 * K^-4)
        distance_sun2earth = 1.496 * (10 ** 8)  # km

        # calculate radiation from sun to outside of wall
        solar_rad = o * (4 * math.pi * sun_radius ** 2) * (sun_temp ** 4)  # W
        solar_i = solar_rad / (4 * math.pi * (distance_sun2earth ** 2))  # W/m^2

        # calculate amount of heat conducted through a single uniform wall (no layers)
        w_conducted_heat = (w_area * (self.outside_temp.value - self.sharedInfo[0])) / self.walls.R

        # calculate amount that internal temperature raises by after adding the
        # heat conducted through the walls into the room
        temp_change = w_conducted_heat / (air_density * r_volume * air_heat_cap)
        self.sharedInfo[0] += temp_change

    def color_gradient(self, step_num=None) -> str:
        """Determine color of house depending on temperature

        :param step_num: Step to go to
        :type step_num: int
        :return: String containing hex color code of the house
        """

        if step_num is not None:
            internal_temp = self.get_int_temp(step_num)
        else:
            internal_temp = self.get_int_temp()

        r = 255
        g = 255
        b = 255

        t_c = int(round((c2f(internal_temp) - self._lower_temp_grad)))
        diff = int(math.ceil((self._upper_temp_grad - self._lower_temp_grad) / 4))

        if t_c >= (diff * 4):
            g = 0
            b = 0

        elif t_c >= (diff * 3):
            g = int(round(g * (1 - ((t_c % diff) * (1 / diff)))))
            b = 0

        elif t_c >= (diff * 2):
            r = int(round(r * ((t_c % diff) * (1 / diff))))
            b = 0

        elif t_c >= diff:
            r = 0
            b = int(round(b * (1 - ((t_c % diff) * (1 / diff)))))

        elif t_c >= 0:
            r = 0
            g = int(g * round((t_c % diff) * (1 / diff), 2))

        else:
            r = 0
            g = 0

        color_code = '%02x%02x%02x' % (r, g, b)
        hex_int = int(color_code, 16)

        if t_c < 0:
            hex_int -= abs(t_c) * 4
        elif t_c > (diff * 4):
            t_c -= (diff * 4)
            hex_int -= t_c * (131072 * 2)

        return str.format('#{:06x}', hex_int)

    def get_int_temp(self, step_num=None) -> float:
        """Returns internal temperature of a house at a specified time

        :param step_num: Step to retrieve temperature from. Default is None, which means the current step
        :type step_num: int
        :return: temperature at step
        """

        if step_num is not None:
            return self.temp_history[step_num]
        else:
            return self.temp_history[self.world_clock.value]

    def get_target_temp(self) -> int:
        """Returns the current target temperature of the house"""

        return self.thermostat.get_target_temp()

    def get_wall_type(self) -> str:
        """Returns the type of the materials making up the walls"""

        return self.walls.type
예제 #25
0
 def setUp(self):
     self.thermostat = Thermostat("Upstairs")
예제 #26
0
#!/usr/bin/python

from threading import Thread
import thermostat
import time
from furnace import Furnace
from thermostat import Thermostat
from temperature_reader import TemperatureReader

print("Starting Runner.py")
f = Furnace()
furnaceThread = Thread(target = f.run, args = ())
furnaceThread.daemon = True
furnaceThread.start()

r = TemperatureReader()
readerThread = Thread(target = r.run, args = ())
readerThread.daemon = True
readerThread.start()

t = Thermostat()
thermostatThread = Thread(target = t.run, args = (f,))
thermostatThread.daemon = True
thermostatThread.start()

while True:
	time.sleep(1)
예제 #27
0
def main(t, g):
    while True:
        griddy_data = g.query()
        current_price = griddy_data["now"]["price_ckwh"]
        price_display = g.format_price(current_price)

        if g.price_is_high(current_price):
            t.set_spike_active(True)
            log.info("Spike active. Current price: {}".format(price_display))
        else:
            t.set_spike_active(False)

        t.run()

        time.sleep(POLL_FREQUENCY)


if __name__ == "__main__":
    log.info("Thermostat monitor started.")

    t = Thermostat(config["thermostat"]["address"])

    g = griddy.Griddy(config["griddy"]["meter_id"],
                      config["griddy"]["member_id"],
                      config["griddy"]["settlement_point"])

    m = Process(target=main, args=(t, g))
    m.start()
    m.join()
예제 #28
0
 def setTemperature(self, newValue):
     self.repository.update(Thermostat("Thermostat", temp=newValue))
     logging.info("Set temperature to \"{0}\"".format(newValue))
예제 #29
0
 def test_get_thermostat(self):
     thermo = Thermostat("Thermostat", temp=68)
     self.home.repository.get = MagicMock(return_value=thermo)
     self.assertEqual(self.home.getThermostat(), thermo)
#!/usr/bin/python

from thermostat import Thermostat

''' 
Start and maintain the
thermostat
'''

# execute #

thermostat = Thermostat()
thermostat.engage_thermostat()
예제 #31
0
 def initBaseComponents(self):
     self.repository.add(Thermostat("Thermostat", temp=68))
     self.repository.add(Light("Living Room Light"))
     logging.info("Initialized 1 thermostat and 1 light in memory")
예제 #32
0
class TestThermostat(TestCase):

    @classmethod
    def setUpClass(cls):
        random.seed(0)

    def setUp(self):
        # create instances
        self.heater = TestHeater()
        self.thermometer = TestThermometer()
        self.clock = TestClock()
        self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)

        # setup testing environment
        # in the beginning, temperature is above threshold, heater is off, both exceptions are on
        self.clock.set_clock(0)
        self.thermometer.temperature = 68
        self.heater._is_turned_on = False
        self.heater.exception_if_turned_on = True
        self.heater.exception_if_turned_off = True

        # start thermostat in target mode with target=68 (thresholds of 67/69)
        self.thermostat.set_target_temperature(68)
        self.thermostat.set_mode('target')


    def test_read_heater_status(self):
        # turn on
        self.heater.exception_if_turned_on = False
        self.heater.set_to_on(True)
        self.assertTrue(self.thermostat.get_heater_is_on())
        # turn off
        self.heater.exception_if_turned_off = False
        self.heater.set_to_on(False)
        self.assertFalse(self.thermostat.get_heater_is_on())

    def test_turn_on_heater_manually(self):
        # turn on
        self.heater.exception_if_turned_on = False
        self.thermostat.set_mode("on")
        self.assertTrue(self.heater.is_on())

    def test_turn_off_heater_manually(self):
        # turn off heater
        self.heater.exception_if_turned_off = False
        self.thermostat.set_mode("off")
        self.assertFalse(self.heater.is_on())

    def test_read_thermometer(self):
        for temp in [0, -5, 98.6]:
            self.thermometer.temperature = temp
            self.assertEquals(self.thermostat.get_room_temperature(), temp)

    def test_set_point(self):
        for temp in [40, 68, 82]:
            self.thermostat.set_target_temperature(temp)
            self.assertEquals(self.thermostat.get_target_temperature(), temp)
            self.assertLess(self.thermostat.threshold_low, temp)
            self.assertGreater(self.thermostat.threshold_high, temp)

    def test_set_point_too_low(self):
        temp = 39  # min allowable is 40
        with self.assertRaises(ThermostatException):
            self.thermostat.set_target_temperature(temp)

    def test_set_point_too_high(self):
        temp = 83  # max allowable is 82
        with self.assertRaises(ThermostatException):
            self.thermostat.set_target_temperature(temp)

    def test_turn_heater_on_when_too_cold(self):
        # after 5 minutes below at or below .threshold_low(), turns on heater
        # advance to some arbitrary time, go below threshold
        self.clock.advance_random()
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # advance less than the required time, heater still off
        self.clock.advance(minutes=4.9)
        self.thermostat.iterate()
        # advance to the required time, heater should kick on
        self.clock.advance(minutes=0.1)
        self.heater.exception_if_turned_on = False
        self.thermostat.iterate()
        self.assertTrue(self.heater.is_on())

    def helper_get_cold_to_trigger_heater(self):
        # possible unintended consequences if not run as first line in test
        # advance to some arbitrary time, it is now too cold
        self.clock.advance_random()
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # stay cold long enough for heater to kick on
        self.clock.advance(minutes=5)
        self.heater.exception_if_turned_on = False
        self.thermostat.iterate()
        self.assertTrue(self.heater.is_on())

    def test_turn_heater_on_when_too_cold_helper(self):
        self.helper_get_cold_to_trigger_heater()

    def test_dont_heat_up_if_not_cold_long_enough(self):
        # threshold duration is 5 minutes. heater should not turn on if cold for 4, warm for 1, cold for 4
        # advance to some arbitrary time, go below threshold
        self.clock.advance_random()
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # advance less than the required time, heater still off
        self.clock.advance(minutes=4)
        self.thermostat.iterate()
        # advance 1 minute, but temperature is above threshold now
        self.clock.advance(minutes=1)
        self.thermometer.temperature = 68
        self.thermostat.iterate()
        # advance 1 minute, temperature back below threshold
        self.clock.advance(minutes=1)
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # advance less than the required time, heater still off
        self.clock.advance(minutes=4)
        self.thermostat.iterate()

    def test_keep_heater_on_until_warm_enough(self):
        self.helper_get_cold_to_trigger_heater()
        # advance arbitrary amount of time, heater is still on
        # this arbitrary time must be less than the maximum-on-duration (20 minutes)
        self.clock.advance(minutes=7.2)
        self.thermostat.iterate()
        # come above threshold, heater will run until above for 5 minutes
        # total arbitrary time must be less than the maximum-on-duration (20 minutes)
        self.clock.advance(minutes=4.8)
        self.thermometer.temperature = 70
        self.thermostat.iterate()
        # advance 5 minutes
        self.clock.advance(minutes=5)
        self.heater.exception_if_turned_off = False
        self.thermostat.iterate()
        self.assertFalse(self.heater.is_on())

    # def test_dont_cycle_off_heater_too_quickly(self):
    #     self.helper_get_cold_to_trigger_heater()
    #     # advance 1 minute, already warm enough, but don't cycle off heater yet
    #     self.clock.advance(minutes=1)
    #     self.thermometer.temperature = 70
    #     self.thermostat.iterate()
    #     # advance to just under cycle minimum time on, heater should still be on
    #     self.clock.advance(minutes=3.9)
    #     self.thermostat.iterate()
    #     # advance beyond cycle minimum time on, heater should turn off
    #     self.clock.advance(minutes=0.1)
    #     self.heater.exception_if_turned_off = False
    #     self.thermostat.iterate()
    #     self.assertFalse(self.heater.is_on())
    #
    # def test_dont_cycle_on_heater_too_quickly(self):
    #     # the beginning of this test needs to trigger the heater and let things warm up
    #     self.helper_get_cold_to_trigger_heater()
    #     # advance and warm up
    #     self.clock.advance(minutes=10)
    #     self.thermometer.temperature = 70
    #     self.heater.exception_if_turned_off = False
    #     self.thermostat.iterate()
    #     self.assertFalse(self.heater.is_on())
    #     # the heater is off now, but throw exception if thermostat tries to turn if off again
    #     self.heater.exception_if_turned_off = True
    #     # now quickly get cold again, but don't turn on heater yet
    #     self.clock.advance(minutes=1)
    #     self.thermometer.temperature = 66
    #     self.thermostat.iterate()
    #     # advance to just inside cycle limit, still not on yet
    #     self.clock.advance(minutes=3.9)
    #     self.thermostat.iterate()
    #     # advance to just outside of cycle limit, heater should kick on
    #     self.clock.advance(minutes=0.1)
    #     self.heater.exception_if_turned_on = False
    #     self.thermostat.iterate()
    #     self.assertTrue(self.heater.is_on())

    def test_dont_keep_heater_on_forever(self):
        # use the real heater controller, not the test heater
        self.heater = HeaterCycleProtection(self.clock)
        self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)
        self.thermostat.set_mode('on')
        # advance to just before time limit
        self.clock.advance(minutes=59)
        self.thermostat.iterate()
        self.assertTrue(self.heater.is_on())
        # advance past limit, heater should go off
        self.clock.advance(minutes=1)
        self.thermostat.iterate()
        self.assertFalse(self.heater.is_on())
예제 #33
0
class TestThermostat(TestCase):
    @classmethod
    def setUpClass(cls):
        random.seed(0)

    def setUp(self):
        # create instances
        self.heater = TestHeater()
        self.thermometer = TestThermometer()
        self.clock = TestClock()
        self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)

        # setup testing environment
        # in the beginning, temperature is above threshold, heater is off, both exceptions are on
        self.clock.set_clock(0)
        self.thermometer.temperature = 68
        self.heater._is_turned_on = False
        self.heater.exception_if_turned_on = True
        self.heater.exception_if_turned_off = True

        # start thermostat in target mode with target=68 (thresholds of 67/69)
        self.thermostat.set_target_temperature(68)
        self.thermostat.set_mode('target')

    def test_read_heater_status(self):
        # turn on
        self.heater.exception_if_turned_on = False
        self.heater.set_to_on(True)
        self.assertTrue(self.thermostat.get_heater_is_on())
        # turn off
        self.heater.exception_if_turned_off = False
        self.heater.set_to_on(False)
        self.assertFalse(self.thermostat.get_heater_is_on())

    def test_turn_on_heater_manually(self):
        # turn on
        self.heater.exception_if_turned_on = False
        self.thermostat.set_mode("on")
        self.assertTrue(self.heater.is_on())

    def test_turn_off_heater_manually(self):
        # turn off heater
        self.heater.exception_if_turned_off = False
        self.thermostat.set_mode("off")
        self.assertFalse(self.heater.is_on())

    def test_read_thermometer(self):
        for temp in [0, -5, 98.6]:
            self.thermometer.temperature = temp
            self.assertEquals(self.thermostat.get_room_temperature(), temp)

    def test_set_point(self):
        for temp in [40, 68, 82]:
            self.thermostat.set_target_temperature(temp)
            self.assertEquals(self.thermostat.get_target_temperature(), temp)
            self.assertLess(self.thermostat.threshold_low, temp)
            self.assertGreater(self.thermostat.threshold_high, temp)

    def test_set_point_too_low(self):
        temp = 39  # min allowable is 40
        with self.assertRaises(ThermostatException):
            self.thermostat.set_target_temperature(temp)

    def test_set_point_too_high(self):
        temp = 83  # max allowable is 82
        with self.assertRaises(ThermostatException):
            self.thermostat.set_target_temperature(temp)

    def test_turn_heater_on_when_too_cold(self):
        # after 5 minutes below at or below .threshold_low(), turns on heater
        # advance to some arbitrary time, go below threshold
        self.clock.advance_random()
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # advance less than the required time, heater still off
        self.clock.advance(minutes=4.9)
        self.thermostat.iterate()
        # advance to the required time, heater should kick on
        self.clock.advance(minutes=0.1)
        self.heater.exception_if_turned_on = False
        self.thermostat.iterate()
        self.assertTrue(self.heater.is_on())

    def helper_get_cold_to_trigger_heater(self):
        # possible unintended consequences if not run as first line in test
        # advance to some arbitrary time, it is now too cold
        self.clock.advance_random()
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # stay cold long enough for heater to kick on
        self.clock.advance(minutes=5)
        self.heater.exception_if_turned_on = False
        self.thermostat.iterate()
        self.assertTrue(self.heater.is_on())

    def test_turn_heater_on_when_too_cold_helper(self):
        self.helper_get_cold_to_trigger_heater()

    def test_dont_heat_up_if_not_cold_long_enough(self):
        # threshold duration is 5 minutes. heater should not turn on if cold for 4, warm for 1, cold for 4
        # advance to some arbitrary time, go below threshold
        self.clock.advance_random()
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # advance less than the required time, heater still off
        self.clock.advance(minutes=4)
        self.thermostat.iterate()
        # advance 1 minute, but temperature is above threshold now
        self.clock.advance(minutes=1)
        self.thermometer.temperature = 68
        self.thermostat.iterate()
        # advance 1 minute, temperature back below threshold
        self.clock.advance(minutes=1)
        self.thermometer.temperature = 66
        self.thermostat.iterate()
        # advance less than the required time, heater still off
        self.clock.advance(minutes=4)
        self.thermostat.iterate()

    def test_keep_heater_on_until_warm_enough(self):
        self.helper_get_cold_to_trigger_heater()
        # advance arbitrary amount of time, heater is still on
        # this arbitrary time must be less than the maximum-on-duration (20 minutes)
        self.clock.advance(minutes=7.2)
        self.thermostat.iterate()
        # come above threshold, heater will run until above for 5 minutes
        # total arbitrary time must be less than the maximum-on-duration (20 minutes)
        self.clock.advance(minutes=4.8)
        self.thermometer.temperature = 70
        self.thermostat.iterate()
        # advance 5 minutes
        self.clock.advance(minutes=5)
        self.heater.exception_if_turned_off = False
        self.thermostat.iterate()
        self.assertFalse(self.heater.is_on())

    # def test_dont_cycle_off_heater_too_quickly(self):
    #     self.helper_get_cold_to_trigger_heater()
    #     # advance 1 minute, already warm enough, but don't cycle off heater yet
    #     self.clock.advance(minutes=1)
    #     self.thermometer.temperature = 70
    #     self.thermostat.iterate()
    #     # advance to just under cycle minimum time on, heater should still be on
    #     self.clock.advance(minutes=3.9)
    #     self.thermostat.iterate()
    #     # advance beyond cycle minimum time on, heater should turn off
    #     self.clock.advance(minutes=0.1)
    #     self.heater.exception_if_turned_off = False
    #     self.thermostat.iterate()
    #     self.assertFalse(self.heater.is_on())
    #
    # def test_dont_cycle_on_heater_too_quickly(self):
    #     # the beginning of this test needs to trigger the heater and let things warm up
    #     self.helper_get_cold_to_trigger_heater()
    #     # advance and warm up
    #     self.clock.advance(minutes=10)
    #     self.thermometer.temperature = 70
    #     self.heater.exception_if_turned_off = False
    #     self.thermostat.iterate()
    #     self.assertFalse(self.heater.is_on())
    #     # the heater is off now, but throw exception if thermostat tries to turn if off again
    #     self.heater.exception_if_turned_off = True
    #     # now quickly get cold again, but don't turn on heater yet
    #     self.clock.advance(minutes=1)
    #     self.thermometer.temperature = 66
    #     self.thermostat.iterate()
    #     # advance to just inside cycle limit, still not on yet
    #     self.clock.advance(minutes=3.9)
    #     self.thermostat.iterate()
    #     # advance to just outside of cycle limit, heater should kick on
    #     self.clock.advance(minutes=0.1)
    #     self.heater.exception_if_turned_on = False
    #     self.thermostat.iterate()
    #     self.assertTrue(self.heater.is_on())

    def test_dont_keep_heater_on_forever(self):
        # use the real heater controller, not the test heater
        self.heater = HeaterCycleProtection(self.clock)
        self.thermostat = Thermostat(self.heater, self.thermometer, self.clock)
        self.thermostat.set_mode('on')
        # advance to just before time limit
        self.clock.advance(minutes=59)
        self.thermostat.iterate()
        self.assertTrue(self.heater.is_on())
        # advance past limit, heater should go off
        self.clock.advance(minutes=1)
        self.thermostat.iterate()
        self.assertFalse(self.heater.is_on())
예제 #34
0
    ip = None
    thermostat = None

    if config and config.get('secret', None) is not None:
        if config.get('secret').get('ip_zibase', None) is not None:
            ip = config.get('secret').get('ip_zibase')
            if ip == "":
                ip = None

        print("Address ip zibase:{}").format(ip)
        for x, y in config.items():
            print(x, y)

    if ip is not None:
        try:
            thermostat = Thermostat(ip)
            thermostat.setSetpointDay(207)
            thermostat.setSetpointNight(195)
            thermostat.addSetpointDay(1)
            thermostat.addSetpointNight(5)
            thermostat.setMode(0)
            thermostat.update()

            thermostat.read()

        except Exception as e:
            zibase = None
            print('Error Thermostat {}'.format(e))

    h.subscribe_intents(intent_received).start()
예제 #35
0
	def __init__(self, name, addr):
		Thermostat.__init__(self, name, addr, 0x0fff)
예제 #36
0
iconDay = Icon(path, '/icons/sun-2-32')
iconNight = Icon(path, '/icons/moon-2-32')
iconOff = Icon(path, '/icons/off')
iconFlame = Icon(path, '/icons/flame32')

zibaseId = None
tokenId = None
try:
    config = SnipsConfigParser.read_configuration_file(configPath)
    #print configPath, config
    zibaseId = config.get('secret').get('zibaseid')
    tokenId = config.get('secret').get('tokenid')
except:
    config = None

thermostat = Thermostat(config)

display = 3  # Set the Default display here

# update interval in seconds
if display == 2 or display == 3:
    updateRate = 60
else:
    updateRate = 60 * 5

lastupdate = 0

# define a variable to control the main loop
running = True
try: