예제 #1
0
class TestListQuery(unittest.TestCase):
    def setUp(self):
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)

    def tearDown(self):
        self.bw_client.close()

    def testListQuery(self):
        for planet, probe in PERSISTED_DATA.items():
            po = PayloadObject((64, 0, 0, 0), None, probe)
            uri = BASE_URI + "/persisted/" + planet
            self.bw_client.publish(uri, payload_objects=(po, ), persist=True)

        results = self.bw_client.query(BASE_URI + "/persisted/+")
        self.assertEquals(len(results), len(PERSISTED_DATA))
        probes = [result.payload_objects[0].content for result in results]
        self.assertTrue(
            all([probe in PERSISTED_DATA.values() for probe in probes]))

        children = self.bw_client.list(BASE_URI + "/persisted")
        self.assertEquals(len(children), len(PERSISTED_DATA))
        planets = [child[child.rfind("/") + 1:] for child in children]
        self.assertTrue(
            all([planet in PERSISTED_DATA.keys() for planet in planets]))
예제 #2
0
class TestPubSubscribe(unittest.TestCase):
    def onMessage(self, message):
        self.assertTrue(len(message.payload_objects) > 0)
        msg_body = message.payload_objects[0].content
        self.assertIn(msg_body, MESSAGES)
        self.counter += 1
        if self.counter == len(MESSAGES):
            self.semaphore.release()

    def setUp(self):
        self.counter = 0
        self.semaphore = Semaphore(0)
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)
        self.bw_client.subscribe(URI, self.onMessage)

    def tearDown(self):
        self.bw_client.close()

    def testPublishSubscribe(self):
        for msg in MESSAGES:
            po = PayloadObject((64, 0, 0, 0), None, msg)
            self.bw_client.publish(URI, payload_objects=(po, ))
        self.semaphore.acquire()
class TestPubSubscribe(unittest.TestCase):
    def onMessage(self, message):
        self.assertTrue(len(message.payload_objects) > 0)
        msg_body = message.payload_objects[0].content
        self.assertIn(msg_body, MESSAGES)
        self.counter += 1
        if self.counter == len(MESSAGES):
            self.semaphore.release()

    def setUp(self):
        self.counter = 0
        self.semaphore = Semaphore(0)
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)
        self.bw_client.subscribe(URI, self.onMessage)

    def tearDown(self):
        self.bw_client.close()

    def testPublishSubscribe(self):
        for msg in MESSAGES:
            po = PayloadObject((64, 0, 0, 0), None, msg)
            self.bw_client.publish(URI, payload_objects=(po,))
        self.semaphore.acquire()
예제 #4
0
파일: hod.py 프로젝트: thomson-greg/XBOS
    def __init__(self, url, client=None, timeout=20):
        if client is None:
            client = Client()
            client.vk = client.setEntityFromEnviron()
            client.overrideAutoChainTo(True)
        if not isinstance(client, Client):
            raise TypeError(
                "first argument must be bw2python.client.Client or None")
        self.c = client
        self.vk = client.vk
        self.url = url

        responses = self.c.query("{0}/*/s.hod/!meta/lastalive".format(url))
        for resp in responses:
            # get the metadata records from the response
            md_records = filter(
                lambda po: po.type_dotted == ponames.PODFSMetadata,
                resp.payload_objects)
            # get timestamp field from the first metadata record
            last_seen_timestamp = msgpack.unpackb(
                md_records[0].content).get('ts')
            # get how long ago that was
            now = time.time() * 1e9  # nanoseconds
            # convert to microseconds and get the timedelta
            diff = timedelta(microseconds=(now - last_seen_timestamp) / 1e3)
            print "Saw [{0}] HodDB {1}".format(self.url,
                                               pretty_print_timedelta(diff))
            if diff.total_seconds() > timeout:
                raise TimeoutException("HodDB at {0} is too old".format(
                    self.url))
예제 #5
0
class TestListQuery(unittest.TestCase):
    def onSetEntityResponse(self, response):
        self.assertEqual("okay", response.status)
        self.semaphore.release()

    def assertOkay(self, response):
        self.assertEqual("okay", response.status)

    def onMessage(self, message):
        if message.getFirstValue("finished") != "true":
            self.assertTrue(len(message.payload_objects) > 0)
            msg_body = message.payload_objects[0].content
            self.assertIn(msg_body, PERSISTED_DATA.values())
            self.counter += 1
        else:
            self.assertEqual(self.counter, len(PERSISTED_DATA))
            self.semaphore.release()

    def onListResult(self, child):
        if child is not None:
            planet = child[child.rfind("/") + 1:]
            self.assertIn(planet, PERSISTED_DATA.keys())
            self.counter += 1
        else:
            self.assertEqual(self.counter, len(PERSISTED_DATA))
            self.semaphore.release()

    def setUp(self):
        self.counter = 0
        self.semaphore = Semaphore(0)
        self.bw_client = Client()
        self.bw_client.asyncSetEntityFromFile(KEY_FILE,
                                              self.onSetEntityResponse)
        self.bw_client.overrideAutoChainTo(True)
        self.semaphore.acquire()

    def tearDown(self):
        self.bw_client.close()

    def testListQuery(self):
        for planet, probe in PERSISTED_DATA.items():
            po = PayloadObject((64, 0, 0, 0), None, probe)
            uri = BASE_URI + "/persisted/" + planet
            self.bw_client.asyncPublish(uri,
                                        self.assertOkay,
                                        payload_objects=(po, ),
                                        persist=True)
        self.bw_client.asyncQuery(BASE_URI + "/persisted/+", self.assertOkay,
                                  self.onMessage)
        self.semaphore.acquire()

        self.counter = 0
        self.bw_client.asyncList(BASE_URI + "/persisted", self.assertOkay,
                                 self.onListResult)
        self.semaphore.acquire()
class TestListQuery(unittest.TestCase):
    def onSetEntityResponse(self, response):
        self.assertEqual("okay", response.status)
        self.semaphore.release()

    def assertOkay(self, response):
        self.assertEqual("okay", response.status)

    def onMessage(self, message):
        if message.getFirstValue("finished") != "true":
            self.assertTrue(len(message.payload_objects) > 0)
            msg_body = message.payload_objects[0].content
            self.assertIn(msg_body, PERSISTED_DATA.values())
            self.counter += 1
        else:
            self.assertEqual(self.counter, len(PERSISTED_DATA))
            self.semaphore.release()

    def onListResult(self, child):
        if child is not None:
            planet = child[child.rfind("/")+1:]
            self.assertIn(planet, PERSISTED_DATA.keys())
            self.counter += 1
        else:
            self.assertEqual(self.counter, len(PERSISTED_DATA))
            self.semaphore.release()

    def setUp(self):
        self.counter = 0
        self.semaphore = Semaphore(0)
        self.bw_client = Client()
        self.bw_client.asyncSetEntityFromFile(KEY_FILE, self.onSetEntityResponse)
        self.bw_client.overrideAutoChainTo(True)
        self.semaphore.acquire()

    def tearDown(self):
        self.bw_client.close()

    def testListQuery(self):
        for planet, probe in PERSISTED_DATA.items():
            po = PayloadObject((64, 0, 0, 0), None, probe)
            uri = BASE_URI + "/persisted/" + planet
            self.bw_client.asyncPublish(uri, self.assertOkay, payload_objects=(po,), persist=True)
        self.bw_client.asyncQuery(BASE_URI + "/persisted/+", self.assertOkay, self.onMessage)
        self.semaphore.acquire()

        self.counter = 0
        self.bw_client.asyncList(BASE_URI + "/persisted", self.assertOkay, self.onListResult)
        self.semaphore.acquire()
예제 #7
0
파일: pundat.py 프로젝트: thomson-greg/XBOS
    def __init__(self, client=None, archivers=None):
        """
        Creates a BW2 Data client

        Arguments:
        [client]: if this is None, we use environment vars to configure a client
                  automatically; else, we use the client provided
        [archivers]: this is a list of base archiver URIs. These can be found by
                  running "pundat scan <namespace>"
        """
        # bw2 client
        if client is None:
            client = Client()
            client.vk = client.setEntityFromEnviron()
            client.overrideAutoChainTo(True)
        if not isinstance(client, Client):
            raise TypeError(
                "first argument must be bw2python.client.Client or None")
        self.c = client
        self.vk = client.vk

        if archivers is None:
            archivers = ["ucberkeley"]  # default archiver
        self.archivers = []
        # scan for archiver liveness
        for archiver in archivers:
            responses = self.c.query(
                "{0}/*/s.giles/!meta/lastalive".format(archiver))
            for resp in responses:
                # get the metadata records from the response
                md_records = filter(
                    lambda po: po.type_dotted == ponames.PODFSMetadata,
                    resp.payload_objects)
                # get timestamp field from the first metadata record
                last_seen_timestamp = msgpack.unpackb(
                    md_records[0].content).get('ts')
                # get how long ago that was
                now = time.time() * 1e9  # nanoseconds
                # convert to microseconds and get the timedelta
                diff = timedelta(microseconds=(now - last_seen_timestamp) /
                                 1e3)
                print "Saw [{0}] archiver {1}".format(
                    archiver, pretty_print_timedelta(diff))
                if diff.total_seconds() < 20:
                    self.archivers.append(archiver)
        if len(self.archivers) == 0:
            self.archivers = archivers
예제 #8
0
class TestPubSubFailure(unittest.TestCase):
    def setUp(self):
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)

    def tearDown(self):
        self.bw_client.close()

    def testQueryFailure(self):
        with self.assertRaises(RuntimeError):
            # Unit test key should not have permissions on this URI
            self.bw_client.query("jkolb/test")

    def testListFailure(self):
        with self.assertRaises(RuntimeError):
            # Unit test key should not have permissions on this URI
            self.bw_client.list("jkolb/test")
예제 #9
0
class TestPubSubFailure(unittest.TestCase):
    def onMessage(self, message):
        pass

    def setUp(self):
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)

    def tearDown(self):
        self.bw_client.close()

    def testSubscribeFailure(self):
        with self.assertRaises(RuntimeError):
            # Unit test key should not have permissions on this URI
            self.bw_client.subscribe("jkolb/test", self.onMessage)

    def testPublishFailure(self):
        with self.assertRaises(RuntimeError):
            # Unit test key should not have permissions on this URI
            po = PayloadObject(ponames.PODFText, None, "Hello, World!")
            self.bw_client.publish("jkolb/test", payload_objects=(po, ))
class TestPubSubFailure(unittest.TestCase):
    def onMessage(self, message):
        pass

    def setUp(self):
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)

    def tearDown(self):
        self.bw_client.close()

    def testSubscribeFailure(self):
        with self.assertRaises(RuntimeError):
            # Unit test key should not have permissions on this URI
            self.bw_client.subscribe("jkolb/test", self.onMessage)

    def testPublishFailure(self):
        with self.assertRaises(RuntimeError):
            # Unit test key should not have permissions on this URI
            po = PayloadObject(ponames.PODFText, None, "Hello, World!")
            self.bw_client.publish("jkolb/test", payload_objects=(po,))
예제 #11
0
    def __init__(self, url, client=None, timeout=30):
        """
        Creates an MDAL client.

        Arguments:
        [url]: the BOSSWAVE uri where mdal is hosted
        [client]: if this is None, we use environment vars to configure a client
                  automatically; else, we use the client provided from bw2python
        """
        if client is None:
            client = Client()
            client.vk = client.setEntityFromEnviron()
            client.overrideAutoChainTo(True)
        if not isinstance(client, Client):
            raise TypeError(
                "first argument must be bw2python.client.Client or None")
        self.c = client
        self.vk = client.vk
        self.url = url

        # check liveness
        responses = self.c.query("{0}/*/s.mdal/!meta/lastalive".format(url))
        for resp in responses:
            # get the metadata records from the response
            md_records = filter(
                lambda po: po.type_dotted == ponames.PODFSMetadata,
                resp.payload_objects)
            # get timestamp field from the first metadata record
            last_seen_timestamp = msgpack.unpackb(
                md_records[0].content).get('ts')
            # get how long ago that was
            now = time.time() * 1e9  # nanoseconds
            # convert to microseconds and get the timedelta
            diff = timedelta(microseconds=(now - last_seen_timestamp) / 1e3)
            print "Saw [{0}] MDAL {1}".format(self.url,
                                              pretty_print_timedelta(diff))
            if diff.total_seconds() > timeout:
                raise TimeoutException("MDAL at {0} is too old".format(
                    self.url))
class TestListQuery(unittest.TestCase):
    def setUp(self):
        self.bw_client = Client()
        self.bw_client.setEntityFromFile(KEY_FILE)
        self.bw_client.overrideAutoChainTo(True)

    def tearDown(self):
        self.bw_client.close()

    def testListQuery(self):
        for planet, probe in PERSISTED_DATA.items():
            po = PayloadObject((64, 0, 0, 0), None, probe)
            uri = BASE_URI + "/persisted/" + planet
            self.bw_client.publish(uri, payload_objects=(po,), persist=True)

        results = self.bw_client.query(BASE_URI + "/persisted/+")
        self.assertEquals(len(results), len(PERSISTED_DATA))
        probes = [result.payload_objects[0].content for result in results]
        self.assertTrue(all([probe in PERSISTED_DATA.values() for probe in probes]))

        children = self.bw_client.list(BASE_URI + "/persisted")
        self.assertEquals(len(children), len(PERSISTED_DATA))
        planets = [child[child.rfind("/")+1:] for child in children]
        self.assertTrue(all([planet in PERSISTED_DATA.keys() for planet in planets]))
예제 #13
0
import cv2
import requests
import time
import random
import string
from PIL import Image, ExifTags
from bw2python import ponames
from bw2python.bwtypes import PayloadObject
from bw2python.client import Client


#uuid

bw_client = Client()
bw_client.setEntityFromEnviron()
bw_client.overrideAutoChainTo(True)
SERVER_ADDR = "http://localhost:8080"

RESULT_PASS = 0
RESULT_BAD_FORMAT = 1
RESULT_FAIL = 2
DEFAULT_CHANNEL = "scratch.ns/cellmate"
IDENTITY_LENGTH = 10

def test_file(filename):
    obj_name = os.path.basename(filename).split(".")[0]
    img = Image.open(filename)
    width, height = img.size
    if height/width == 480/640:
        width, height = 640, 480
    elif width/height == 480/640:
예제 #14
0
class Scheduler(object):
    def __init__(self, signal, slot, ssus):
        self.signal = signal
        self.slot = slot
        self.ssu_list = SSU_Link.create_ssu_list(ssus)

        self.bw_client = Client()
        self.bw_client.setEntityFromEnviron()
        self.bw_client.overrideAutoChainTo(True)

        self.last_received_schedule = {
            'kwargs': {
                'temperature': None,
                'relative_humidity': None,
                'heating_setpoint': None,
                'cooling_setpoint': None,
                'override': None,
                'fan': None,
                'mode': None,
                'state': None,
                'time': time.time() * 1e9
            }
        }

    def run(self):
        print "scheduler running"
        self.bw_client.subscribe(self.slot, self.on_message)
        while True:
            #For time-based SSUs. Sends a signal every hour. Publishing will fail if initial SSU is not strictly time-based.
            msg = copy.deepcopy(self.last_received_schedule)
            msg['kwargs']['time'] = time.time() * 1e9
            thread.start_new_thread(self.publish, (), msg)
            time.sleep(3600)
            print "sleeping"

    def publish(self, **kwargs):
        try:
            kwargs = kwargs.get('kwargs')
            sched = self.generate_schedule(kwargs.get('temperature'),
                                           kwargs.get('relative_humidity'),
                                           kwargs.get('heating_setpoint'),
                                           kwargs.get('cooling_setpoint'),
                                           kwargs.get('override'),
                                           kwargs.get('fan'),
                                           kwargs.get('mode'),
                                           kwargs.get('state'),
                                           kwargs.get('time'))
            self.publish_schedule(*sched)
        except Exception as e:
            print "Failed to publish message", e

    def generate_schedule(self, temp, rel_humidity, heating_setpt,
                          cooling_setpt, override, fan, mode, state, time):
        data = (temp, rel_humidity, heating_setpt, cooling_setpt, override,
                fan, mode, state, time)
        curr = self.ssu_list
        while curr is not None:
            data = curr.ssu.generate_schedule(*data)
            curr = curr.rest

        heating_setpt, cooling_setpt = data[2], data[3]

        if temp <= heating_setpt:
            mode = 1
        elif temp >= cooling_setpt:
            mode = 2

        return float(heating_setpt), float(cooling_setpt), override, mode, fan

    def publish_schedule(self, heating_setpt, cooling_setpt, override, mode,
                         fan):
        assert isinstance(heating_setpt, float)
        assert isinstance(cooling_setpt, float)
        assert isinstance(override, bool)
        assert isinstance(mode, int)
        assert isinstance(fan, bool)

        t = {
            'heating_setpoint': heating_setpt,
            'cooling_setpoint': cooling_setpt,
            'override': override,
            'mode': mode,
            'fan': fan
        }
        po = PayloadObject((2, 1, 1, 0), None, msgpack.packb(t))
        print t
        self.bw_client.publish(self.signal, payload_objects=(po, ))

    def on_message(self, bw_message):
        print "msg received"
        try:
            for po in bw_message.payload_objects:
                if po.type_dotted == (2, 1, 1, 0):
                    tstat_data = msgpack.unpackb(po.content)
                    self.last_received_schedule = {'kwargs': tstat_data}
                    thread.start_new_thread(self.publish, (),
                                            self.last_received_schedule)
        except Exception as e:
            print e
예제 #15
0
import cv2
import requests
import time
import random
import string
from PIL import Image, ExifTags
from bw2python import ponames
from bw2python.bwtypes import PayloadObject
from bw2python.client import Client




bw_client = Client()
bw_client.setEntityFromEnviron()
bw_client.overrideAutoChainTo(True)
SERVER_ADDR = "http://localhost:8080"

RESULT_PASS = 0
RESULT_BAD_FORMAT = 1
RESULT_FAIL = 2
DEFAULT_CHANNEL = "scratch.ns/cellmate"
IDENTITY_LENGTH = 10

def test_file(filename):
    obj_name = os.path.basename(filename).split(".")[0]

    img = Image.open(filename)
    width, height = img.size
    if height/width == 480/640:
        width, height = 640, 480
예제 #16
0
class Controller:
    def __init__(self):
        self.bw_client = Client()
        self.bw_client.setEntityFromEnviron()
        self.bw_client.overrideAutoChainTo(True)
        self.hod_client = HodClient("xbos/hod", self.bw_client)
        self.priority = {
            "fan": 1,
            "kettle": 2,
            "student_office_tstat": 3,
            "microwave": 4,
            "sra_office_tstat": 5,
            "space_heater": 5,
            "fridge": 6,
            "evse": 7,
            "michaels_office_tstat": 8
        }

        meter_q = """
            SELECT ?uri FROM rfs WHERE {
            ?m rdf:type brick:Building_Electric_Meter .
  	         ?m bf:uri ?uri .
             };
        """
        self.building_meter = Meter(
            self.bw_client,
            self.hod_client.do_query(meter_q)['Rows'][0]['?uri'])
        self.tstats = {
            "student_office_tstat":
            Thermostat(
                self.bw_client,
                "rfs/devices/s.pelican/Student_Office/i.xbos.thermostat"),
            "sra_office_tstat":
            Thermostat(self.bw_client,
                       "rfs/devices/s.pelican/SRA_Office/i.xbos.thermostat"),
            "michaels_office_tstat":
            Thermostat(
                self.bw_client,
                "rfs/devices/s.pelican/Michaels_Office/i.xbos.thermostat")
        }

        self.plugloads = {
            "fan":
            Plug(self.bw_client, "rfs/devices/fan/s.tplink.v0/0/i.xbos.plug"),
            "fridge":
            Plug(self.bw_client,
                 "rfs/devices/refrigerator/s.tplink.v0/0/i.xbos.plug"),
            "space_heater":
            Plug(self.bw_client,
                 "rfs/devices/heater/s.tplink.v0/0/i.xbos.plug"),
            "kettle":
            Plug(self.bw_client,
                 "rfs/devices/boiler/s.tplink.v0/0/i.xbos.plug"),
            "microwave":
            Plug(self.bw_client,
                 "rfs/devices/microwave/s.tplink.v0/0/i.xbos.plug")
        }
        self.evse = EVSE(self.bw_client,
                         "rfs/devices/s.aerovironment/ParkingLot/i.xbos.evse")
        self.evse.set_current_limit(_MAX_EVSE_CURRENT)

    def control(self, threshold):
        if self.evse.state:
            car_demand = self.evse.current * self.evse.voltage
            allowed_car_threshold = threshold - self.building_meter.power * 1000
            if car_demand < allowed_car_threshold:
                if self.evse.current_limit < _MAX_EVSE_CURRENT:
                    print(
                        "current total consumption is less than threshold, increasing car charging limit"
                    )
                    if allowed_car_threshold < _MAX_EVSE_CONSUMPTION:
                        print("setting limit to:",
                              (allowed_car_threshold) // _MAX_EVSE_VOLTAGE)
                        self.evse.set_current_limit(
                            (allowed_car_threshold) // _MAX_EVSE_VOLTAGE)
                    else:
                        print("setting limit to:", _MAX_EVSE_CURRENT)
                        self.evse.set_current_limit(_MAX_EVSE_CURRENT)
                else:
                    print(
                        "current total consumption is less than threshold, evse limit is already at max nothing to do"
                    )
                return
        else:
            if self.building_meter.power <= threshold:
                print(
                    "current building consumption is less than threshold and evse is off, nothing to do"
                )
                return

        # current consumption is higher than threshold

        # get total power consumption of controllable loads without evse (plugloads and baseboard heaters)
        controllable_loads = 0

        for _, tstat in self.tstats.iteritems():
            controllable_loads += (tstat.state * _BASEBOARD_HEATER_CONSUMPTION)

        for _, plug in self.plugloads.iteritems():
            controllable_loads += plug.power

        print("Building electric meter:", self.building_meter.power * 1000)
        print("Total controllable_loads power:", controllable_loads)
        process_load = self.building_meter.power * 1000 - controllable_loads
        print("Total process (uncontrollable) loads power:", process_load)

        # if process_load is greater than threshold
        if process_load >= threshold:
            if controllable_loads == 0:
                print(
                    "current consumption is greater than threshold, but all controllable_loads are off, nothing to do"
                )
                return
            else:
                print(
                    "current consumption is greater than threshold, turning off all controllable loads. nothing else to do"
                )
                for _, tstat in self.tstats.iteritems():
                    tstat.set_mode(0)

                for _, plug in self.plugloads.iteritems():
                    plug.set_state(0.0)

                self.evse.set_state(False)
                return

        # subtract uncontrollable loads from threshold
        ctrl_threshold = threshold - process_load
        print("Controllable threshold:", ctrl_threshold)

        # get and sort controllable_loads
        controllable_loads = [{
            'name': 'fan',
            'priority': self.priority.get('fan'),
            'capacity': self.plugloads.get('fan').power,
            'state': int(self.plugloads.get('fan').state)
        }, {
            'name': 'kettle',
            'priority': self.priority.get('kettle'),
            'capacity': self.plugloads.get('kettle').power,
            'state': int(self.plugloads.get('kettle').state)
        }, {
            'name':
            'student_office_tstat',
            'priority':
            self.priority.get('student_office_tstat'),
            'capacity':
            _BASEBOARD_HEATER_CONSUMPTION,
            'state':
            self.tstats.get('student_office_tstat').state
        }, {
            'name':
            'microwave',
            'priority':
            self.priority.get('microwave'),
            'capacity':
            self.plugloads.get('microwave').power,
            'state':
            int(self.plugloads.get('microwave').state)
        }, {
            'name':
            'sra_office_tstat',
            'priority':
            self.priority.get('sra_office_tstat'),
            'capacity':
            _BASEBOARD_HEATER_CONSUMPTION,
            'state':
            self.tstats.get('sra_office_tstat').state
        }, {
            'name':
            'space_heater',
            'priority':
            self.priority.get('space_heater'),
            'capacity':
            self.plugloads.get('space_heater').power,
            'state':
            int(self.plugloads.get('space_heater').state)
        }, {
            'name':
            'michaels_office_tstat',
            'priority':
            self.priority.get('michaels_office_tstat'),
            'capacity':
            _BASEBOARD_HEATER_CONSUMPTION,
            'state':
            self.tstats.get('michaels_office_tstat').state
        }, {
            'name': 'fridge',
            'priority': self.priority.get('fridge'),
            'capacity': self.plugloads.get('fridge').power,
            'state': int(self.plugloads.get('fridge').state)
        }, {
            'name': 'evse',
            'priority': self.priority.get('evse'),
            'capacity': _MIN_EVSE_CONSUMPTION,
            'state': int(self.evse.state)
        }]
        controllable_loads = sorted(controllable_loads,
                                    key=operator.itemgetter(
                                        'priority', 'capacity'),
                                    reverse=True)
        loads_to_keep = []
        # get loads to keep on
        for load in controllable_loads:
            if load['state'] == 1 and load['capacity'] <= ctrl_threshold:
                print load
                loads_to_keep.append(load['name'])
                ctrl_threshold -= load['capacity']
                print("Updated controllable threshold:", ctrl_threshold)
        # turn off other loads
        for load in controllable_loads:
            if load['state'] == 1 and load['name'] not in loads_to_keep:
                if load['name'] == 'evse':
                    print "turning off evse"
                    self.evse.set_state(False)
                elif load['name'].endswith('_tstat'):
                    print "turning off tstat: " + load['name']
                    self.tstats.get(load['name']).set_mode(0)
                else:
                    print "turning off plug: " + load['name']
                    self.plugloads.get(load['name']).set_state(0.0)
        # set current_limit for evse to match threshold
        if ctrl_threshold > 0 and 'evse' in loads_to_keep:
            if _MIN_EVSE_CONSUMPTION + ctrl_threshold < _MAX_EVSE_CONSUMPTION:
                print("setting limit to:",
                      (_MIN_EVSE_CONSUMPTION + ctrl_threshold) //
                      _MAX_EVSE_VOLTAGE)
                self.evse.set_current_limit(
                    (_MIN_EVSE_CONSUMPTION + ctrl_threshold) //
                    _MAX_EVSE_VOLTAGE)
            else:
                print("setting limit to:", _MAX_EVSE_CURRENT)
                self.evse.set_current_limit(_MAX_EVSE_CURRENT)

    def report_state(self):
        print("EVSE state: ", self.evse.state)
        print("EVSE current: ", self.evse.current)
        print("EVSE voltage: ", self.evse.voltage)
        print("Building_Electric_Meter: ", self.building_meter.power * 1000)
        for _, tstat in self.tstats.iteritems():
            print("Tstat ", tstat._uri, " State: ", tstat.state)
            print("Tstat ", tstat._uri, " Power: ",
                  tstat.state * _BASEBOARD_HEATER_CONSUMPTION)
        for _, plug in self.plugloads.iteritems():
            print("Plugload ", plug._uri, " State: ", plug.state)
            print("Plugload ", plug._uri, " Power: ", plug.power)