Exemple #1
0
class Logger:
    def __init__(self, address, port):

        # connect to the cube
        self.cube = MaxCube(MaxCubeConnection(address, port))

    def log(self, today):
        self.cube.update()

        now = time.strftime("%Y-%m-%d %H:%M")
        apartments = {}

        print(len(self.cube.devices), "devices found")
        for device in self.cube.devices:
            id = device.name.split("_")[0]
            if id not in apartments:
                apartments[id] = []
            apartments[id].append(device)

            today_file = today + "-log.csv"

            if not Path(today_file).is_file():
                # create a new file if it doesn't exist
                with open(today_file, "w") as file:
                    file.write("time,apartment,thermostat,valve,temp\n")
                    file.close()

            with open(today_file, "a") as file:
                row = ",".join([
                    now, id, device.name,
                    str(device.valve_position),
                    str(device.actual_temperature)
                ]) + "\n"
                file.write(row)
                file.close()
    def init(self, ClassMock, responses):
        self.commander = ClassMock.return_value
        self.commander.update.return_value = responses

        self.cube = MaxCube("host", 1234, now=lambda: datetime(2012, 10, 22, 5, 30))

        self.commander.update.assert_called_once()
        self.commander.update.reset_mock()
        self.commander.send_radio_msg.return_value = True
Exemple #3
0
    def refresh_topology(self):
        time.sleep(0.01)
        self.logger.debug('Starting topology refresh')
        try:
            self.connect()
            cube = MaxCube(self.__max_cube_connection)
            #TODO report cube values to the broker
            # self.__messageQ.put(self.prepare_output('cube', 'free_mem_slots', cube.free_mem_slots))
            # self.__messageQ.put(self.prepare_output('cube', 'duty_cycle', cube.duty_cycle))
            for device in cube.devices:
                device_id = self.update_device(device)
                if device.type in (MAX_THERMOSTAT, MAX_THERMOSTAT_PLUS, MAX_WALL_THERMOSTAT) \
                        and self.enable_sanity_check \
                        and (device_id in self.desired_temperatures) \
                        and (self.desired_temperatures[device_id] != device.target_temperature):
                    try:
                        self.logger.info(
                            "Correcting temperature for device :%s (%s/%s) from:%s to:%s"
                            % (device_id, device.room_name, device.name,
                               device.target_temperature,
                               self.desired_temperatures[device_id]))
                        cube.set_target_temperature(
                            device, self.desired_temperatures[device_id])
                        self.logger.info("Command result:%s" %
                                         cube.command_result)
                        if cube.command_success:
                            self.__messageQ.put(
                                self.prepare_output(
                                    device_id, 'target_temperature',
                                    self.topology[device_id]
                                    ['target_temperature']))
                            self.__messageQ.put(
                                self.prepare_output('cube', 'free_mem_slots',
                                                    cube.free_mem_slots))
                            self.__messageQ.put(
                                self.prepare_output(''
                                                    'cube', 'duty_cycle',
                                                    cube.duty_cycle))
                            self.cube_duty_cycle = cube.duty_cycle
                            self.cube_duty_cycle_reset = time.time()

                    except Exception as e:
                        self.logger.error("Set error:%s" % (format(e)))
        except Exception as e:
            self.logger.error(format(e))
        self.logger.debug('Finished topology refresh')
        if self.update_timer_elapsed():
            self.mqtt_last_refresh = time.time()
            self.dump_topology()
        return (True)
    def onHeartbeat(self):
        #Cancel the rest of this function if this heartbeat needs to be skipped
        if self.beats < self.skipbeats:
            Domoticz.Debug("Skipping heartbeat: " + str(self.beats))
            self.beats += 1
            return
        self.beats=1

        self.HeatDemand = 0

        # Read data from Cube
        Domoticz.Debug("Reading e-Q3 MAX! devices from Cube...")
        try:
            cube = MaxCube(MaxCubeConnection(Parameters["Address"], int(Parameters["Port"])))
        except:
            Domoticz.Error("Error connecting to Cube. Other running MAX! programs may block the communication!")
            return

        # Update devices in Domoticz
        for EQ3device in cube.devices:
            Domoticz.Debug("Checking device '" + EQ3device.name + "' in room " + str(EQ3device.room_id))
            if cube.is_thermostat(EQ3device):
                # Check if valve requires heat
                if EQ3device.valve_position > int(Parameters["Mode4"]): self.HeatDemand += 1
                # Update Domoticz devices for radiator valves
                self.UpdateDevice(EQ3device, "Valve")
                if not self.RoomHasThermostat[EQ3device.room_id]:
                    self.UpdateDevice(EQ3device, "Thermostat")
                    self.UpdateDevice(EQ3device, "Temperature")
                    self.UpdateDevice(EQ3device, "Mode")

            elif cube.is_wallthermostat(EQ3device):
                # Update Domoticz devices for wall thermostats
                self.UpdateDevice(EQ3device, "Thermostat")
                self.UpdateDevice(EQ3device, "Temperature")
                self.UpdateDevice(EQ3device, "Mode")

            elif cube.is_windowshutter(EQ3device):
                # Look up & update Domoticz device for contact switches
                self.UpdateDevice(EQ3device, "Contact")

        # Update heat demand switch if necessary
        Domoticz.Debug(str(self.HeatDemand) + " valves require heat")
        if self.HeatDemand > 0 and Parameters["Mode3"] == "True" and 255 in Devices and Devices[255].sValue == "Off":
            Devices[255].Update(nValue=1, sValue="On")
            Domoticz.Log("Heat demand switch turned on")
        elif self.HeatDemand == 0 and Parameters["Mode3"] == "True" and 255 in Devices and Devices[255].sValue == "On":
            Devices[255].Update(nValue=0, sValue="Off")
            Domoticz.Log("Heat demand switch turned off")
Exemple #5
0
def setup(hass, config):
    """Establish connection to MAX! Cube."""
    from maxcube.connection import MaxCubeConnection
    from maxcube.cube import MaxCube
    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    connection_failed = 0
    gateways = config[DOMAIN][CONF_GATEWAYS]
    for gateway in gateways:
        host = gateway[CONF_HOST]
        port = gateway[CONF_PORT]

        try:
            cube = MaxCube(MaxCubeConnection(host, port))
            hass.data[DATA_KEY][host] = MaxCubeHandle(cube)
        except timeout as ex:
            _LOGGER.error("Unable to connect to Max!Cube gateway: %s", str(ex))
            hass.components.persistent_notification.create(
                'Error: {}<br />'
                'You will need to restart Home Assistant after fixing.'
                ''.format(ex),
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID)
            connection_failed += 1

    if connection_failed >= len(gateways):
        return False

    load_platform(hass, 'climate', DOMAIN)
    load_platform(hass, 'binary_sensor', DOMAIN)

    return True
Exemple #6
0
def setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Establish connection to MAX! Cube."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    connection_failed = 0
    gateways = config[DOMAIN][CONF_GATEWAYS]
    for gateway in gateways:
        host = gateway[CONF_HOST]
        port = gateway[CONF_PORT]
        scan_interval = gateway[CONF_SCAN_INTERVAL].total_seconds()

        try:
            cube = MaxCube(host, port, now=now)
            hass.data[DATA_KEY][host] = MaxCubeHandle(cube, scan_interval)
        except timeout as ex:
            _LOGGER.error("Unable to connect to Max!Cube gateway: %s", str(ex))
            persistent_notification.create(
                hass,
                f"Error: {ex}<br />You will need to restart Home Assistant after fixing.",
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID,
            )
            connection_failed += 1

    if connection_failed >= len(gateways):
        return False

    load_platform(hass, Platform.CLIMATE, DOMAIN, {}, config)
    load_platform(hass, Platform.BINARY_SENSOR, DOMAIN, {}, config)

    return True
Exemple #7
0
    def run(self):

        self.refresh_topology()
        self.topology_last_refresh = time.time()


        while True:
            time.sleep(0.01)
            # resetting internal duty cycle metric
            if time.time() > (self.cube_duty_cycle_reset + self.cube_duty_cycle_reset_interval):
                self.cube_duty_cycle = 0
                self.cube_duty_cycle_reset = time.time()
                self.__messageQ.put(self.prepare_output(
                    'cube', 'duty_cycle', self.cube_duty_cycle))

            # processing incoming data
            if not self.__commandQ.empty():
                try:
                    self.connect()
                    cube = MaxCube(self.__max_cube_connection)
                    while not self.__commandQ.empty():
                        task = self.__commandQ.get()
                        if task['method'] == 'command':
                            if task['param'] == 'target_temperature':
                                self.set_temperature(cube,task['deviceId'],task['payload'])
                            elif task['param'] == 'mode':
                                self.set_mode(cube,task['deviceId'],task['payload'])
                            self.logger.debug("Executing command:%s" % (task))
                except Exception as e:
                    self.logger.error(format(e))
            # refreshing topology
            if self.update_timer_elapsed():
                self.refresh_topology()
                self.topology_last_refresh = time.time()
            self.close()
Exemple #8
0
def setup(hass, config):
    """Establish connection to MAX! Cube."""
    from maxcube.connection import MaxCubeConnection
    from maxcube.cube import MaxCube

    # Read Config
    host = config.get(DOMAIN).get(CONF_HOST)
    port = config.get(DOMAIN).get(CONF_PORT)

    # Assign Cube Handle to global variable
    try:
        cube = MaxCube(MaxCubeConnection(host, port))
    except timeout:
        _LOGGER.error("Connection to Max!Cube could not be established")
        cube = None
        return False

    hass.data[MAXCUBE_HANDLE] = MaxCubeHandle(cube)

    # Load Climate (for Thermostats)
    load_platform(hass, 'climate', DOMAIN)

    # Load BinarySensor (for Window Shutter)
    load_platform(hass, 'binary_sensor', DOMAIN)

    # Initialization successfull
    return True
Exemple #9
0
def setup(hass, config):
    """Establish connection to MAX! Cube."""

    if DATA_KEY not in hass.data:
        hass.data[DATA_KEY] = {}

    connection_failed = 0
    gateways = config[DOMAIN][CONF_GATEWAYS]
    for gateway in gateways:
        host = gateway[CONF_HOST]
        port = gateway[CONF_PORT]
        scan_interval = gateway[CONF_SCAN_INTERVAL].total_seconds()

        try:
            cube = MaxCube(MaxCubeConnection(host, port))
            hass.data[DATA_KEY][host] = MaxCubeHandle(cube, scan_interval)
        except timeout as ex:
            _LOGGER.error("Unable to connect to Max!Cube gateway: %s", str(ex))
            hass.components.persistent_notification.create(
                "Error: {}<br />"
                "You will need to restart Home Assistant after fixing."
                "".format(ex),
                title=NOTIFICATION_TITLE,
                notification_id=NOTIFICATION_ID,
            )
            connection_failed += 1

    if connection_failed >= len(gateways):
        return False

    load_platform(hass, "climate", DOMAIN, {}, config)
    load_platform(hass, "binary_sensor", DOMAIN, {}, config)

    return True
Exemple #10
0
    def __init__(self, address, port):

        # connect to the cube
        self.cube = MaxCube(MaxCubeConnection(address, port))

        # setup the output mode on all the pins
        wiringpi.wiringPiSetup()
        wiringpi.pinMode(PIN1, 1)
        wiringpi.pinMode(PIN2, 1)
        wiringpi.pinMode(PIN3, 1)

        # pin_status dict contains the current status of the output pins
        # status 0 means that the pump is operating normally (turned on)
        # status 1 means that the pump is turned off (1 on the GPIO pin opens the relay)
        self.pin_status = {PIN1: 0, PIN2: 0, PIN3: 0}

        # map apartment IDs to the output pins
        self.pin_mapping = {"10": PIN1, "11": PIN2}
    def onStart(self):
        # Set heartbeat
        self.skipbeats=int(Parameters["Mode5"])/30
        self.beats=self.skipbeats
        Domoticz.Heartbeat(30)

        # Set debugging
        if Parameters["Mode6"]=="True": 
            Domoticz.Debugging(2)
            Domoticz.Debug("Debugging mode activated")

        # Read Cube for intialization of devices
        Domoticz.Debug("Reading e-Q3 MAX! devices from Cube...")
        try:
            cube = MaxCube(MaxCubeConnection(Parameters["Address"], int(Parameters["Port"])))
        except:
            Domoticz.Error("Error connecting to Cube. Other running MAX! programs may block the communication!")
            return
        
        # Check which rooms have a wall mounterd thermostat
        max_room = 0
        for room in cube.rooms:
            if room.id > max_room: max_room = room.id
        Domoticz.Debug("Number of rooms found: " + str((len(cube.rooms))) + " (highest number: " + str(max_room) + ")")
        self.RoomHasThermostat=[False] * (max_room+1)
        for EQ3device in cube.devices:
            if cube.is_wallthermostat(EQ3device):
                self.RoomHasThermostat[EQ3device.room_id] = True
                Domoticz.Debug("Room " + str(EQ3device.room_id) + " (" + cube.room_by_id(EQ3device.room_id).name + ") has a thermostat")

        # Create or delete devices if necessary
        for EQ3device in cube.devices:
            if cube.is_thermostat(EQ3device):
                self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Valve")
                if not self.RoomHasThermostat[EQ3device.room_id]:
                    self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Thermostat")
                    self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Temperature")
                    self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Mode")
            elif cube.is_wallthermostat(EQ3device):
                self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Thermostat")
                self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Temperature")
                self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Mode")
            elif cube.is_windowshutter(EQ3device):
                self.CheckDevice(EQ3device.name, EQ3device.rf_address, "Contact")

        # Create or delete heat demand switch if necessary
        if Parameters["Mode3"] == "True" and 255 not in Devices:
            Domoticz.Device(Name="Heat demand", Unit=255, TypeName="Switch", Image=9, Used=1).Create()
            if 255 not in Devices:
                Domoticz.Error("Heat demand switch could not be created. Is 'Accept new Hardware Devices' enabled under Settings?")
            else:
                Domoticz.Log("Created device '" + Parameters["Name"] + " - Heat demand'") 
                Devices[255].Update(nValue=0, sValue="Off")
        elif Parameters["Mode3"] == "False" and 255 in Devices:
            Devices[255].Delete()
            Domoticz.Log("Deleted heat demand switch")
Exemple #12
0
 def discover(self):
     try:
         self.cube = MaxCube(MaxCubeConnection(self.address, self.port))
     except socket.timeout:
         logging.error('Could not connect to MAX! cube when setting up the bridge. '
             'Make sure nothing else is connected to the MAX! cube at start up and '
             'try again.')
     for device in self.cube.devices:
         if device.type != MAX_THERMOSTAT:
             logging.info('Discovered non-thermostat')
             continue
         self.add_accessory(Thermostat(self.cube, device, self.driver))
    def onCommand(self, Unit, Command, Level, Hue):
        # Update commands for thermostats
        if Devices[Unit].Type == 242 and Devices[Unit].sValue != str(Level):
            Domoticz.Log("Setpoint changed for " + Devices[Unit].Name + ". New setpoint: " + str(Level))
            try:
                cube = MaxCube(MaxCubeConnection(Parameters["Address"], int(Parameters["Port"])))
            except:
                Domoticz.Error("Error connecting to Cube. Other running MAX! programs may block the communication!")
                return
            for EQ3device in cube.devices:
                if Devices[Unit].DeviceID == EQ3device.rf_address:
                    cube.set_target_temperature(EQ3device, Level)
                    Devices[Unit].Update(nValue=0, sValue=str(Level))
                    Devices[Unit].Refresh()

        # Update commands for mode switches
        if Devices[Unit].Type == 244 and Devices[Unit].SubType == 62 and Devices[Unit].sValue != str(Level):
            if Level == 00:
                mode = 0
                mode_text = "Auto"
            elif Level == 10:
                mode = 1
                mode_text = "Manual"
            elif Level == 20:
                mode = 2
                mode_text = "Vacation"
            elif Level == 30:
                mode = 3
                mode_text = "Boost"
            Domoticz.Log("Mode changed for " + Devices[Unit].Name + ". New mode: " + mode_text)
            try:
                cube = MaxCube(MaxCubeConnection(Parameters["Address"], int(Parameters["Port"])))
            except:
                Domoticz.Error("Error connecting to Cube. Other running MAX! programs may block the communication!")
                return
            for EQ3device in cube.devices:
                if Devices[Unit].DeviceID == EQ3device.rf_address:
                    cube.set_mode(EQ3device, mode)
                    Devices[Unit].Update(nValue=0, sValue=str(Level))
                    Devices[Unit].Refresh()
Exemple #14
0
def setup(hass, config):
    """Establish connection to MAX! Cube."""
    from maxcube.connection import MaxCubeConnection
    from maxcube.cube import MaxCube

    host = config.get(DOMAIN).get(CONF_HOST)
    port = config.get(DOMAIN).get(CONF_PORT)

    try:
        cube = MaxCube(MaxCubeConnection(host, port))
    except timeout:
        _LOGGER.error("Connection to Max!Cube could not be established")
        cube = None
        return False

    hass.data[MAXCUBE_HANDLE] = MaxCubeHandle(cube)

    load_platform(hass, 'climate', DOMAIN)
    load_platform(hass, 'binary_sensor', DOMAIN)

    return True
Exemple #15
0
def check_maxdevices(app):
    if not serverIP:
        return

    # only check every 15 minutes
    global minuteCounter
    minuteCounter = minuteCounter + 1
    if minuteCounter > 15:
        minuteCounter = 0
    if minuteCounter != 0:
        return

    try:
        cube = MaxCube(MaxCubeConnection(serverIP, 62910))
    except socket.timeout:
        print "MAX: Timeout..."
        return

    with app.app_context():
        for device in cube.devices:
            if device.linkStatusError != 0:
                statusOk = False
            else:
                statusOk = True

            record = Hosts.query.filter_by(fqdn=device.name).first()
            if record:  # update if MAX! device already exists
                record.status = statusOk
                record.last_checked = datetime.utcnow()
            else:  # otherwise create a new entry
                host = Hosts(fqdn=device.name,
                             friendly_name=None,
                             status=statusOk,
                             last_checked=datetime.utcnow(),
                             type='MAX',
                             idle_duration=60)
                db.session.add(host)
        db.session.commit()
Exemple #16
0
        def Connect(self):

            if not cBaseInterFaceSettings.Connect(self):
                return False

            if self.aInterFaceIniSettings.uHost == '':
                return False

            try:
                if self.oDevice is None:
                    # self.oDevice = Cube(address=self.aInterFaceIniSettings.uHost, port=ToInt(self.aInterFaceIniSettings.uPort))
                    self.oDevice = MaxCube(
                        MaxCubeConnection(
                            host=self.aInterFaceIniSettings.uHost,
                            port=ToInt(self.aInterFaceIniSettings.uPort)))

                # self.oDevice.connect()
                self.oInterFace.oInterFaceConfig.WriteDefinitionConfigPar(
                    uSectionName=self.uSection,
                    uVarName=u'OldDiscoveredIP',
                    uVarValue=self.aInterFaceIniSettings.uHost)
                self.bIsConnected = True
                return self.bIsConnected
            except Exception as e:
                if hasattr(e, "errno"):
                    if e.errno == 10051:
                        self.bOnError = True
                        self.ShowWarning(u'Cannot connect (No Network):' +
                                         self.aInterFaceIniSettings.uHost +
                                         ':' +
                                         self.aInterFaceIniSettings.uPort)
                        return False
                self.ShowError(
                    u'Cannot connect:' + self.aInterFaceIniSettings.uHost +
                    ':' + self.aInterFaceIniSettings.uPort, e)
                self.bOnError = True
                return False
Exemple #17
0
from maxcube.cube import MaxCube
from maxcube.connection import MaxCubeConnection

cube = MaxCube(MaxCubeConnection('192.168.0.20', 62910))

for device in cube.devices:
    print(device.name)
    print(device.actual_temperature)
    print(device.target_temperature)

    cube.set_target_temperature(device, 18)


class MaxcubeMQTT:
    def __init__(self):
        self.cube = MaxCube(MaxCubeConnection('192.168.1.186', 62910))

        print "rooms:"
        for room in self.cube.get_rooms():
            print "%s (%d)" % (room.name, room.id)
class CubeCtrl(object):

    '''
    Wat gaan we doen:
    - haal kamers (naam, id) op
    - haal thermostaat per kamer op (naam, actual_temperature, target_temperature, valve_position)
    - 
    - target temp
    '''

    cube = None

    def __init__(self):
        self.cube = MaxCube(MaxCubeConnection('192.168.1.186', 62910))

        print "rooms:"
        for room in self.cube.get_rooms():
            print "%s (%d)" % (room.name, room.id)

    def get_info(self):

        room = self.cube.room_by_id(1)
        print("Room(1): " + room.name)

        for device in self.cube.devices_by_room(room):

            self.get_device_info(device)

    def set_temperature(self, room_id=1, temp=10.5):
        room = self.cube.room_by_id(1)
        for device in self.cube.devices_by_room(room):
            print(device)
            if self.cube.is_wallthermostat(device) or self.cube.is_thermostat(device):
                print("Setting temp to %s" % str(temp))
                self.cube.set_target_temperature(device, temp)
            else:
                print("No Thermostat")

    def set_device_mode(self, device):
        print(device)
        if self.cube.is_wallthermostat(device):
            print("Setting mode")
            self.cube.set_mode(device, MAX_DEVICE_MODE_MANUAL)
        else:
            print("No Wall Thermostat") 

    def get_device_info(self, device):

        print("Device: " + device.name)
        if device.type == MAX_THERMOSTAT:
            type = "MAX_THERMOSTAT"
        elif device.type == MAX_THERMOSTAT_PLUS:
            type = "MAX_THERMOSTAT_PLUS"
        elif device.type == MAX_WINDOW_SHUTTER:
            type = "MAX_WINDOW_SHUTTER"
        elif device.type == MAX_WALL_THERMOSTAT:
            type = "MAX_WALL_THERMOSTAT"
        print("Type:   " + type)
        print("RF:     " + device.rf_address)
        print("Room ID:" + str(device.room_id))
        print("Room:   " + self.cube.room_by_id(device.room_id).name)
        print("Name:   " + device.name)
        print("Serial: " + device.serial)

        if device.type == MAX_THERMOSTAT:
            print("MaxSetP:" + str(device.max_temperature))
            print("MinSetP:" + str(device.min_temperature))
            if device.mode == MAX_DEVICE_MODE_AUTOMATIC:
                mode = "AUTO"
            elif device.mode == MAX_DEVICE_MODE_MANUAL:
                mode = "MANUAL"
            print("Mode:   " + mode)
            print("Valve: " + str(device.valve_position))
            print("Actual: " + str(device.actual_temperature))
            print("Target: " + str(device.target_temperature))

        if device.type == MAX_WALL_THERMOSTAT:
            print("MaxSetP:" + str(device.max_temperature))
            print("MinSetP:" + str(device.min_temperature))
            if device.mode == MAX_DEVICE_MODE_AUTOMATIC:
                mode = "AUTO"
            elif device.mode == MAX_DEVICE_MODE_MANUAL:
                mode = "MANUAL"
            print("Mode:   " + mode)
            print("Actual: " + str(device.actual_temperature))
            print("Target: " + str(device.target_temperature))

        if device.type == MAX_WINDOW_SHUTTER:
            print("IsOpen: " + str(device.is_open))

        print("")
Exemple #20
0
import argparse
import sys

from maxcube.connection import MaxCubeConnection
from maxcube.cube import MaxCube

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Set or dump thermostat programmes')
    parser.add_argument('--host', required=True)
    parser.add_argument('--port', required=True, type=int)
    parser.add_argument('cmd', choices=['load', 'dump'])
    args = parser.parse_args()
    cube = MaxCube(MaxCubeConnection(args.host, args.port))
    if args.cmd == 'load':
        cube.set_programmes_from_config(sys.stdin)
    elif args.cmd == 'dump':
        print(cube.devices_as_json())
Exemple #21
0
 def setUp(self):
     self.cube = MaxCube(MaxCubeConnectionMock(INIT_RESPONSE_2))
Exemple #22
0
class TestMaxCubeExtended(unittest.TestCase):
    """ Test the Max! Cube. """
    def setUp(self):
        self.cube = MaxCube(MaxCubeConnectionMock(INIT_RESPONSE_2))

    def test_init(self):
        self.assertEqual('015d2a', self.cube.rf_address)
        self.assertEqual('Cube', self.cube.name)
        self.assertEqual('01.13', self.cube.firmware_version)
        self.assertEqual(3, len(self.cube.devices))

    def test_parse_response(self):
        self.cube.parse_response(INIT_RESPONSE_2)
        self.assertEqual('015d2a', self.cube.rf_address)
        self.assertEqual('Cube', self.cube.name)
        self.assertEqual('01.13', self.cube.firmware_version)
        self.assertEqual(3, len(self.cube.devices))

    def test_parse_c_message_thermostat(self):
        device = self.cube.devices[0]
        self.assertEqual(21.5, device.comfort_temperature)
        self.assertEqual(16.5, device.eco_temperature)
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(30.5, device.max_temperature)
        device = self.cube.devices[1]
        self.assertEqual(21.5, device.comfort_temperature)
        self.assertEqual(16.5, device.eco_temperature)
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(30.5, device.max_temperature)
        device = self.cube.devices[2]
        self.assertEqual(1, device.initialized)

    def test_parse_h_message(self):
        self.cube.parse_h_message(
            'H:KEQ0566338,0b6444,0113,00000000,335b04d2,33,32,0f0c1d,101c,03,0000'
        )
        self.assertEqual('0b6444', self.cube.rf_address)
        self.assertEqual('01.13', self.cube.firmware_version)

    def test_parse_m_message(self):
        self.cube.parse_m_message(
            'M:00,01,VgIEAQdLaXRjaGVuBrxTAgZMaXZpbmcGvFoDCFNsZWVwaW5nCKuCBARXb3JrBrxcBAEGvF'
            'NLRVEwMzM2MTA4B0tpdGNoZW4BAQa8WktFUTAzMzYxMDAGTGl2aW5nAgEIq4JLRVEwMzM1NjYyCFNs'
            'ZWVwaW5nAwEGvFxLRVEwMzM2MTA0BFdvcmsEAQ==')
        self.assertEqual('0E2EBA', self.cube.devices[0].rf_address)
        self.assertEqual('Thermostat', self.cube.devices[0].name)
        self.assertEqual(MAX_THERMOSTAT, self.cube.devices[0].type)
        self.assertEqual('KEQ1086437', self.cube.devices[0].serial)
        self.assertEqual(1, self.cube.devices[0].room_id)

        self.assertEqual('0A0881', self.cube.devices[1].rf_address)
        self.assertEqual('Wandthermostat', self.cube.devices[1].name)
        self.assertEqual(MAX_WALL_THERMOSTAT, self.cube.devices[1].type)
        self.assertEqual('KEQ0655743', self.cube.devices[1].serial)
        self.assertEqual(2, self.cube.devices[1].room_id)

        self.assertEqual('0CA2B2', self.cube.devices[2].rf_address)
        self.assertEqual('Fensterkontakt', self.cube.devices[2].name)
        self.assertEqual(MAX_WINDOW_SHUTTER, self.cube.devices[2].type)
        self.assertEqual('KEQ0839778', self.cube.devices[2].serial)
        self.assertEqual(1, self.cube.devices[3].room_id)

        self.assertEqual('Badezimmer', self.cube.rooms[0].name)
        self.assertEqual(1, self.cube.rooms[0].id)

        self.assertEqual('Wohnzimmer', self.cube.rooms[1].name)
        self.assertEqual(2, self.cube.rooms[1].id)

    def test_parse_l_message(self):
        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertEqual(None, device.actual_temperature)
        self.assertEqual(8.0, device.target_temperature)

        device = self.cube.devices[1]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertEqual(22.9, device.actual_temperature)
        self.assertEqual(8.0, device.target_temperature)

        device = self.cube.devices[2]
        self.assertEqual(False, device.is_open)

    def test_resolve_device_mode(self):
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC,
                         self.cube.resolve_device_mode(24))
        self.assertEqual(MAX_DEVICE_MODE_MANUAL,
                         self.cube.resolve_device_mode(25))

    def test_is_thermostat(self):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertEqual(False, device.is_thermostat())
        device.type = MAX_THERMOSTAT
        self.assertEqual(True, device.is_thermostat())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertEqual(True, device.is_thermostat())
        device.type = MAX_WALL_THERMOSTAT
        self.assertEqual(False, device.is_thermostat())
        device.type = MAX_WINDOW_SHUTTER
        self.assertEqual(False, device.is_thermostat())

    def test_is_wall_thermostat(self):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertEqual(False, device.is_wallthermostat())
        device.type = MAX_THERMOSTAT
        self.assertEqual(False, device.is_wallthermostat())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertEqual(False, device.is_wallthermostat())
        device.type = MAX_WALL_THERMOSTAT
        self.assertEqual(True, device.is_wallthermostat())
        device.type = MAX_WINDOW_SHUTTER
        self.assertEqual(False, device.is_wallthermostat())

    def test_is_window_shutter(self):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertEqual(False, device.is_windowshutter())
        device.type = MAX_THERMOSTAT
        self.assertEqual(False, device.is_windowshutter())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertEqual(False, device.is_windowshutter())
        device.type = MAX_WALL_THERMOSTAT
        self.assertEqual(False, device.is_windowshutter())
        device.type = MAX_WINDOW_SHUTTER
        self.assertEqual(True, device.is_windowshutter())

    def test_set_target_temperature_thermostat(self):
        self.cube.set_target_temperature(self.cube.devices[0], 24.5)
        self.assertEqual('s:AARAAAAADi66ATE=\r\n',
                         self.cube.connection.command)
        self.assertEqual(24.5, self.cube.devices[0].target_temperature)

    def test_set_target_temperature_windowshutter(self):
        self.cube.set_target_temperature(self.cube.devices[2], 24.5)
        self.assertEqual(None, self.cube.connection.command)

    def test_set_mode_thermostat(self):
        self.cube.set_mode(self.cube.devices[0], MAX_DEVICE_MODE_MANUAL)
        self.assertEqual('s:AARAAAAADi66AVA=\r\n',
                         self.cube.connection.command)
        self.assertEqual(MAX_DEVICE_MODE_MANUAL, self.cube.devices[0].mode)

    def test_set_mode_windowshutter(self):
        self.cube.set_mode(self.cube.devices[2], 24.5)
        self.assertEqual(None, self.cube.connection.command)

    def test_set_temperature_mode_thermostat(self):
        self.cube.set_temperature_mode(self.cube.devices[2], 24.5,
                                       MAX_DEVICE_MODE_BOOST)
        self.assertEqual(None, self.cube.connection.command)

    def test_get_devices(self):
        devices = self.cube.get_devices()
        self.assertEqual(3, len(devices))

    def test_device_by_rf(self):
        device = self.cube.device_by_rf('0CA2B2')

        self.assertEqual('0CA2B2', device.rf_address)
        self.assertEqual('Fensterkontakt', device.name)
        self.assertEqual(MAX_WINDOW_SHUTTER, device.type)
        self.assertEqual('KEQ0839778', device.serial)
        self.assertEqual(1, device.room_id)

    def test_device_by_rf_negative(self):
        device = self.cube.device_by_rf('DEADBEEF')

        self.assertEqual(None, device)

    def test_devices_by_room(self):
        room = MaxRoom()
        room.id = 1
        devices = self.cube.devices_by_room(room)
        self.assertEqual(2, len(devices))

    def test_devices_by_room_negative(self):
        room = MaxRoom()
        room.id = 3
        devices = self.cube.devices_by_room(room)
        self.assertEqual(0, len(devices))

    def test_get_rooms(self):
        rooms = self.cube.get_rooms()

        self.assertEqual('Badezimmer', rooms[0].name)
        self.assertEqual(1, rooms[0].id)

        self.assertEqual('Wohnzimmer', rooms[1].name)
        self.assertEqual(2, rooms[1].id)

    def test_room_by_id(self):
        room = self.cube.room_by_id(1)

        self.assertEqual('Badezimmer', room.name)
        self.assertEqual(1, room.id)

    def test_room_by_id_negative(self):
        room = self.cube.room_by_id(3)

        self.assertEqual(None, room)

    def test_set_programme(self):
        self.cube.set_programme(self.cube.devices[0], "saturday",
                                [{
                                    'temp': 20.5,
                                    'until': '13:30'
                                }, {
                                    'temp': 18,
                                    'until': '24:00'
                                }])
        self.assertEqual('s:AAAQAAAADi66AQBSokkgAAAAAAA=\r\n',
                         self.cube.connection.command)

    def test_set_programme_already_existing_does_nothing(self):
        result = self.cube.set_programme(self.cube.devices[0], 'saturday',
                                         INIT_PROGRAMME_1['saturday'])
        self.assertEqual(result, None)
        self.assertEqual(self.cube.connection.command, None)

    def test_get_device_as_dict(self):
        device = self.cube.devices[0]
        result = device.to_dict()
        self.assertEqual(result['name'], 'Thermostat')
        self.assertEqual(result['comfort_temperature'], 21.5)
        self.assertEqual(result['programme']['monday'], [{
            'until': '05:30',
            'temp': 8
        }, {
            'until': '06:30',
            'temp': 21
        }, {
            'until': '23:55',
            'temp': 8
        }, {
            'until': '24:00',
            'temp': 8
        }])
Exemple #23
0
class TestMaxCube(unittest.TestCase):
    """ Test the Max! Cube. """
    def setUp(self):
        self.cube = MaxCube(MaxCubeConnectionMock(INIT_RESPONSE_1))

    def test_init(self):
        self.assertEqual('0b6475', self.cube.rf_address)
        self.assertEqual('Cube', self.cube.name)
        self.assertEqual('01.13', self.cube.firmware_version)
        self.assertEqual(4, len(self.cube.devices))

    def test_parse_response(self):
        self.cube.parse_response(INIT_RESPONSE_1)
        self.assertEqual('0b6475', self.cube.rf_address)
        self.assertEqual('Cube', self.cube.name)
        self.assertEqual('01.13', self.cube.firmware_version)
        self.assertEqual(4, len(self.cube.devices))

    def test_parse_c_message(self):
        self.cube.parse_c_message(
            'C:0b6475,7QtkdQATAf9LRVEwNTY2MzM4AAsABEAAAAAAAAAAAP///////////////////////////'
            'wsABEAAAAAAAAAAQf///////////////////////////2h0dHA6Ly93d3cubWF4LXBvcnRhbC5lbHY'
            'uZGU6ODAvY3ViZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
            'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENFVAAACgADAAAOEEN'
            'FU1QAAwACAAAcIA==')
        device = self.cube.devices[0]
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(25.0, device.max_temperature)

    def test_parse_h_message(self):
        self.cube.parse_h_message(
            'H:KEQ0566338,0b6444,0113,00000000,335b04d2,33,32,0f0c1d,101c,03,0000'
        )
        self.assertEqual('0b6444', self.cube.rf_address)
        self.assertEqual('01.13', self.cube.firmware_version)

    def test_parse_m_message(self):
        self.cube.parse_m_message(
            'M:00,01,VgIEAQdLaXRjaGVuBrxTAgZMaXZpbmcGvFoDCFNsZWVwaW5nCKuCBARXb3JrBrxcBAEGvF'
            'NLRVEwMzM2MTA4B0tpdGNoZW4BAQa8WktFUTAzMzYxMDAGTGl2aW5nAgEIq4JLRVEwMzM1NjYyCFNs'
            'ZWVwaW5nAwEGvFxLRVEwMzM2MTA0BFdvcmsEAQ==')
        self.assertEqual('06BC53', self.cube.devices[0].rf_address)
        self.assertEqual('Kitchen', self.cube.devices[0].name)
        self.assertEqual('06BC5A', self.cube.devices[1].rf_address)
        self.assertEqual('Living', self.cube.devices[1].name)
        self.assertEqual('08AB82', self.cube.devices[2].rf_address)
        self.assertEqual('Sleeping', self.cube.devices[2].name)
        self.assertEqual('06BC5C', self.cube.devices[3].rf_address)
        self.assertEqual('Work', self.cube.devices[3].name)

    def test_parse_l_message(self):
        self.cube.parse_l_message(
            'L:Cwa8U/ESGAAiAAAACwa8WgkSGAAiAAAACwa8XAkSGAUiAAAACwirggMSGAUiAAAA'
        )
        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertEqual(23.6, device.actual_temperature)
        self.assertEqual(17.0, device.target_temperature)
        self.cube.parse_l_message(
            'L:Cwa8U/ESGQkhALMACwa8WgkSGQAhAMAACwa8XAkSGQUhALIACwirggMSGQUhAAAA'
        )
        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_MANUAL, device.mode)
        self.assertEqual(17.9, device.actual_temperature)
        self.assertEqual(16.5, device.target_temperature)

    def test_resolve_device_mode(self):
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC,
                         self.cube.resolve_device_mode(24))
        self.assertEqual(MAX_DEVICE_MODE_MANUAL,
                         self.cube.resolve_device_mode(25))

    def test_is_thermostat(self):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertEqual(False, device.is_thermostat())
        device.type = MAX_THERMOSTAT
        self.assertEqual(True, device.is_thermostat())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertEqual(True, device.is_thermostat())

    def test_set_target_temperature(self):
        self.cube.set_target_temperature(self.cube.devices[0], 24.5)
        self.assertEqual('s:AARAAAAABrxTATE=\r\n',
                         self.cube.connection.command)
        self.assertEqual(24.5, self.cube.devices[0].target_temperature)
        self.cube.set_target_temperature(self.cube.devices[0], 24.6)
        self.assertEqual(24.5, self.cube.devices[0].target_temperature)
#!/usr/bin/python
from maxcube.cube import MaxCube
from maxcube.connection import MaxCubeConnection
from maxcube.device import \
    MAX_THERMOSTAT, \
    MAX_THERMOSTAT_PLUS, \
    MAX_WINDOW_SHUTTER, \
    MAX_WALL_THERMOSTAT, \
    MAX_DEVICE_MODE_AUTOMATIC, \
    MAX_DEVICE_MODE_MANUAL, \
    MAX_DEVICE_MODE_VACATION, \
    MAX_DEVICE_MODE_BOOST
import logging

cube = MaxCube(MaxCubeConnection('192.168.XXX.XXX', 62910))

for room in cube.rooms:
    print("Room: " + room.name)
    for device in cube.devices_by_room(room):
        print("Device: " + device.name)

print("")

for device in cube.devices:
    if device.type == MAX_THERMOSTAT:
        type = "MAX_THERMOSTAT"
    elif device.type == MAX_THERMOSTAT_PLUS:
        type = "MAX_THERMOSTAT_PLUS"
    elif device.type == MAX_WINDOW_SHUTTER:
        type = "MAX_WINDOW_SHUTTER"
    elif device.type == MAX_WALL_THERMOSTAT:
MAX_DEVICE_MODE_HOME = 4

PUBLISH_ONLY_CHANGES = 0
PUBLISH_ALL = 1

# INIT LOGGER
FORMAT = '%(asctime)-15s %(levelname)s %(name)s [%(funcName)s] %(message)s'
LOGFILE = "/home/pi/eq3/maxcubed.log"
#logging.basicConfig(filename=LOGFILE, format=FORMAT, level=logging.DEBUG)
logging.basicConfig(filename=LOGFILE, format=FORMAT, level=logging.INFO)
logger = logging.getLogger(__name__)

# INIT CUBE
#try:
cube = MaxCube(MaxCubeConnection('192.168.0.16', 62910))
#except:
#  logger.error("Could not initialize cube. Exiting")
#  exit()
logger.info("Cube initialized")

# INIT MQTT
success = False
while not success:
    try:
        client = mqtt.Client("maxcubed")
        success = True
    except:
        logger.warning("Could not connect to MQTT. Will retry")
        time.sleep(5)
logger.info("MQTT initialized")
class TestMaxCube(TestCase):
    """ Test the Max! Cube. """

    def init(self, ClassMock, responses):
        self.commander = ClassMock.return_value
        self.commander.update.return_value = responses

        self.cube = MaxCube("host", 1234, now=lambda: datetime(2012, 10, 22, 5, 30))

        self.commander.update.assert_called_once()
        self.commander.update.reset_mock()
        self.commander.send_radio_msg.return_value = True

    def test_init(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        self.assertEqual("KEQ0566338", self.cube.serial)
        self.assertEqual("0b6475", self.cube.rf_address)
        self.assertEqual("Cube", self.cube.name)
        self.assertEqual("01.13", self.cube.firmware_version)
        self.assertEqual(4, len(self.cube.devices))

        device = self.cube.devices[0]
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(25.0, device.max_temperature)
        self.assertEqual("06BC53", device.rf_address)
        self.assertEqual("Kitchen", device.name)

        self.assertEqual("06BC5A", self.cube.devices[1].rf_address)
        self.assertEqual("Living", self.cube.devices[1].name)

        self.assertEqual("08AB82", self.cube.devices[2].rf_address)
        self.assertEqual("Sleeping", self.cube.devices[2].name)

        self.assertEqual("06BC5C", self.cube.devices[3].rf_address)
        self.assertEqual("Work", self.cube.devices[3].name)

    def __update(self, responses: List[Message]):
        self.commander.update.return_value = responses
        self.cube.update()
        self.commander.update.assert_called_once()

    def test_parse_auto_l_message(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        self.__update([LAST_STATE_MSG])

        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertEqual(23.6, device.actual_temperature)
        self.assertEqual(17.0, device.target_temperature)

    def test_parse_manual_l_message(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        self.__update(
            [
                Message.decode(
                    b"L:Cwa8U/ESGQkhALMACwa8WgkSGQAhAMAACwa8XAkSGQUhALIACwirggMSGQUhAAAA"
                )
            ]
        )

        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_MANUAL, device.mode)
        self.assertEqual(17.9, device.actual_temperature)
        self.assertEqual(16.5, device.target_temperature)

    def test_disconnect(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        self.cube.disconnect()
        self.commander.disconnect.assert_called_once()

    def test_use_persistent_connection(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        self.commander.use_persistent_connection = True
        self.assertTrue(self.cube.use_persistent_connection)
        self.cube.use_persistent_connection = False
        self.assertFalse(self.commander.use_persistent_connection)

    def test_is_thermostat(self, _):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertFalse(device.is_thermostat())
        device.type = MAX_THERMOSTAT
        self.assertTrue(device.is_thermostat())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertTrue(device.is_thermostat())
        device.type = MAX_WALL_THERMOSTAT
        self.assertFalse(device.is_thermostat())
        device.type = MAX_WINDOW_SHUTTER
        self.assertFalse(device.is_thermostat())

    def test_is_wall_thermostat(self, _):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertFalse(device.is_wallthermostat())
        device.type = MAX_THERMOSTAT
        self.assertFalse(device.is_wallthermostat())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertFalse(device.is_wallthermostat())
        device.type = MAX_WALL_THERMOSTAT
        self.assertTrue(device.is_wallthermostat())
        device.type = MAX_WINDOW_SHUTTER
        self.assertFalse(device.is_wallthermostat())

    def test_is_window_shutter(self, _):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertFalse(device.is_windowshutter())
        device.type = MAX_THERMOSTAT
        self.assertFalse(device.is_windowshutter())
        device.type = MAX_THERMOSTAT_PLUS
        self.assertFalse(device.is_windowshutter())
        device.type = MAX_WALL_THERMOSTAT
        self.assertFalse(device.is_windowshutter())
        device.type = MAX_WINDOW_SHUTTER
        self.assertTrue(device.is_windowshutter())

    def test_set_target_temperature(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)

        self.assertTrue(self.cube.set_target_temperature(self.cube.devices[0], 24.5))

        self.assertEqual(24.5, self.cube.devices[0].target_temperature)
        self.commander.send_radio_msg.assert_called_once()
        self.commander.send_radio_msg.assert_called_with("00044000000006BC530131")

    def test_do_not_update_if_set_target_temperature_fails(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        self.commander.send_radio_msg.return_value = False

        self.assertFalse(self.cube.set_target_temperature(self.cube.devices[0], 24.5))

        self.assertEqual(21, self.cube.devices[0].target_temperature)
        self.commander.send_radio_msg.assert_called_once()
        self.commander.send_radio_msg.assert_called_with("00044000000006BC530131")

    def test_set_target_temperature_should_round_temperature(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)

        self.cube.set_target_temperature(self.cube.devices[0], 24.6)

        self.assertEqual(24.5, self.cube.devices[0].target_temperature)
        self.commander.send_radio_msg.assert_called_once()
        self.commander.send_radio_msg.assert_called_with("00044000000006BC530131")

    def test_set_target_temperature_is_ignored_by_windowshutter(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        self.cube.set_target_temperature(self.cube.devices[2], 24.5)
        self.commander.send_radio_msg.assert_not_called()

    def test_set_mode_thermostat(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_1)
        device = self.cube.devices[0]
        self.assertEqual(21.0, device.target_temperature)
        self.cube.set_mode(device, MAX_DEVICE_MODE_MANUAL)

        self.assertEqual(MAX_DEVICE_MODE_MANUAL, device.mode)
        self.commander.send_radio_msg.assert_called_once()
        self.commander.send_radio_msg.assert_called_with("00044000000006BC53016A")

    def test_init_2(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        self.assertEqual("JEQ0341267", self.cube.serial)
        self.assertEqual("015d2a", self.cube.rf_address)
        self.assertEqual("Cube", self.cube.name)
        self.assertEqual("01.13", self.cube.firmware_version)
        self.assertEqual(3, len(self.cube.devices))

        device = self.cube.devices[0]
        self.assertEqual(21.5, device.comfort_temperature)
        self.assertEqual(16.5, device.eco_temperature)
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(30.5, device.max_temperature)
        device = self.cube.devices[1]
        self.assertEqual(21.5, device.comfort_temperature)
        self.assertEqual(16.5, device.eco_temperature)
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(30.5, device.max_temperature)
        device = self.cube.devices[2]
        self.assertEqual(1, device.initialized)

        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertIsNone(device.actual_temperature)
        self.assertEqual(8.0, device.target_temperature)

        device = self.cube.devices[1]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertEqual(22.9, device.actual_temperature)
        self.assertEqual(8.0, device.target_temperature)

        device = self.cube.devices[2]
        self.assertFalse(device.is_open)
        self.assertTrue(device.battery == MAX_DEVICE_BATTERY_LOW)

    def test_parse_m_message(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        self.__update(
            [
                Message.decode(
                    b"M:00,01,VgIEAQdLaXRjaGVuBrxTAgZMaXZpbmcGvFoDCFNsZWVwaW5nCKuCBARXb3JrBrxcBAEGvF"
                    b"NLRVEwMzM2MTA4B0tpdGNoZW4BAQa8WktFUTAzMzYxMDAGTGl2aW5nAgEIq4JLRVEwMzM1NjYyCFNs"
                    b"ZWVwaW5nAwEGvFxLRVEwMzM2MTA0BFdvcmsEAQ=="
                ),
                INIT_RESPONSE_2[-1],
            ]
        )

        self.assertEqual("0E2EBA", self.cube.devices[0].rf_address)
        self.assertEqual("Thermostat", self.cube.devices[0].name)
        self.assertEqual(MAX_THERMOSTAT, self.cube.devices[0].type)
        self.assertEqual("KEQ1086437", self.cube.devices[0].serial)
        self.assertEqual(1, self.cube.devices[0].room_id)

        self.assertEqual("0A0881", self.cube.devices[1].rf_address)
        self.assertEqual("Wandthermostat", self.cube.devices[1].name)
        self.assertEqual(MAX_WALL_THERMOSTAT, self.cube.devices[1].type)
        self.assertEqual("KEQ0655743", self.cube.devices[1].serial)
        self.assertEqual(2, self.cube.devices[1].room_id)

        self.assertEqual("0CA2B2", self.cube.devices[2].rf_address)
        self.assertEqual("Fensterkontakt", self.cube.devices[2].name)
        self.assertEqual(MAX_WINDOW_SHUTTER, self.cube.devices[2].type)
        self.assertEqual("KEQ0839778", self.cube.devices[2].serial)
        self.assertEqual(1, self.cube.devices[2].room_id)

        self.assertEqual("Kitchen", self.cube.rooms[0].name)
        self.assertEqual(1, self.cube.rooms[0].id)

        self.assertEqual("Living", self.cube.rooms[1].name)
        self.assertEqual(2, self.cube.rooms[1].id)

    def test_get_devices(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        devices = self.cube.get_devices()
        self.assertEqual(3, len(devices))

    def test_device_by_rf(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        device = self.cube.device_by_rf("0CA2B2")

        self.assertEqual("0CA2B2", device.rf_address)
        self.assertEqual("Fensterkontakt", device.name)
        self.assertEqual(MAX_WINDOW_SHUTTER, device.type)
        self.assertEqual("KEQ0839778", device.serial)
        self.assertEqual(1, device.room_id)

    def test_device_by_rf_negative(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        device = self.cube.device_by_rf("DEADBEEF")

        self.assertIsNone(device)

    def test_devices_by_room(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        room = MaxRoom()
        room.id = 1
        devices = self.cube.devices_by_room(room)
        self.assertEqual(2, len(devices))

    def test_devices_by_room_negative(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        room = MaxRoom()
        room.id = 3
        devices = self.cube.devices_by_room(room)
        self.assertEqual(0, len(devices))

    def test_get_rooms(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        rooms = self.cube.get_rooms()

        self.assertEqual("Badezimmer", rooms[0].name)
        self.assertEqual(1, rooms[0].id)

        self.assertEqual("Wohnzimmer", rooms[1].name)
        self.assertEqual(2, rooms[1].id)

    def test_room_by_id(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        room = self.cube.room_by_id(1)

        self.assertEqual("Badezimmer", room.name)
        self.assertEqual(1, room.id)

    def test_room_by_id_negative(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        room = self.cube.room_by_id(3)

        self.assertIsNone(room)

    def test_set_programme(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        self.commander.send_radio_msg.return_value = True
        result = self.cube.set_programme(
            self.cube.devices[0],
            "saturday",
            [{"temp": 20.5, "until": "13:30"}, {"temp": 18, "until": "24:00"}],
        )
        self.assertTrue(result)
        self.commander.send_radio_msg.assert_called_once()
        self.commander.send_radio_msg.assert_called_with(
            "0000100000000E2EBA010052A249200000000000"
        )

    def test_set_programme_already_existing_does_nothing(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        result = self.cube.set_programme(
            self.cube.devices[0], "saturday", INIT_PROGRAMME_1["saturday"]
        )
        self.assertIsNone(result)
        self.commander.send_radio_msg.assert_not_called()

    def test_get_device_as_dict(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        device = self.cube.devices[0]
        result = device.to_dict()
        self.assertEqual(result["name"], "Thermostat")
        self.assertEqual(result["comfort_temperature"], 21.5)
        self.assertEqual(
            result["programme"]["monday"],
            [
                {"until": "05:30", "temp": 8},
                {"until": "06:30", "temp": 21},
                {"until": "23:55", "temp": 8},
                {"until": "24:00", "temp": 8},
            ],
        )

    def test_set_auto_mode_read_temp_from_program(self, ClassMock):
        self.init(ClassMock, INIT_RESPONSE_2)
        device = self.cube.devices[0]
        self.assertEqual(8.0, device.target_temperature)
        self.cube.set_mode(device, MAX_DEVICE_MODE_AUTOMATIC)
        self.assertEqual(21.0, device.target_temperature)
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.commander.send_radio_msg.assert_called_once()
        self.commander.send_radio_msg.assert_called_with("0004400000000E2EBA0100")
Exemple #27
0
from maxcube.cube import MaxCube
from maxcube.connection import MaxCubeConnection
from maxcube.device import \
    MAX_THERMOSTAT, \
    MAX_THERMOSTAT_PLUS, \
    MAX_WINDOW_SHUTTER, \
    MAX_WALL_THERMOSTAT, \
    MAX_DEVICE_MODE_AUTOMATIC, \
    MAX_DEVICE_MODE_MANUAL, \
    MAX_DEVICE_MODE_VACATION, \
    MAX_DEVICE_MODE_BOOST
import logging

cube = MaxCube(MaxCubeConnection('192.168.0.20', 62910))

for room in cube.rooms:
    print("Room: " + room.name)
    for device in cube.devices_by_room(room):
        print("Device: " + device.name)

print("")

for device in cube.devices:
    if device.type == MAX_THERMOSTAT:
        type = "MAX_THERMOSTAT"
    elif device.type == MAX_THERMOSTAT_PLUS:
        type = "MAX_THERMOSTAT_PLUS"
    elif device.type == MAX_WINDOW_SHUTTER:
        type = "MAX_WINDOW_SHUTTER"
    elif device.type == MAX_WALL_THERMOSTAT:
        type = "MAX_WALL_THERMOSTAT"
Exemple #28
0
import os

from maxcube.cube import MaxCube
from maxcube.device import (
    MAX_DEVICE_MODE_AUTOMATIC,
    MAX_DEVICE_MODE_MANUAL,
    MAX_THERMOSTAT,
    MAX_THERMOSTAT_PLUS,
    MAX_WALL_THERMOSTAT,
    MAX_WINDOW_SHUTTER,
)

cube = MaxCube(os.environ.get("MAXCUBE_IP", "192.168.0.20"), 62910)

print("Serial: %s" % (cube.serial))
for room in cube.rooms:
    print("Room: " + room.name)
    for device in cube.devices_by_room(room):
        print("Device: " + device.name)

print("")

for device in cube.devices:
    if device.type == MAX_THERMOSTAT:
        type = "MAX_THERMOSTAT"
    elif device.type == MAX_THERMOSTAT_PLUS:
        type = "MAX_THERMOSTAT_PLUS"
    elif device.type == MAX_WINDOW_SHUTTER:
        type = "MAX_WINDOW_SHUTTER"
    elif device.type == MAX_WALL_THERMOSTAT:
        type = "MAX_WALL_THERMOSTAT"
Exemple #29
0
        print(i['Name'] + " has a idx " + i['idx'])
        domoticz_props[i['Name']] = [i['idx'], i['LastUpdate'], i['Data']]

#searching for -Sens
url = "http://" + DOMOTICZ_IP + ":" + DOMOTICZ_PORT + "/json.htm?type=devices&filter=temp&used=true&order=Name"

response = urllib.urlopen(url)

data = json.loads(response.read())

for i in data['result']:
    if i['Name'][-5:] == "-Sens":
        #print (i['Name'] + " has a idx " + i['idx'] + " last updated " + i['LastUpdate'])
        domoticz_props[i['Name']] = [i['idx'], i['LastUpdate'], i['Data']]

cube = MaxCube(MaxCubeConnection(IP_CUBE, PORT_CUBE))

for device in cube.devices:
    if device.type != MAX_THERMOSTAT:
        print("Not a thermostat ommiting this device")
    else:
        print("Updating Termostat: " + device.name + 'Read valve open: ' +
              str(device.valve_position) + ' Read temperature: ' +
              str(device.actual_temperature))
        #updating domoticz with the read value
        search_name = device.name[0:-5].encode('ascii', 'ignore')
        url = "http://" + DOMOTICZ_IP + ":" + DOMOTICZ_PORT + "/json.htm?type=command&param=udevice&idx=" + domoticz_props[
            search_name + '-Rad'][0] + "&nvalue=0&svalue=" + str(
                device.valve_position)
        response = urllib.urlopen(url)
        if str(device.actual_temperature) != "None":
Exemple #30
0
    def __init__(self, address, port):

        # connect to the cube
        self.cube = MaxCube(MaxCubeConnection(address, port))
class TestMaxCube(unittest.TestCase):
    """ Test the Max! Cube. """

    def setUp(self):
        self.cube = MaxCube(MaxCubeConnectionMock())

    def test_init(self):
        self.assertEqual('0b6475', self.cube.rf_address)
        self.assertEqual('Cube', self.cube.name)
        self.assertEqual('01.13', self.cube.firmware_version)
        self.assertEqual(4, len(self.cube.devices))

    def test_parse_response(self):
        self.cube.parse_response(INIT_RESPONSE)
        self.assertEqual('0b6475', self.cube.rf_address)
        self.assertEqual('Cube', self.cube.name)
        self.assertEqual('01.13', self.cube.firmware_version)
        self.assertEqual(4, len(self.cube.devices))

    def test_parse_c_message(self):
        self.cube.parse_c_message('C:0b6475,7QtkdQATAf9LRVEwNTY2MzM4AAsABEAAAAAAAAAAAP///////////////////////////'
                                  'wsABEAAAAAAAAAAQf///////////////////////////2h0dHA6Ly93d3cubWF4LXBvcnRhbC5lbHY'
                                  'uZGU6ODAvY3ViZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
                                  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENFVAAACgADAAAOEEN'
                                  'FU1QAAwACAAAcIA==')
        device = self.cube.devices[0]
        self.assertEqual(4.5, device.min_temperature)
        self.assertEqual(25.0, device.max_temperature)

    def test_parse_h_message(self):
        self.cube.parse_h_message('H:KEQ0566338,0b6444,0113,00000000,335b04d2,33,32,0f0c1d,101c,03,0000')
        self.assertEqual('0b6444', self.cube.rf_address)
        self.assertEqual('01.13', self.cube.firmware_version)

    def test_parse_m_message(self):
        self.cube.parse_m_message('M:00,01,VgIEAQdLaXRjaGVuBrxTAgZMaXZpbmcGvFoDCFNsZWVwaW5nCKuCBARXb3JrBrxcBAEGvF'
                                  'NLRVEwMzM2MTA4B0tpdGNoZW4BAQa8WktFUTAzMzYxMDAGTGl2aW5nAgEIq4JLRVEwMzM1NjYyCFNs'
                                  'ZWVwaW5nAwEGvFxLRVEwMzM2MTA0BFdvcmsEAQ==')
        self.assertEqual('6BC53', self.cube.devices[0].rf_address)
        self.assertEqual('Kitchen', self.cube.devices[0].name)
        self.assertEqual('6BC5A', self.cube.devices[1].rf_address)
        self.assertEqual('Living', self.cube.devices[1].name)
        self.assertEqual('8AB82', self.cube.devices[2].rf_address)
        self.assertEqual('Sleeping', self.cube.devices[2].name)
        self.assertEqual('6BC5C', self.cube.devices[3].rf_address)
        self.assertEqual('Work', self.cube.devices[3].name)

    def test_parse_l_message(self):
        self.cube.parse_l_message('L:Cwa8U/ESGAAiAAAACwa8WgkSGAAiAAAACwa8XAkSGAUiAAAACwirggMSGAUiAAAA')
        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, device.mode)
        self.assertEqual(23.6, device.actual_temperature)
        self.assertEqual(17.0, device.target_temperature)
        self.cube.parse_l_message('L:Cwa8U/ESGQkhALMACwa8WgkSGQAhAMAACwa8XAkSGQUhALIACwirggMSGQUhAAAA')
        device = self.cube.devices[0]
        self.assertEqual(MAX_DEVICE_MODE_MANUAL, device.mode)
        self.assertEqual(17.9, device.actual_temperature)
        self.assertEqual(16.5, device.target_temperature)

    def test_resolve_device_mode(self):
        self.assertEqual(MAX_DEVICE_MODE_AUTOMATIC, self.cube.resolve_device_mode(24))
        self.assertEqual(MAX_DEVICE_MODE_MANUAL, self.cube.resolve_device_mode(25))

    def test_is_thermostat(self):
        device = MaxDevice()
        device.type = MAX_CUBE
        self.assertEqual(False, self.cube.is_thermostat(device))
        device.type = MAX_THERMOSTAT
        self.assertEqual(True, self.cube.is_thermostat(device))
        device.type = MAX_THERMOSTAT_PLUS
        self.assertEqual(True, self.cube.is_thermostat(device))

    def test_set_target_temperature(self):
        self.cube.set_target_temperature(self.cube.devices[0], 24.5)
        self.assertEqual('s:AARAAAAABrxTATE=\r\n', self.cube.connection.command)
        self.assertEqual(24.5, self.cube.devices[0].target_temperature)
        self.cube.set_target_temperature(self.cube.devices[0], 24.6)
        self.assertEqual(24.5, self.cube.devices[0].target_temperature)
Exemple #32
0
 def setUp(self):
     self.cube = MaxCube(MaxCubeConnectionMock())
 def setUp(self):
     self.cube = MaxCube(MaxCubeConnectionMock())
Exemple #34
0
class Controller:
    def __init__(self, address, port):

        # connect to the cube
        self.cube = MaxCube(MaxCubeConnection(address, port))

        # setup the output mode on all the pins
        wiringpi.wiringPiSetup()
        wiringpi.pinMode(PIN1, 1)
        wiringpi.pinMode(PIN2, 1)
        wiringpi.pinMode(PIN3, 1)

        # pin_status dict contains the current status of the output pins
        # status 0 means that the pump is operating normally (turned on)
        # status 1 means that the pump is turned off (1 on the GPIO pin opens the relay)
        self.pin_status = {PIN1: 0, PIN2: 0, PIN3: 0}

        # map apartment IDs to the output pins
        self.pin_mapping = {"10": PIN1, "11": PIN2}

    def update_pins(self):
        """
        update the GPIO pins to the status set in the self.pin_status dictionary
        """
        for pin in [PIN1, PIN2, PIN3]:
            wiringpi.digitalWrite(pin, self.pin_status[pin])

    def scan_and_update_pins(self):
        """
        Scan for all the connected thermostats. They are named "ID_name", where ID is the id of the apartment.

        If valves on all the thermostats in an apartment are set to 0, turn off the corresponding pin
        """
        self.cube.update()

        apartments = {}

        print(len(self.cube.devices), "devices found")
        for device in self.cube.devices:
            id = device.name.split("_")[0]
            if id not in apartments:
                apartments[id] = []
            apartments[id].append(device)

        for id in apartments.keys():
            all_off = True
            for device in apartments[id]:
                all_off &= device.valve_position == 0

            if all_off:
                if self.pin_status[self.pin_mapping[id]] == 0:
                    print("The pump for apartment", id, "will be turned off.")
                self.pin_status[self.pin_mapping[id]] = 1
            else:
                if self.pin_status[self.pin_mapping[id]] == 1:
                    print("The pump for apartment", id,
                          "will be turned back on.")
                self.pin_status[self.pin_mapping[id]] = 0

            self.update_pins()

    def run_forever(self, interval=5):
        while True:
            try:
                self.scan_and_update_pins()
                sleep(interval * 60)
            except Exception:
                print("Background sleep was terminated, exiting the loop")
                break

        # turn everything to 0 and exit
        wiringpi.wiringPiSetup()
        wiringpi.pinMode(PIN1, 1)
        wiringpi.pinMode(PIN2, 1)
        wiringpi.pinMode(PIN3, 1)
        wiringpi.digitalWrite(PIN1, 0)
        wiringpi.digitalWrite(PIN2, 0)
        wiringpi.digitalWrite(PIN3, 0)

        print("All the pumps are now on")
        print("Controller is shutting down")