class EcobeeObject(object):
    __slots__ = []

    attribute_name_map = {}

    attribute_type_map = {}

    def __repr__(self):
        return (
            '{0}('.format(self.__class__.__name__)
            + ', '.join(
                [
                    '{0}={1!r}'.format(
                        attribute_name[1:], getattr(self, attribute_name)
                    )
                    for attribute_name in self.slots()
                ]
            )
            + ')'
        )

    def __str__(self):
        return (
            '{0}('.format(self.__class__.__name__)
            + ', '.join(
                [
                    '{0}={1!s}'.format(
                        type(self).attribute_name_map[attribute_name[1:]],
                        getattr(self, attribute_name),
                    )
                    for attribute_name in self.slots()
                ]
            )
            + ')'
        )

    def pretty_format(self, indent=2, level=0, sort_attributes=True):
        """
        Pretty format a response object

        :param indent: The amount of indentation added for each
        recursive level
        :param level: The recursion level
        :param sort_attributes: Whether to sort the attributes or not
        :return: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        pretty_formatted = ['{0}(\n'.format(self.__class__.__name__)]
        level = level + 1

        for (i, attribute_name) in enumerate(
            sorted(self.slots()) if sort_attributes else self.slots()
        ):
            if i:
                pretty_formatted.append(',\n')

            if isinstance(getattr(self, attribute_name), list):
                pretty_formatted.append(
                    '{0}{1}=[\n'.format(
                        ' ' * (indent * level),
                        self.attribute_name_map[attribute_name[1:]],
                    )
                )
                level = level + 1

                for (j, list_entry) in enumerate(getattr(self, attribute_name)):
                    if j:
                        pretty_formatted.append(',\n')

                    if hasattr(list_entry, 'pretty_format'):
                        pretty_formatted.append(
                            '{0}{1}'.format(
                                ' ' * (indent * level),
                                list_entry.pretty_format(
                                    indent, level, sort_attributes
                                ),
                            )
                        )
                    else:
                        if isinstance(list_entry, list):
                            pretty_formatted.append(
                                '{0}[\n'.format(' ' * (indent * level))
                            )

                            level = level + 1

                            for (k, sub_list_entry) in enumerate(list_entry):
                                if k:
                                    pretty_formatted.append(',\n')

                                pretty_formatted.append(
                                    '{0}{1}'.format(
                                        ' ' * (indent * level), sub_list_entry
                                    )
                                )

                            if list_entry:
                                pretty_formatted.append('\n')

                            level = level - 1
                            pretty_formatted.append(
                                '{0}]'.format(' ' * (indent * level))
                            )
                        else:
                            pretty_formatted.append(
                                '{0}{1}'.format(' ' * (indent * level), list_entry)
                            )

                if getattr(self, attribute_name):
                    pretty_formatted.append('\n')

                level = level - 1
                pretty_formatted.append('{0}]'.format(' ' * (indent * level)))
            else:
                pretty_formatted.append(' ' * (indent * level))

                if hasattr(getattr(self, attribute_name), 'pretty_format'):
                    pretty_formatted.append(
                        '{0}={1!s}'.format(
                            self.attribute_name_map[attribute_name[1:]],
                            getattr(self, attribute_name).pretty_format(
                                indent, level, sort_attributes
                            ),
                        )
                    )
                else:
                    pretty_formatted.append(
                        '{0}={1!s}'.format(
                            self.attribute_name_map[attribute_name[1:]],
                            getattr(self, attribute_name),
                        )
                    )

        level = level - 1
        pretty_formatted.append('\n{0})'.format(' ' * (indent * level)))

        return ''.join(pretty_formatted)

    def slots(self):
        return chain.from_iterable(
            getattr(cls, '__slots__', []) for cls in type(self).__mro__
        ) class AckType(Enum):
    ACCEPT = 'accept'
    DECLINE = 'decline'
    DEFER = 'defer'
    UNACKNOWLEDGED = 'unacknowledged' class FanMode(Enum):
    AUTO = 'auto'
    ON = 'on' class HoldType(Enum):
    HOLD_HOURS = 'holdHours'
    INDEFINITE = 'indefinite'
    NEXT_TRANSITION = 'nextTransition'
    DATE_TIME = 'dateTime' class PlugState(Enum):
    OFF = 'off'
    ON = 'on'
    RESUME = 'resume' class Scope(Enum):
    EMS = 'ems'
    SMART_READ = 'smartRead'
    SMART_WRITE = 'smartWrite' class SelectionType(Enum):
    MANAGEMENT_SET = 'managementSet'
    REGISTERED = 'registered'
    THERMOSTATS = 'thermostats' class DemandManagement(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/DemandManagement.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = ['_date', '_hour', '_temp_offsets']

    attribute_name_map = {
        'date': 'date',
        'hour': 'hour',
        'temp_offsets': 'tempOffsets',
        'tempOffsets': 'temp_offsets',
    }

    attribute_type_map = {
        'date': 'six.text_type',
        'hour': 'int',
        'temp_offsets': 'List[int]',
    }

    def __init__(self, date, hour, temp_offsets):
        """
        Construct a DemandManagement instance
        """
        self._date = date
        self._hour = hour
        self._temp_offsets = temp_offsets

    @property
    def date(self):
        """
        Gets the date attribute of this DemandManagement instance.

        :return: The value of the date attribute of this
        DemandManagement instance.
        :rtype: six.text_type
        """

        return self._date

    @date.setter
    def date(self, date):
        """
        Sets the date attribute of this DemandManagement instance.

        :param date: The date value to set for the date attribute of
        this DemandManagement instance.
        :type: six.text_type
        """

        self._date = date

    @property
    def hour(self):
        """
        Gets the hour attribute of this DemandManagement instance.

        :return: The value of the hour attribute of this
        DemandManagement instance.
        :rtype: int
        """

        return self._hour

    @hour.setter
    def hour(self, hour):
        """
        Sets the hour attribute of this DemandManagement instance.

        :param hour: The hour value to set for the hour attribute of
        this DemandManagement instance.
        :type: int
        """

        self._hour = hour

    @property
    def temp_offsets(self):
        """
        Gets the temp_offsets attribute of this DemandManagement
        instance.

        :return: The value of the temp_offsets attribute of this
        DemandManagement instance.
        :rtype: List[int]
        """

        return self._temp_offsets

    @temp_offsets.setter
    def temp_offsets(self, temp_offsets):
        """
        Sets the temp_offsets attribute of this DemandManagement
        instance.

        :param temp_offsets: The temp_offsets value to set for the
        temp_offsets attribute of this DemandManagement instance.
        :type: List[int]
        """

        self._temp_offsets = temp_offsets class DemandResponse(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/DemandResponse.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = [
        '_name',
        '_demand_response_ref',
        '_comments',
        '_message',
        '_deferred_date',
        '_deferred_time',
        '_show_idt',
        '_show_web',
        '_send_email',
        '_randomize_start_time',
        '_random_start_time_seconds',
        '_randomize_end_time',
        '_random_end_time_seconds',
        '_event',
        '_thermostats',
        '_external_ref',
        '_external_ref_type',
        '_priority',
    ]

    attribute_name_map = {
        'name': 'name',
        'demand_response_ref': 'demandResponseRef',
        'demandResponseRef': 'demand_response_ref',
        'comments': 'comments',
        'message': 'message',
        'deferred_date': 'deferredDate',
        'deferredDate': 'deferred_date',
        'deferred_time': 'deferredTime',
        'deferredTime': 'deferred_time',
        'show_idt': 'showIdt',
        'showIdt': 'show_idt',
        'show_web': 'showWeb',
        'showWeb': 'show_web',
        'send_email': 'sendEmail',
        'sendEmail': 'send_email',
        'randomize_start_time': 'randomizeStartTime',
        'randomizeStartTime': 'randomize_start_time',
        'random_start_time_seconds': 'randomStartTimeSeconds',
        'randomStartTimeSeconds': 'random_start_time_seconds',
        'randomize_end_time': 'randomizeEndTime',
        'randomizeEndTime': 'randomize_end_time',
        'random_end_time_seconds': 'randomEndTimeSeconds',
        'randomEndTimeSeconds': 'random_end_time_seconds',
        'event': 'event',
        'thermostats': 'thermostats',
        'external_ref': 'externalRef',
        'externalRef': 'external_ref',
        'external_ref_type': 'externalRefType',
        'externalRefType': 'external_ref_type',
        'priority': 'priority',
    }

    attribute_type_map = {
        'name': 'six.text_type',
        'demand_response_ref': 'six.text_type',
        'comments': 'six.text_type',
        'message': 'six.text_type',
        'deferred_date': 'six.text_type',
        'deferred_time': 'six.text_type',
        'show_idt': 'bool',
        'show_web': 'bool',
        'send_email': 'bool',
        'randomize_start_time': 'bool',
        'random_start_time_seconds': 'int',
        'randomize_end_time': 'bool',
        'random_end_time_seconds': 'int',
        'event': 'Event',
        'thermostats': 'List[six.text_type]',
        'external_ref': 'six.text_type',
        'external_ref_type': 'six.text_type',
        'priority': 'Long',
    }

    def __init__(
        self,
        name=None,
        demand_response_ref=None,
        comments=None,
        message=None,
        deferred_date=None,
        deferred_time=None,
        show_idt=None,
        show_web=None,
        send_email=None,
        randomize_start_time=None,
        random_start_time_seconds=None,
        randomize_end_time=None,
        random_end_time_seconds=None,
        event=None,
        thermostats=None,
        external_ref=None,
        external_ref_type=None,
        priority=None,
    ):
        """
        Construct a DemandResponse instance
        """
        self._name = name
        self._demand_response_ref = demand_response_ref
        self._comments = comments
        self._message = message
        self._deferred_date = deferred_date
        self._deferred_time = deferred_time
        self._show_idt = show_idt
        self._show_web = show_web
        self._send_email = send_email
        self._randomize_start_time = randomize_start_time
        self._random_start_time_seconds = random_start_time_seconds
        self._randomize_end_time = randomize_end_time
        self._random_end_time_seconds = random_end_time_seconds
        self._event = event
        self._thermostats = thermostats
        self._external_ref = external_ref
        self._external_ref_type = external_ref_type
        self._priority = priority

    @property
    def name(self):
        """
        Gets the name attribute of this DemandResponse instance.

        :return: The value of the name attribute of this DemandResponse
        instance.
        :rtype: six.text_type
        """

        return self._name

    @name.setter
    def name(self, name):
        """
        Sets the name attribute of this DemandResponse instance.

        :param name: The name value to set for the name attribute of
        this DemandResponse instance.
        :type: six.text_type
        """

        self._name = name

    @property
    def demand_response_ref(self):
        """
        Gets the demand_response_ref attribute of this DemandResponse
        instance.

        :return: The value of the demand_response_ref attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._demand_response_ref

    @property
    def comments(self):
        """
        Gets the comments attribute of this DemandResponse instance.

        :return: The value of the comments attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._comments

    @comments.setter
    def comments(self, comments):
        """
        Sets the comments attribute of this DemandResponse instance.

        :param comments: The comments value to set for the comments
        attribute of this DemandResponse instance.
        :type: six.text_type
        """

        self._comments = comments

    @property
    def message(self):
        """
        Gets the message attribute of this DemandResponse instance.

        :return: The value of the message attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._message

    @message.setter
    def message(self, message):
        """
        Sets the message attribute of this DemandResponse instance.

        :param message: The message value to set for the message
        attribute of this DemandResponse instance.
        :type: six.text_type
        """

        self._message = message

    @property
    def deferred_date(self):
        """
        Gets the deferred_date attribute of this DemandResponse
        instance.

        :return: The value of the deferred_date attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._deferred_date

    @deferred_date.setter
    def deferred_date(self, deferred_date):
        """
        Sets the deferred_date attribute of this DemandResponse
        instance.

        :param deferred_date: The deferred_date value to set for the
        deferred_date attribute of this DemandResponse instance.
        :type: six.text_type
        """

        self._deferred_date = deferred_date

    @property
    def deferred_time(self):
        """
        Gets the deferred_time attribute of this DemandResponse
        instance.

        :return: The value of the deferred_time attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._deferred_time

    @deferred_time.setter
    def deferred_time(self, deferred_time):
        """
        Sets the deferred_time attribute of this DemandResponse
        instance.

        :param deferred_time: The deferred_time value to set for the
        deferred_time attribute of this DemandResponse instance.
        :type: six.text_type
        """

        self._deferred_time = deferred_time

    @property
    def show_idt(self):
        """
        Gets the show_idt attribute of this DemandResponse instance.

        :return: The value of the show_idt attribute of this
        DemandResponse instance.
        :rtype: bool
        """

        return self._show_idt

    @show_idt.setter
    def show_idt(self, show_idt):
        """
        Sets the show_idt attribute of this DemandResponse instance.

        :param show_idt: The show_idt value to set for the show_idt
        attribute of this DemandResponse instance.
        :type: bool
        """

        self._show_idt = show_idt

    @property
    def show_web(self):
        """
        Gets the show_web attribute of this DemandResponse instance.

        :return: The value of the show_web attribute of this
        DemandResponse instance.
        :rtype: bool
        """

        return self._show_web

    @show_web.setter
    def show_web(self, show_web):
        """
        Sets the show_web attribute of this DemandResponse instance.

        :param show_web: The show_web value to set for the show_web
        attribute of this DemandResponse instance.
        :type: bool
        """

        self._show_web = show_web

    @property
    def send_email(self):
        """
        Gets the send_email attribute of this DemandResponse instance.

        :return: The value of the send_email attribute of this
        DemandResponse instance.
        :rtype: bool
        """

        return self._send_email

    @send_email.setter
    def send_email(self, send_email):
        """
        Sets the send_email attribute of this DemandResponse instance.

        :param send_email: The send_email value to set for the
        send_email attribute of this DemandResponse instance.
        :type: bool
        """

        self._send_email = send_email

    @property
    def randomize_start_time(self):
        """
        Gets the randomize_start_time attribute of this DemandResponse
        instance.

        :return: The value of the randomize_start_time attribute of this
        DemandResponse instance.
        :rtype: bool
        """

        return self._randomize_start_time

    @randomize_start_time.setter
    def randomize_start_time(self, randomize_start_time):
        """
        Sets the randomize_start_time attribute of this DemandResponse
        instance.

        :param randomize_start_time: The randomize_start_time value to
        set for the randomize_start_time attribute of this
        DemandResponse instance.
        :type: bool
        """

        self._randomize_start_time = randomize_start_time

    @property
    def random_start_time_seconds(self):
        """
        Gets the random_start_time_seconds attribute of this
        DemandResponse instance.

        :return: The value of the random_start_time_seconds attribute of
        this DemandResponse instance.
        :rtype: int
        """

        return self._random_start_time_seconds

    @random_start_time_seconds.setter
    def random_start_time_seconds(self, random_start_time_seconds):
        """
        Sets the random_start_time_seconds attribute of this
        DemandResponse instance.

        :param random_start_time_seconds: The random_start_time_seconds
        value to set for the random_start_time_seconds attribute of this
        DemandResponse instance.
        :type: int
        """

        self._random_start_time_seconds = random_start_time_seconds

    @property
    def randomize_end_time(self):
        """
        Gets the randomize_end_time attribute of this DemandResponse
        instance.

        :return: The value of the randomize_end_time attribute of this
        DemandResponse instance.
        :rtype: bool
        """

        return self._randomize_end_time

    @randomize_end_time.setter
    def randomize_end_time(self, randomize_end_time):
        """
        Sets the randomize_end_time attribute of this DemandResponse
        instance.

        :param randomize_end_time: The randomize_end_time value to set
        for the randomize_end_time attribute of this DemandResponse
        instance.
        :type: bool
        """

        self._randomize_end_time = randomize_end_time

    @property
    def random_end_time_seconds(self):
        """
        Gets the random_end_time_seconds attribute of this
        DemandResponse instance.

        :return: The value of the random_end_time_seconds attribute of
        this DemandResponse instance.
        :rtype: int
        """

        return self._random_end_time_seconds

    @random_end_time_seconds.setter
    def random_end_time_seconds(self, random_end_time_seconds):
        """
        Sets the random_end_time_seconds attribute of this
        DemandResponse instance.

        :param random_end_time_seconds: The random_end_time_seconds
        value to set for the random_end_time_seconds attribute of this
        DemandResponse instance.
        :type: int
        """

        self._random_end_time_seconds = random_end_time_seconds

    @property
    def event(self):
        """
        Gets the event attribute of this DemandResponse instance.

        :return: The value of the event attribute of this DemandResponse
        instance.
        :rtype: Event
        """

        return self._event

    @event.setter
    def event(self, event):
        """
        Sets the event attribute of this DemandResponse instance.

        :param event: The event value to set for the event attribute of
        this DemandResponse instance.
        :type: Event
        """

        self._event = event

    @property
    def thermostats(self):
        """
        Gets the thermostats attribute of this DemandResponse instance.

        :return: The value of the thermostats attribute of this
        DemandResponse instance.
        :rtype: List[six.text_type]
        """

        return self._thermostats

    @property
    def external_ref(self):
        """
        Gets the external_ref attribute of this DemandResponse instance.

        :return: The value of the external_ref attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._external_ref

    @external_ref.setter
    def external_ref(self, external_ref):
        """
        Sets the external_ref attribute of this DemandResponse instance.

        :param external_ref: The external_ref value to set for the
        external_ref attribute of this DemandResponse instance.
        :type: six.text_type
        """

        self._external_ref = external_ref

    @property
    def external_ref_type(self):
        """
        Gets the external_ref_type attribute of this DemandResponse
        instance.

        :return: The value of the external_ref_type attribute of this
        DemandResponse instance.
        :rtype: six.text_type
        """

        return self._external_ref_type

    @external_ref_type.setter
    def external_ref_type(self, external_ref_type):
        """
        Sets the external_ref_type attribute of this DemandResponse
        instance.

        :param external_ref_type: The external_ref_type value to set for
        the external_ref_type attribute of this DemandResponse instance.
        :type: six.text_type
        """

        self._external_ref_type = external_ref_type

    @property
    def priority(self):
        """
        Gets the priority attribute of this DemandResponse instance.

        :return: The value of the priority attribute of this
        DemandResponse instance.
        :rtype: Long
        """

        return self._priority

    @priority.setter
    def priority(self, priority):
        """
        Sets the priority attribute of this DemandResponse instance.

        :param priority: The priority value to set for the priority
        attribute of this DemandResponse instance.
        :type: Long
        """

        self._priority = priority class Function(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/Function.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = ['_type', '_params']

    attribute_name_map = {'type': 'type', 'params': 'params'}

    attribute_type_map = {
        'type': 'six.text_type',
        'params': 'Dict[six.text_type, object]',
    }

    def __init__(self, type_=None, params=None):
        """
        Construct a Function instance
        """
        self._type = type_
        self._params = params

    @property
    def type(self):
        """
        Gets the type attribute of this Function instance.

        :return: The value of the type attribute of this Function
        instance.
        :rtype: six.text_type
        """

        return self._type

    @type.setter
    def type(self, type_):
        """
        Sets the type attribute of this Function instance.

        :param type: The type value to set for the type attribute of
        this Function instance.
        :type: six.text_type
        """

        self._type = type_

    @property
    def params(self):
        """
        Gets the params attribute of this Function instance.

        :return: The value of the params attribute of this Function
        instance.
        :rtype: Dict[six.text_type, object]
        """

        return self._params

    @params.setter
    def params(self, params):
        """
        Sets the params attribute of this Function instance.

        :param params: The params value to set for the params attribute
        of this Function instance.
        :type: Dict[six.text_type, object]
        """

        self._params = params class Group(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/Group.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = [
        '_group_name',
        '_group_ref',
        '_synchronize_alerts',
        '_synchronize_system_mode',
        '_synchronize_schedule',
        '_synchronize_quick_save',
        '_synchronize_reminders',
        '_synchronize_contractor_info',
        '_synchronize_user_preferences',
        '_synchronize_utility_info',
        '_synchronize_location',
        '_synchronize_reset',
        '_synchronize_vacation',
        '_thermostats',
    ]

    attribute_name_map = {
        'group_name': 'groupName',
        'groupName': 'group_name',
        'group_ref': 'groupRef',
        'groupRef': 'group_ref',
        'synchronize_alerts': 'synchronizeAlerts',
        'synchronizeAlerts': 'synchronize_alerts',
        'synchronize_system_mode': 'synchronizeSystemMode',
        'synchronizeSystemMode': 'synchronize_system_mode',
        'synchronize_schedule': 'synchronizeSchedule',
        'synchronizeSchedule': 'synchronize_schedule',
        'synchronize_quick_save': 'synchronizeQuickSave',
        'synchronizeQuickSave': 'synchronize_quick_save',
        'synchronize_reminders': 'synchronizeReminders',
        'synchronizeReminders': 'synchronize_reminders',
        'synchronize_contractor_info': 'synchronizeContractorInfo',
        'synchronizeContractorInfo': 'synchronize_contractor_info',
        'synchronize_user_preferences': 'synchronizeUserPreferences',
        'synchronizeUserPreferences': 'synchronize_user_preferences',
        'synchronize_utility_info': 'synchronizeUtilityInfo',
        'synchronizeUtilityInfo': 'synchronize_utility_info',
        'synchronize_location': 'synchronizeLocation',
        'synchronizeLocation': 'synchronize_location',
        'synchronize_reset': 'synchronizeReset',
        'synchronizeReset': 'synchronize_reset',
        'synchronize_vacation': 'synchronizeVacation',
        'synchronizeVacation': 'synchronize_vacation',
        'thermostats': 'thermostats',
    }

    attribute_type_map = {
        'group_name': 'six.text_type',
        'group_ref': 'six.text_type',
        'synchronize_alerts': 'bool',
        'synchronize_system_mode': 'bool',
        'synchronize_schedule': 'bool',
        'synchronize_quick_save': 'bool',
        'synchronize_reminders': 'bool',
        'synchronize_contractor_info': 'bool',
        'synchronize_user_preferences': 'bool',
        'synchronize_utility_info': 'bool',
        'synchronize_location': 'bool',
        'synchronize_reset': 'bool',
        'synchronize_vacation': 'bool',
        'thermostats': 'List[six.text_type]',
    }

    def __init__(
        self,
        group_name,
        group_ref=None,
        synchronize_alerts=None,
        synchronize_system_mode=None,
        synchronize_schedule=None,
        synchronize_quick_save=None,
        synchronize_reminders=None,
        synchronize_contractor_info=None,
        synchronize_user_preferences=None,
        synchronize_utility_info=None,
        synchronize_location=None,
        synchronize_reset=None,
        synchronize_vacation=None,
        thermostats=None,
    ):
        """
        Construct a Group instance
        """
        self._group_name = group_name
        self._group_ref = group_ref
        self._synchronize_alerts = synchronize_alerts
        self._synchronize_system_mode = synchronize_system_mode
        self._synchronize_schedule = synchronize_schedule
        self._synchronize_quick_save = synchronize_quick_save
        self._synchronize_reminders = synchronize_reminders
        self._synchronize_contractor_info = synchronize_contractor_info
        self._synchronize_user_preferences = synchronize_user_preferences
        self._synchronize_utility_info = synchronize_utility_info
        self._synchronize_location = synchronize_location
        self._synchronize_reset = synchronize_reset
        self._synchronize_vacation = synchronize_vacation
        self._thermostats = thermostats

    @property
    def group_name(self):
        """
        Gets the group_name attribute of this Group instance.

        :return: The value of the group_name attribute of this Group
        instance.
        :rtype: six.text_type
        """

        return self._group_name

    @group_name.setter
    def group_name(self, group_name):
        """
        Sets the group_name attribute of this Group instance.

        :param group_name: The group_name value to set for the
        group_name attribute of this Group instance.
        :type: six.text_type
        """

        self._group_name = group_name

    @property
    def group_ref(self):
        """
        Gets the group_ref attribute of this Group instance.

        :return: The value of the group_ref attribute of this Group
        instance.
        :rtype: six.text_type
        """

        return self._group_ref

    @property
    def synchronize_alerts(self):
        """
        Gets the synchronize_alerts attribute of this Group instance.

        :return: The value of the synchronize_alerts attribute of this
        Group instance.
        :rtype: bool
        """

        return self._synchronize_alerts

    @synchronize_alerts.setter
    def synchronize_alerts(self, synchronize_alerts):
        """
        Sets the synchronize_alerts attribute of this Group instance.

        :param synchronize_alerts: The synchronize_alerts value to set
        for the synchronize_alerts attribute of this Group instance.
        :type: bool
        """

        self._synchronize_alerts = synchronize_alerts

    @property
    def synchronize_system_mode(self):
        """
        Gets the synchronize_system_mode attribute of this Group
        instance.

        :return: The value of the synchronize_system_mode attribute of
        this Group instance.
        :rtype: bool
        """

        return self._synchronize_system_mode

    @synchronize_system_mode.setter
    def synchronize_system_mode(self, synchronize_system_mode):
        """
        Sets the synchronize_system_mode attribute of this Group
        instance.

        :param synchronize_system_mode: The synchronize_system_mode
        value to set for the synchronize_system_mode attribute of this
        Group instance.
        :type: bool
        """

        self._synchronize_system_mode = synchronize_system_mode

    @property
    def synchronize_schedule(self):
        """
        Gets the synchronize_schedule attribute of this Group instance.

        :return: The value of the synchronize_schedule attribute of this
        Group instance.
        :rtype: bool
        """

        return self._synchronize_schedule

    @synchronize_schedule.setter
    def synchronize_schedule(self, synchronize_schedule):
        """
        Sets the synchronize_schedule attribute of this Group instance.

        :param synchronize_schedule: The synchronize_schedule value to
        set for the synchronize_schedule attribute of this Group
        instance.
        :type: bool
        """

        self._synchronize_schedule = synchronize_schedule

    @property
    def synchronize_quick_save(self):
        """
        Gets the synchronize_quick_save attribute of this Group
        instance.

        :return: The value of the synchronize_quick_save attribute of
        this Group instance.
        :rtype: bool
        """

        return self._synchronize_quick_save

    @synchronize_quick_save.setter
    def synchronize_quick_save(self, synchronize_quick_save):
        """
        Sets the synchronize_quick_save attribute of this Group
        instance.

        :param synchronize_quick_save: The synchronize_quick_save value
        to set for the synchronize_quick_save attribute of this Group
        instance.
        :type: bool
        """

        self._synchronize_quick_save = synchronize_quick_save

    @property
    def synchronize_reminders(self):
        """
        Gets the synchronize_reminders attribute of this Group instance.

        :return: The value of the synchronize_reminders attribute of
        this Group instance.
        :rtype: bool
        """

        return self._synchronize_reminders

    @synchronize_reminders.setter
    def synchronize_reminders(self, synchronize_reminders):
        """
        Sets the synchronize_reminders attribute of this Group instance.

        :param synchronize_reminders: The synchronize_reminders value to
        set for the synchronize_reminders attribute of this Group
        instance.
        :type: bool
        """

        self._synchronize_reminders = synchronize_reminders

    @property
    def synchronize_contractor_info(self):
        """
        Gets the synchronize_contractor_info attribute of this Group
        instance.

        :return: The value of the synchronize_contractor_info attribute
        of this Group instance.
        :rtype: bool
        """

        return self._synchronize_contractor_info

    @synchronize_contractor_info.setter
    def synchronize_contractor_info(self, synchronize_contractor_info):
        """
        Sets the synchronize_contractor_info attribute of this Group
        instance.

        :param synchronize_contractor_info: The
        synchronize_contractor_info value to set for the
        synchronize_contractor_info attribute of this Group instance.
        :type: bool
        """

        self._synchronize_contractor_info = synchronize_contractor_info

    @property
    def synchronize_user_preferences(self):
        """
        Gets the synchronize_user_preferences attribute of this Group
        instance.

        :return: The value of the synchronize_user_preferences attribute
        of this Group instance.
        :rtype: bool
        """

        return self._synchronize_user_preferences

    @synchronize_user_preferences.setter
    def synchronize_user_preferences(self, synchronize_user_preferences):
        """
        Sets the synchronize_user_preferences attribute of this Group
        instance.

        :param synchronize_user_preferences: The
        synchronize_user_preferences value to set for the
        synchronize_user_preferences attribute of this Group instance.
        :type: bool
        """

        self._synchronize_user_preferences = synchronize_user_preferences

    @property
    def synchronize_utility_info(self):
        """
        Gets the synchronize_utility_info attribute of this Group
        instance.

        :return: The value of the synchronize_utility_info attribute of
        this Group instance.
        :rtype: bool
        """

        return self._synchronize_utility_info

    @synchronize_utility_info.setter
    def synchronize_utility_info(self, synchronize_utility_info):
        """
        Sets the synchronize_utility_info attribute of this Group
        instance.

        :param synchronize_utility_info: The synchronize_utility_info
        value to set for the synchronize_utility_info attribute of this
        Group instance.
        :type: bool
        """

        self._synchronize_utility_info = synchronize_utility_info

    @property
    def synchronize_location(self):
        """
        Gets the synchronize_location attribute of this Group instance.

        :return: The value of the synchronize_location attribute of this
        Group instance.
        :rtype: bool
        """

        return self._synchronize_location

    @synchronize_location.setter
    def synchronize_location(self, synchronize_location):
        """
        Sets the synchronize_location attribute of this Group instance.

        :param synchronize_location: The synchronize_location value to
        set for the synchronize_location attribute of this Group
        instance.
        :type: bool
        """

        self._synchronize_location = synchronize_location

    @property
    def synchronize_reset(self):
        """
        Gets the synchronize_reset attribute of this Group instance.

        :return: The value of the synchronize_reset attribute of this
        Group instance.
        :rtype: bool
        """

        return self._synchronize_reset

    @synchronize_reset.setter
    def synchronize_reset(self, synchronize_reset):
        """
        Sets the synchronize_reset attribute of this Group instance.

        :param synchronize_reset: The synchronize_reset value to set for
        the synchronize_reset attribute of this Group instance.
        :type: bool
        """

        self._synchronize_reset = synchronize_reset

    @property
    def synchronize_vacation(self):
        """
        Gets the synchronize_vacation attribute of this Group instance.

        :return: The value of the synchronize_vacation attribute of this
        Group instance.
        :rtype: bool
        """

        return self._synchronize_vacation

    @synchronize_vacation.setter
    def synchronize_vacation(self, synchronize_vacation):
        """
        Sets the synchronize_vacation attribute of this Group instance.

        :param synchronize_vacation: The synchronize_vacation value to
        set for the synchronize_vacation attribute of this Group
        instance.
        :type: bool
        """

        self._synchronize_vacation = synchronize_vacation

    @property
    def thermostats(self):
        """
        Gets the thermostats attribute of this Group instance.

        :return: The value of the thermostats attribute of this Group
        instance.
        :rtype: List[six.text_type]
        """

        return self._thermostats

    @thermostats.setter
    def thermostats(self, thermostats):
        """
        Sets the thermostats attribute of this Group instance.

        :param thermostats: The thermostats value to set for the
        thermostats attribute of this Group instance.
        :type: List[six.text_type]
        """

        self._thermostats = thermostats class HierarchyPrivilege(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/HierarchyPrivilege.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = [
        '_set_path',
        '_user_name',
        '_set_name',
        '_allow_all',
        '_allow_none',
        '_allow_view',
        '_allow_program',
        '_allow_vacation',
        '_allow_settings',
        '_allow_details',
        '_allow_report',
        '_allow_security',
        '_allow_hierarchy',
        '_allow_alerts',
        '_allow_manage_account',
    ]

    attribute_name_map = {
        'set_path': 'setPath',
        'setPath': 'set_path',
        'user_name': 'userName',
        'userName': 'user_name',
        'set_name': 'setName',
        'setName': 'set_name',
        'allow_all': 'allowAll',
        'allowAll': 'allow_all',
        'allow_none': 'allowNone',
        'allowNone': 'allow_none',
        'allow_view': 'allowView',
        'allowView': 'allow_view',
        'allow_program': 'allowProgram',
        'allowProgram': 'allow_program',
        'allow_vacation': 'allowVacation',
        'allowVacation': 'allow_vacation',
        'allow_settings': 'allowSettings',
        'allowSettings': 'allow_settings',
        'allow_details': 'allowDetails',
        'allowDetails': 'allow_details',
        'allow_report': 'allowReport',
        'allowReport': 'allow_report',
        'allow_security': 'allowSecurity',
        'allowSecurity': 'allow_security',
        'allow_hierarchy': 'allowHierarchy',
        'allowHierarchy': 'allow_hierarchy',
        'allow_alerts': 'allowAlerts',
        'allowAlerts': 'allow_alerts',
        'allow_manage_account': 'allowManageAccount',
        'allowManageAccount': 'allow_manage_account',
    }

    attribute_type_map = {
        'set_path': 'six.text_type',
        'user_name': 'six.text_type',
        'set_name': 'six.text_type',
        'allow_all': 'bool',
        'allow_none': 'bool',
        'allow_view': 'bool',
        'allow_program': 'bool',
        'allow_vacation': 'bool',
        'allow_settings': 'bool',
        'allow_details': 'bool',
        'allow_report': 'bool',
        'allow_security': 'bool',
        'allow_hierarchy': 'bool',
        'allow_alerts': 'bool',
        'allow_manage_account': 'bool',
    }

    def __init__(
        self,
        set_path,
        user_name,
        set_name=None,
        allow_all=None,
        allow_none=None,
        allow_view=None,
        allow_program=None,
        allow_vacation=None,
        allow_settings=None,
        allow_details=None,
        allow_report=None,
        allow_security=None,
        allow_hierarchy=None,
        allow_alerts=None,
        allow_manage_account=None,
    ):
        """
        Construct a HierarchyPrivilege instance
        """
        self._set_path = set_path
        self._user_name = user_name
        self._set_name = set_name
        self._allow_all = allow_all
        self._allow_none = allow_none
        self._allow_view = allow_view
        self._allow_program = allow_program
        self._allow_vacation = allow_vacation
        self._allow_settings = allow_settings
        self._allow_details = allow_details
        self._allow_report = allow_report
        self._allow_security = allow_security
        self._allow_hierarchy = allow_hierarchy
        self._allow_alerts = allow_alerts
        self._allow_manage_account = allow_manage_account

    @property
    def set_path(self):
        """
        Gets the set_path attribute of this HierarchyPrivilege instance.

        :return: The value of the set_path attribute of this
        HierarchyPrivilege instance.
        :rtype: six.text_type
        """

        return self._set_path

    @set_path.setter
    def set_path(self, set_path):
        """
        Sets the set_path attribute of this HierarchyPrivilege instance.

        :param set_path: The set_path value to set for the set_path
        attribute of this HierarchyPrivilege instance.
        :type: six.text_type
        """

        self._set_path = set_path

    @property
    def user_name(self):
        """
        Gets the user_name attribute of this HierarchyPrivilege
        instance.

        :return: The value of the user_name attribute of this
        HierarchyPrivilege instance.
        :rtype: six.text_type
        """

        return self._user_name

    @user_name.setter
    def user_name(self, user_name):
        """
        Sets the user_name attribute of this HierarchyPrivilege
        instance.

        :param user_name: The user_name value to set for the user_name
        attribute of this HierarchyPrivilege instance.
        :type: six.text_type
        """

        self._user_name = user_name

    @property
    def set_name(self):
        """
        Gets the set_name attribute of this HierarchyPrivilege instance.

        :return: The value of the set_name attribute of this
        HierarchyPrivilege instance.
        :rtype: six.text_type
        """

        return self._set_name

    @property
    def allow_all(self):
        """
        Gets the allow_all attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_all attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_all

    @allow_all.setter
    def allow_all(self, allow_all):
        """
        Sets the allow_all attribute of this HierarchyPrivilege
        instance.

        :param allow_all: The allow_all value to set for the allow_all
        attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_all = allow_all

    @property
    def allow_none(self):
        """
        Gets the allow_none attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_none attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_none

    @allow_none.setter
    def allow_none(self, allow_none):
        """
        Sets the allow_none attribute of this HierarchyPrivilege
        instance.

        :param allow_none: The allow_none value to set for the
        allow_none attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_none = allow_none

    @property
    def allow_view(self):
        """
        Gets the allow_view attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_view attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_view

    @allow_view.setter
    def allow_view(self, allow_view):
        """
        Sets the allow_view attribute of this HierarchyPrivilege
        instance.

        :param allow_view: The allow_view value to set for the
        allow_view attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_view = allow_view

    @property
    def allow_program(self):
        """
        Gets the allow_program attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_program attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_program

    @allow_program.setter
    def allow_program(self, allow_program):
        """
        Sets the allow_program attribute of this HierarchyPrivilege
        instance.

        :param allow_program: The allow_program value to set for the
        allow_program attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_program = allow_program

    @property
    def allow_vacation(self):
        """
        Gets the allow_vacation attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_vacation attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_vacation

    @allow_vacation.setter
    def allow_vacation(self, allow_vacation):
        """
        Sets the allow_vacation attribute of this HierarchyPrivilege
        instance.

        :param allow_vacation: The allow_vacation value to set for the
        allow_vacation attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_vacation = allow_vacation

    @property
    def allow_settings(self):
        """
        Gets the allow_settings attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_settings attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_settings

    @allow_settings.setter
    def allow_settings(self, allow_settings):
        """
        Sets the allow_settings attribute of this HierarchyPrivilege
        instance.

        :param allow_settings: The allow_settings value to set for the
        allow_settings attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_settings = allow_settings

    @property
    def allow_details(self):
        """
        Gets the allow_details attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_details attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_details

    @allow_details.setter
    def allow_details(self, allow_details):
        """
        Sets the allow_details attribute of this HierarchyPrivilege
        instance.

        :param allow_details: The allow_details value to set for the
        allow_details attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_details = allow_details

    @property
    def allow_report(self):
        """
        Gets the allow_report attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_report attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_report

    @allow_report.setter
    def allow_report(self, allow_report):
        """
        Sets the allow_report attribute of this HierarchyPrivilege
        instance.

        :param allow_report: The allow_report value to set for the
        allow_report attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_report = allow_report

    @property
    def allow_security(self):
        """
        Gets the allow_security attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_security attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_security

    @allow_security.setter
    def allow_security(self, allow_security):
        """
        Sets the allow_security attribute of this HierarchyPrivilege
        instance.

        :param allow_security: The allow_security value to set for the
        allow_security attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_security = allow_security

    @property
    def allow_hierarchy(self):
        """
        Gets the allow_hierarchy attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_hierarchy attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_hierarchy

    @allow_hierarchy.setter
    def allow_hierarchy(self, allow_hierarchy):
        """
        Sets the allow_hierarchy attribute of this HierarchyPrivilege
        instance.

        :param allow_hierarchy: The allow_hierarchy value to set for the
        allow_hierarchy attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_hierarchy = allow_hierarchy

    @property
    def allow_alerts(self):
        """
        Gets the allow_alerts attribute of this HierarchyPrivilege
        instance.

        :return: The value of the allow_alerts attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_alerts

    @allow_alerts.setter
    def allow_alerts(self, allow_alerts):
        """
        Sets the allow_alerts attribute of this HierarchyPrivilege
        instance.

        :param allow_alerts: The allow_alerts value to set for the
        allow_alerts attribute of this HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_alerts = allow_alerts

    @property
    def allow_manage_account(self):
        """
        Gets the allow_manage_account attribute of this
        HierarchyPrivilege instance.

        :return: The value of the allow_manage_account attribute of this
        HierarchyPrivilege instance.
        :rtype: bool
        """

        return self._allow_manage_account

    @allow_manage_account.setter
    def allow_manage_account(self, allow_manage_account):
        """
        Sets the allow_manage_account attribute of this
        HierarchyPrivilege instance.

        :param allow_manage_account: The allow_manage_account value to
        set for the allow_manage_account attribute of this
        HierarchyPrivilege instance.
        :type: bool
        """

        self._allow_manage_account = allow_manage_account class HierarchyUser(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/HierarchyUser.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = [
        '_user_name',
        '_first_name',
        '_last_name',
        '_phone',
        '_last_login',
        '_active',
        '_email_alerts',
    ]

    attribute_name_map = {
        'user_name': 'userName',
        'userName': 'user_name',
        'first_name': 'firstName',
        'firstName': 'first_name',
        'last_name': 'lastName',
        'lastName': 'last_name',
        'phone': 'phone',
        'last_login': 'lastLogin',
        'lastLogin': 'last_login',
        'active': 'active',
        'email_alerts': 'emailAlerts',
        'emailAlerts': 'email_alerts',
    }

    attribute_type_map = {
        'user_name': 'six.text_type',
        'first_name': 'six.text_type',
        'last_name': 'six.text_type',
        'phone': 'six.text_type',
        'last_login': 'six.text_type',
        'active': 'bool',
        'email_alerts': 'bool',
    }

    def __init__(
        self,
        user_name,
        first_name=None,
        last_name=None,
        phone=None,
        last_login=None,
        active=None,
        email_alerts=None,
    ):
        """
        Construct a HierarchyUser instance
        """
        self._user_name = user_name
        self._first_name = first_name
        self._last_name = last_name
        self._phone = phone
        self._last_login = last_login
        self._active = active
        self._email_alerts = email_alerts

    @property
    def user_name(self):
        """
        Gets the user_name attribute of this HierarchyUser instance.

        :return: The value of the user_name attribute of this
        HierarchyUser instance.
        :rtype: six.text_type
        """

        return self._user_name

    @user_name.setter
    def user_name(self, user_name):
        """
        Sets the user_name attribute of this HierarchyUser instance.

        :param user_name: The user_name value to set for the user_name
        attribute of this HierarchyUser instance.
        :type: six.text_type
        """

        self._user_name = user_name

    @property
    def first_name(self):
        """
        Gets the first_name attribute of this HierarchyUser instance.

        :return: The value of the first_name attribute of this
        HierarchyUser instance.
        :rtype: six.text_type
        """

        return self._first_name

    @first_name.setter
    def first_name(self, first_name):
        """
        Sets the first_name attribute of this HierarchyUser instance.

        :param first_name: The first_name value to set for the
        first_name attribute of this HierarchyUser instance.
        :type: six.text_type
        """

        self._first_name = first_name

    @property
    def last_name(self):
        """
        Gets the last_name attribute of this HierarchyUser instance.

        :return: The value of the last_name attribute of this
        HierarchyUser instance.
        :rtype: six.text_type
        """

        return self._last_name

    @last_name.setter
    def last_name(self, last_name):
        """
        Sets the last_name attribute of this HierarchyUser instance.

        :param last_name: The last_name value to set for the last_name
        attribute of this HierarchyUser instance.
        :type: six.text_type
        """

        self._last_name = last_name

    @property
    def phone(self):
        """
        Gets the phone attribute of this HierarchyUser instance.

        :return: The value of the phone attribute of this HierarchyUser
        instance.
        :rtype: six.text_type
        """

        return self._phone

    @phone.setter
    def phone(self, phone):
        """
        Sets the phone attribute of this HierarchyUser instance.

        :param phone: The phone value to set for the phone attribute of
        this HierarchyUser instance.
        :type: six.text_type
        """

        self._phone = phone

    @property
    def last_login(self):
        """
        Gets the last_login attribute of this HierarchyUser instance.

        :return: The value of the last_login attribute of this
        HierarchyUser instance.
        :rtype: six.text_type
        """

        return self._last_login

    @property
    def active(self):
        """
        Gets the active attribute of this HierarchyUser instance.

        :return: The value of the active attribute of this HierarchyUser
        instance.
        :rtype: bool
        """

        return self._active

    @active.setter
    def active(self, active):
        """
        Sets the active attribute of this HierarchyUser instance.

        :param active: The active value to set for the active attribute
        of this HierarchyUser instance.
        :type: bool
        """

        self._active = active

    @property
    def email_alerts(self):
        """
        Gets the email_alerts attribute of this HierarchyUser instance.

        :return: The value of the email_alerts attribute of this
        HierarchyUser instance.
        :rtype: bool
        """

        return self._email_alerts

    @email_alerts.setter
    def email_alerts(self, email_alerts):
        """
        Sets the email_alerts attribute of this HierarchyUser instance.

        :param email_alerts: The email_alerts value to set for the
        email_alerts attribute of this HierarchyUser instance.
        :type: bool
        """

        self._email_alerts = email_alerts class Selection(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/Selection.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = [
        '_selection_type',
        '_selection_match',
        '_include_runtime',
        '_include_extended_runtime',
        '_include_electricity',
        '_include_settings',
        '_include_location',
        '_include_program',
        '_include_events',
        '_include_device',
        '_include_technician',
        '_include_utility',
        '_include_management',
        '_include_alerts',
        '_include_reminders',
        '_include_weather',
        '_include_house_details',
        '_include_oem_cfg',
        '_include_equipment_status',
        '_include_notification_settings',
        '_include_privacy',
        '_include_version',
        '_include_security_settings',
        '_include_sensors',
        '_include_audio',
        '_include_energy',
    ]

    attribute_name_map = {
        'selection_type': 'selectionType',
        'selectionType': 'selection_type',
        'selection_match': 'selectionMatch',
        'selectionMatch': 'selection_match',
        'include_runtime': 'includeRuntime',
        'includeRuntime': 'include_runtime',
        'include_extended_runtime': 'includeExtendedRuntime',
        'includeExtendedRuntime': 'include_extended_runtime',
        'include_electricity': 'includeElectricity',
        'includeElectricity': 'include_electricity',
        'include_settings': 'includeSettings',
        'includeSettings': 'include_settings',
        'include_location': 'includeLocation',
        'includeLocation': 'include_location',
        'include_program': 'includeProgram',
        'includeProgram': 'include_program',
        'include_events': 'includeEvents',
        'includeEvents': 'include_events',
        'include_device': 'includeDevice',
        'includeDevice': 'include_device',
        'include_technician': 'includeTechnician',
        'includeTechnician': 'include_technician',
        'include_utility': 'includeUtility',
        'includeUtility': 'include_utility',
        'include_management': 'includeManagement',
        'includeManagement': 'include_management',
        'include_alerts': 'includeAlerts',
        'includeAlerts': 'include_alerts',
        'include_reminders': 'includeReminders',
        'includeReminders': 'include_reminders',
        'include_weather': 'includeWeather',
        'includeWeather': 'include_weather',
        'include_house_details': 'includeHouseDetails',
        'includeHouseDetails': 'include_house_details',
        'include_oem_cfg': 'includeOemCfg',
        'includeOemCfg': 'include_oem_cfg',
        'include_equipment_status': 'includeEquipmentStatus',
        'includeEquipmentStatus': 'include_equipment_status',
        'include_notification_settings': 'includeNotificationSettings',
        'includeNotificationSettings': 'include_notification_settings',
        'include_privacy': 'includePrivacy',
        'includePrivacy': 'include_privacy',
        'include_version': 'includeVersion',
        'includeVersion': 'include_version',
        'include_security_settings': 'includeSecuritySettings',
        'includeSecuritySettings': 'include_security_settings',
        'include_sensors': 'includeSensors',
        'includeSensors': 'include_sensors',
        'include_audio': 'includeAudio',
        'includeAudio': 'include_audio',
        'include_energy': 'includeEnergy',
        'includeEnergy': 'include_energy',
    }

    attribute_type_map = {
        'selection_type': 'six.text_type',
        'selection_match': 'six.text_type',
        'include_runtime': 'boolean',
        'include_extended_runtime': 'boolean',
        'include_electricity': 'boolean',
        'include_settings': 'boolean',
        'include_location': 'boolean',
        'include_program': 'boolean',
        'include_events': 'boolean',
        'include_device': 'boolean',
        'include_technician': 'boolean',
        'include_utility': 'boolean',
        'include_management': 'boolean',
        'include_alerts': 'boolean',
        'include_reminders': 'boolean',
        'include_weather': 'boolean',
        'include_house_details': 'boolean',
        'include_oem_cfg': 'boolean',
        'include_equipment_status': 'boolean',
        'include_notification_settings': 'boolean',
        'include_privacy': 'boolean',
        'include_version': 'boolean',
        'include_security_settings': 'boolean',
        'include_sensors': 'boolean',
        'include_audio': 'boolean',
        'include_energy': 'boolean',
    }

    def __init__(
        self,
        selection_type,
        selection_match,
        include_runtime=None,
        include_extended_runtime=None,
        include_electricity=None,
        include_settings=None,
        include_location=None,
        include_program=None,
        include_events=None,
        include_device=None,
        include_technician=None,
        include_utility=None,
        include_management=None,
        include_alerts=None,
        include_reminders=None,
        include_weather=None,
        include_house_details=None,
        include_oem_cfg=None,
        include_equipment_status=None,
        include_notification_settings=None,
        include_privacy=None,
        include_version=None,
        include_security_settings=None,
        include_sensors=None,
        include_audio=None,
        include_energy=None,
    ):
        """
        Construct a Selection instance
        """
        self._selection_type = selection_type
        self._selection_match = selection_match
        self._include_runtime = include_runtime
        self._include_extended_runtime = include_extended_runtime
        self._include_electricity = include_electricity
        self._include_settings = include_settings
        self._include_location = include_location
        self._include_program = include_program
        self._include_events = include_events
        self._include_device = include_device
        self._include_technician = include_technician
        self._include_utility = include_utility
        self._include_management = include_management
        self._include_alerts = include_alerts
        self._include_reminders = include_reminders
        self._include_weather = include_weather
        self._include_house_details = include_house_details
        self._include_oem_cfg = include_oem_cfg
        self._include_equipment_status = include_equipment_status
        self._include_notification_settings = include_notification_settings
        self._include_privacy = include_privacy
        self._include_version = include_version
        self._include_security_settings = include_security_settings
        self._include_sensors = include_sensors
        self._include_audio = include_audio
        self._include_energy = include_energy

    @property
    def selection_type(self):
        """
        Gets the selection_type attribute of this Selection instance.

        :return: The value of the selection_type attribute of this
        Selection instance.
        :rtype: six.text_type
        """

        return self._selection_type

    @selection_type.setter
    def selection_type(self, selection_type):
        """
        Sets the selection_type attribute of this Selection instance.

        :param selection_type: The selection_type value to set for the
        selection_type attribute of this Selection instance.
        :type: six.text_type
        """

        self._selection_type = selection_type

    @property
    def selection_match(self):
        """
        Gets the selection_match attribute of this Selection instance.

        :return: The value of the selection_match attribute of this
        Selection instance.
        :rtype: six.text_type
        """

        return self._selection_match

    @selection_match.setter
    def selection_match(self, selection_match):
        """
        Sets the selection_match attribute of this Selection instance.

        :param selection_match: The selection_match value to set for the
        selection_match attribute of this Selection instance.
        :type: six.text_type
        """

        self._selection_match = selection_match

    @property
    def include_runtime(self):
        """
        Gets the include_runtime attribute of this Selection instance.

        :return: The value of the include_runtime attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_runtime

    @include_runtime.setter
    def include_runtime(self, include_runtime):
        """
        Sets the include_runtime attribute of this Selection instance.

        :param include_runtime: The include_runtime value to set for the
        include_runtime attribute of this Selection instance.
        :type: boolean
        """

        self._include_runtime = include_runtime

    @property
    def include_extended_runtime(self):
        """
        Gets the include_extended_runtime attribute of this Selection
        instance.

        :return: The value of the include_extended_runtime attribute of
        this Selection instance.
        :rtype: boolean
        """

        return self._include_extended_runtime

    @include_extended_runtime.setter
    def include_extended_runtime(self, include_extended_runtime):
        """
        Sets the include_extended_runtime attribute of this Selection
        instance.

        :param include_extended_runtime: The include_extended_runtime
        value to set for the include_extended_runtime attribute of this
        Selection instance.
        :type: boolean
        """

        self._include_extended_runtime = include_extended_runtime

    @property
    def include_electricity(self):
        """
        Gets the include_electricity attribute of this Selection
        instance.

        :return: The value of the include_electricity attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_electricity

    @include_electricity.setter
    def include_electricity(self, include_electricity):
        """
        Sets the include_electricity attribute of this Selection
        instance.

        :param include_electricity: The include_electricity value to set
        for the include_electricity attribute of this Selection
        instance.
        :type: boolean
        """

        self._include_electricity = include_electricity

    @property
    def include_settings(self):
        """
        Gets the include_settings attribute of this Selection instance.

        :return: The value of the include_settings attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_settings

    @include_settings.setter
    def include_settings(self, include_settings):
        """
        Sets the include_settings attribute of this Selection instance.

        :param include_settings: The include_settings value to set for
        the include_settings attribute of this Selection instance.
        :type: boolean
        """

        self._include_settings = include_settings

    @property
    def include_location(self):
        """
        Gets the include_location attribute of this Selection instance.

        :return: The value of the include_location attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_location

    @include_location.setter
    def include_location(self, include_location):
        """
        Sets the include_location attribute of this Selection instance.

        :param include_location: The include_location value to set for
        the include_location attribute of this Selection instance.
        :type: boolean
        """

        self._include_location = include_location

    @property
    def include_program(self):
        """
        Gets the include_program attribute of this Selection instance.

        :return: The value of the include_program attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_program

    @include_program.setter
    def include_program(self, include_program):
        """
        Sets the include_program attribute of this Selection instance.

        :param include_program: The include_program value to set for the
        include_program attribute of this Selection instance.
        :type: boolean
        """

        self._include_program = include_program

    @property
    def include_events(self):
        """
        Gets the include_events attribute of this Selection instance.

        :return: The value of the include_events attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_events

    @include_events.setter
    def include_events(self, include_events):
        """
        Sets the include_events attribute of this Selection instance.

        :param include_events: The include_events value to set for the
        include_events attribute of this Selection instance.
        :type: boolean
        """

        self._include_events = include_events

    @property
    def include_device(self):
        """
        Gets the include_device attribute of this Selection instance.

        :return: The value of the include_device attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_device

    @include_device.setter
    def include_device(self, include_device):
        """
        Sets the include_device attribute of this Selection instance.

        :param include_device: The include_device value to set for the
        include_device attribute of this Selection instance.
        :type: boolean
        """

        self._include_device = include_device

    @property
    def include_technician(self):
        """
        Gets the include_technician attribute of this Selection
        instance.

        :return: The value of the include_technician attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_technician

    @include_technician.setter
    def include_technician(self, include_technician):
        """
        Sets the include_technician attribute of this Selection
        instance.

        :param include_technician: The include_technician value to set
        for the include_technician attribute of this Selection instance.
        :type: boolean
        """

        self._include_technician = include_technician

    @property
    def include_utility(self):
        """
        Gets the include_utility attribute of this Selection instance.

        :return: The value of the include_utility attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_utility

    @include_utility.setter
    def include_utility(self, include_utility):
        """
        Sets the include_utility attribute of this Selection instance.

        :param include_utility: The include_utility value to set for the
        include_utility attribute of this Selection instance.
        :type: boolean
        """

        self._include_utility = include_utility

    @property
    def include_management(self):
        """
        Gets the include_management attribute of this Selection
        instance.

        :return: The value of the include_management attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_management

    @include_management.setter
    def include_management(self, include_management):
        """
        Sets the include_management attribute of this Selection
        instance.

        :param include_management: The include_management value to set
        for the include_management attribute of this Selection instance.
        :type: boolean
        """

        self._include_management = include_management

    @property
    def include_alerts(self):
        """
        Gets the include_alerts attribute of this Selection instance.

        :return: The value of the include_alerts attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_alerts

    @include_alerts.setter
    def include_alerts(self, include_alerts):
        """
        Sets the include_alerts attribute of this Selection instance.

        :param include_alerts: The include_alerts value to set for the
        include_alerts attribute of this Selection instance.
        :type: boolean
        """

        self._include_alerts = include_alerts

    @property
    def include_reminders(self):
        """
        Gets the include_reminders attribute of this Selection instance.

        :return: The value of the include_reminders attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_reminders

    @include_reminders.setter
    def include_reminders(self, include_reminders):
        """
        Sets the include_reminders attribute of this Selection instance.

        :param include_reminders: The include_reminders value to set for
        the include_reminders attribute of this Selection instance.
        :type: boolean
        """

        self._include_reminders = include_reminders

    @property
    def include_weather(self):
        """
        Gets the include_weather attribute of this Selection instance.

        :return: The value of the include_weather attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_weather

    @include_weather.setter
    def include_weather(self, include_weather):
        """
        Sets the include_weather attribute of this Selection instance.

        :param include_weather: The include_weather value to set for the
        include_weather attribute of this Selection instance.
        :type: boolean
        """

        self._include_weather = include_weather

    @property
    def include_house_details(self):
        """
        Gets the include_house_details attribute of this Selection
        instance.

        :return: The value of the include_house_details attribute of
        this Selection instance.
        :rtype: boolean
        """

        return self._include_house_details

    @include_house_details.setter
    def include_house_details(self, include_house_details):
        """
        Sets the include_house_details attribute of this Selection
        instance.

        :param include_house_details: The include_house_details value to
        set for the include_house_details attribute of this Selection
        instance.
        :type: boolean
        """

        self._include_house_details = include_house_details

    @property
    def include_oem_cfg(self):
        """
        Gets the include_oem_cfg attribute of this Selection instance.

        :return: The value of the include_oem_cfg attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_oem_cfg

    @include_oem_cfg.setter
    def include_oem_cfg(self, include_oem_cfg):
        """
        Sets the include_oem_cfg attribute of this Selection instance.

        :param include_oem_cfg: The include_oem_cfg value to set for the
        include_oem_cfg attribute of this Selection instance.
        :type: boolean
        """

        self._include_oem_cfg = include_oem_cfg

    @property
    def include_equipment_status(self):
        """
        Gets the include_equipment_status attribute of this Selection
        instance.

        :return: The value of the include_equipment_status attribute of
        this Selection instance.
        :rtype: boolean
        """

        return self._include_equipment_status

    @include_equipment_status.setter
    def include_equipment_status(self, include_equipment_status):
        """
        Sets the include_equipment_status attribute of this Selection
        instance.

        :param include_equipment_status: The include_equipment_status
        value to set for the include_equipment_status attribute of this
        Selection instance.
        :type: boolean
        """

        self._include_equipment_status = include_equipment_status

    @property
    def include_notification_settings(self):
        """
        Gets the include_notification_settings attribute of this
        Selection instance.

        :return: The value of the include_notification_settings
        attribute of this Selection instance.
        :rtype: boolean
        """

        return self._include_notification_settings

    @include_notification_settings.setter
    def include_notification_settings(self, include_notification_settings):
        """
        Sets the include_notification_settings attribute of this
        Selection instance.

        :param include_notification_settings: The
        include_notification_settings value to set for the
        include_notification_settings attribute of this Selection
        instance.
        :type: boolean
        """

        self._include_notification_settings = include_notification_settings

    @property
    def include_privacy(self):
        """
        Gets the include_privacy attribute of this Selection instance.

        :return: The value of the include_privacy attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_privacy

    @include_privacy.setter
    def include_privacy(self, include_privacy):
        """
        Sets the include_privacy attribute of this Selection instance.

        :param include_privacy: The include_privacy value to set for the
        include_privacy attribute of this Selection instance.
        :type: boolean
        """

        self._include_privacy = include_privacy

    @property
    def include_version(self):
        """
        Gets the include_version attribute of this Selection instance.

        :return: The value of the include_version attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_version

    @include_version.setter
    def include_version(self, include_version):
        """
        Sets the include_version attribute of this Selection instance.

        :param include_version: The include_version value to set for the
        include_version attribute of this Selection instance.
        :type: boolean
        """

        self._include_version = include_version

    @property
    def include_security_settings(self):
        """
        Gets the include_security_settings attribute of this Selection
        instance.

        :return: The value of the include_security_settings attribute of
        this Selection instance.
        :rtype: boolean
        """

        return self._include_security_settings

    @include_security_settings.setter
    def include_security_settings(self, include_security_settings):
        """
        Sets the include_security_settings attribute of this Selection
        instance.

        :param include_security_settings: The include_security_settings
        value to set for the include_security_settings attribute of this
        Selection instance.
        :type: boolean
        """

        self._include_security_settings = include_security_settings

    @property
    def include_sensors(self):
        """
        Gets the include_sensors attribute of this Selection instance.

        :return: The value of the include_sensors attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_sensors

    @include_sensors.setter
    def include_sensors(self, include_sensors):
        """
        Sets the include_sensors attribute of this Selection instance.

        :param include_sensors: The include_sensors value to set for the
        include_sensors attribute of this Selection instance.
        :type: boolean
        """

        self._include_sensors = include_sensors

    @property
    def include_audio(self):
        """
        Gets the include_audio attribute of this Selection instance.

        :return: The value of the include_audio attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_audio

    @include_audio.setter
    def include_audio(self, include_audio):
        """
        Sets the include_audio attribute of this Selection instance.

        :param include_audio: The include_audio value to set for the
        include_audio attribute of this Selection instance.
        :type: boolean
        """

        self._include_audio = include_audio

    @property
    def include_energy(self):
        """
        Gets the include_energy attribute of this Selection instance.

        :return: The value of the include_energy attribute of this
        Selection instance.
        :rtype: boolean
        """

        return self._include_energy

    @include_energy.setter
    def include_energy(self, include_energy):
        """
        Sets the include_energy attribute of this Selection instance.

        :param include_energy: The include_energy value to set for the
        include_energy attribute of this Selection instance.
        :type: boolean
        """

        self._include_energy = include_energy class Thermostat(EcobeeObject):
    """
    This class has been auto generated by scraping
    https://www.ecobee.com/home/developer/api/documentation/v1/objects/Thermostat.shtml

    Attribute names have been generated by converting ecobee property
    names from camelCase to snake_case.

    A getter property has been generated for each attribute.
    A setter property has been generated for each attribute whose value
    of READONLY is "no".

    An __init__ argument without a default value has been generated if
    the value of REQUIRED is "yes".
    An __init__ argument with a default value of None has been generated
    if the value of REQUIRED is "no".
    """

    __slots__ = [
        '_identifier',
        '_name',
        '_thermostat_rev',
        '_is_registered',
        '_model_number',
        '_brand',
        '_features',
        '_last_modified',
        '_thermostat_time',
        '_utc_time',
        '_audio',
        '_alerts',
        '_reminders',
        '_settings',
        '_runtime',
        '_extended_runtime',
        '_electricity',
        '_devices',
        '_location',
        '_energy',
        '_technician',
        '_utility',
        '_management',
        '_weather',
        '_events',
        '_program',
        '_house_details',
        '_oem_cfg',
        '_equipment_status',
        '_notification_settings',
        '_privacy',
        '_version',
        '_security_settings',
        '_filter_subscription',
        '_remote_sensors',
    ]

    attribute_name_map = {
        'identifier': 'identifier',
        'name': 'name',
        'thermostat_rev': 'thermostatRev',
        'thermostatRev': 'thermostat_rev',
        'is_registered': 'isRegistered',
        'isRegistered': 'is_registered',
        'model_number': 'modelNumber',
        'modelNumber': 'model_number',
        'brand': 'brand',
        'features': 'features',
        'last_modified': 'lastModified',
        'lastModified': 'last_modified',
        'thermostat_time': 'thermostatTime',
        'thermostatTime': 'thermostat_time',
        'utc_time': 'utcTime',
        'utcTime': 'utc_time',
        'audio': 'audio',
        'alerts': 'alerts',
        'reminders': 'reminders',
        'settings': 'settings',
        'runtime': 'runtime',
        'extended_runtime': 'extendedRuntime',
        'extendedRuntime': 'extended_runtime',
        'electricity': 'electricity',
        'devices': 'devices',
        'location': 'location',
        'energy': 'energy',
        'technician': 'technician',
        'utility': 'utility',
        'management': 'management',
        'weather': 'weather',
        'events': 'events',
        'program': 'program',
        'house_details': 'houseDetails',
        'houseDetails': 'house_details',
        'oem_cfg': 'oemCfg',
        'oemCfg': 'oem_cfg',
        'equipment_status': 'equipmentStatus',
        'equipmentStatus': 'equipment_status',
        'notification_settings': 'notificationSettings',
        'notificationSettings': 'notification_settings',
        'privacy': 'privacy',
        'version': 'version',
        'security_settings': 'securitySettings',
        'securitySettings': 'security_settings',
        'filter_subscription': 'filterSubscription',
        'filterSubscription': 'filter_subscription',
        'remote_sensors': 'remoteSensors',
        'remoteSensors': 'remote_sensors',
    }

    attribute_type_map = {
        'identifier': 'six.text_type',
        'name': 'six.text_type',
        'thermostat_rev': 'six.text_type',
        'is_registered': 'bool',
        'model_number': 'six.text_type',
        'brand': 'six.text_type',
        'features': 'six.text_type',
        'last_modified': 'six.text_type',
        'thermostat_time': 'six.text_type',
        'utc_time': 'six.text_type',
        'audio': 'Audio',
        'alerts': 'List[Alert]',
        'reminders': 'List[ThermostatReminder2]',
        'settings': 'Settings',
        'runtime': 'Runtime',
        'extended_runtime': 'ExtendedRuntime',
        'electricity': 'Electricity',
        'devices': 'List[Device]',
        'location': 'Location',
        'energy': 'Energy',
        'technician': 'Technician',
        'utility': 'Utility',
        'management': 'Management',
        'weather': 'Weather',
        'events': 'List[Event]',
        'program': 'Program',
        'house_details': 'HouseDetails',
        'oem_cfg': 'ThermostatOemCfg',
        'equipment_status': 'six.text_type',
        'notification_settings': 'NotificationSettings',
        'privacy': 'ThermostatPrivacy',
        'version': 'Version',
        'security_settings': 'SecuritySettings',
        'filter_subscription': 'ApiFilterSubscription',
        'remote_sensors': 'List[RemoteSensor]',
    }

    def __init__(
        self,
        identifier,
        name=None,
        thermostat_rev=None,
        is_registered=None,
        model_number=None,
        brand=None,
        features=None,
        last_modified=None,
        thermostat_time=None,
        utc_time=None,
        audio=None,
        alerts=None,
        reminders=None,
        settings=None,
        runtime=None,
        extended_runtime=None,
        electricity=None,
        devices=None,
        location=None,
        energy=None,
        technician=None,
        utility=None,
        management=None,
        weather=None,
        events=None,
        program=None,
        house_details=None,
        oem_cfg=None,
        equipment_status=None,
        notification_settings=None,
        privacy=None,
        version=None,
        security_settings=None,
        filter_subscription=None,
        remote_sensors=None,
    ):
        """
        Construct a Thermostat instance
        """
        self._identifier = identifier
        self._name = name
        self._thermostat_rev = thermostat_rev
        self._is_registered = is_registered
        self._model_number = model_number
        self._brand = brand
        self._features = features
        self._last_modified = last_modified
        self._thermostat_time = thermostat_time
        self._utc_time = utc_time
        self._audio = audio
        self._alerts = alerts
        self._reminders = reminders
        self._settings = settings
        self._runtime = runtime
        self._extended_runtime = extended_runtime
        self._electricity = electricity
        self._devices = devices
        self._location = location
        self._energy = energy
        self._technician = technician
        self._utility = utility
        self._management = management
        self._weather = weather
        self._events = events
        self._program = program
        self._house_details = house_details
        self._oem_cfg = oem_cfg
        self._equipment_status = equipment_status
        self._notification_settings = notification_settings
        self._privacy = privacy
        self._version = version
        self._security_settings = security_settings
        self._filter_subscription = filter_subscription
        self._remote_sensors = remote_sensors

    @property
    def identifier(self):
        """
        Gets the identifier attribute of this Thermostat instance.

        :return: The value of the identifier attribute of this
        Thermostat instance.
        :rtype: six.text_type
        """

        return self._identifier

    @property
    def name(self):
        """
        Gets the name attribute of this Thermostat instance.

        :return: The value of the name attribute of this Thermostat
        instance.
        :rtype: six.text_type
        """

        return self._name

    @name.setter
    def name(self, name):
        """
        Sets the name attribute of this Thermostat instance.

        :param name: The name value to set for the name attribute of
        this Thermostat instance.
        :type: six.text_type
        """

        self._name = name

    @property
    def thermostat_rev(self):
        """
        Gets the thermostat_rev attribute of this Thermostat instance.

        :return: The value of the thermostat_rev attribute of this
        Thermostat instance.
        :rtype: six.text_type
        """

        return self._thermostat_rev

    @property
    def is_registered(self):
        """
        Gets the is_registered attribute of this Thermostat instance.

        :return: The value of the is_registered attribute of this
        Thermostat instance.
        :rtype: bool
        """

        return self._is_registered

    @property
    def model_number(self):
        """
        Gets the model_number attribute of this Thermostat instance.

        :return: The value of the model_number attribute of this
        Thermostat instance.
        :rtype: six.text_type
        """

        return self._model_number

    @property
    def brand(self):
        """
        Gets the brand attribute of this Thermostat instance.

        :return: The value of the brand attribute of this Thermostat
        instance.
        :rtype: six.text_type
        """

        return self._brand

    @property
    def features(self):
        """
        Gets the features attribute of this Thermostat instance.

        :return: The value of the features attribute of this Thermostat
        instance.
        :rtype: six.text_type
        """

        return self._features

    @property
    def last_modified(self):
        """
        Gets the last_modified attribute of this Thermostat instance.

        :return: The value of the last_modified attribute of this
        Thermostat instance.
        :rtype: six.text_type
        """

        return self._last_modified

    @property
    def thermostat_time(self):
        """
        Gets the thermostat_time attribute of this Thermostat instance.

        :return: The value of the thermostat_time attribute of this
        Thermostat instance.
        :rtype: six.text_type
        """

        return self._thermostat_time

    @property
    def utc_time(self):
        """
        Gets the utc_time attribute of this Thermostat instance.

        :return: The value of the utc_time attribute of this Thermostat
        instance.
        :rtype: six.text_type
        """

        return self._utc_time

    @property
    def audio(self):
        """
        Gets the audio attribute of this Thermostat instance.

        :return: The value of the audio attribute of this Thermostat
        instance.
        :rtype: Audio
        """

        return self._audio

    @audio.setter
    def audio(self, audio):
        """
        Sets the audio attribute of this Thermostat instance.

        :param audio: The audio value to set for the audio attribute of
        this Thermostat instance.
        :type: Audio
        """

        self._audio = audio

    @property
    def alerts(self):
        """
        Gets the alerts attribute of this Thermostat instance.

        :return: The value of the alerts attribute of this Thermostat
        instance.
        :rtype: List[Alert]
        """

        return self._alerts

    @property
    def reminders(self):
        """
        Gets the reminders attribute of this Thermostat instance.

        :return: The value of the reminders attribute of this Thermostat
        instance.
        :rtype: List[ThermostatReminder2]
        """

        return self._reminders

    @property
    def settings(self):
        """
        Gets the settings attribute of this Thermostat instance.

        :return: The value of the settings attribute of this Thermostat
        instance.
        :rtype: Settings
        """

        return self._settings

    @settings.setter
    def settings(self, settings):
        """
        Sets the settings attribute of this Thermostat instance.

        :param settings: The settings value to set for the settings
        attribute of this Thermostat instance.
        :type: Settings
        """

        self._settings = settings

    @property
    def runtime(self):
        """
        Gets the runtime attribute of this Thermostat instance.

        :return: The value of the runtime attribute of this Thermostat
        instance.
        :rtype: Runtime
        """

        return self._runtime

    @property
    def extended_runtime(self):
        """
        Gets the extended_runtime attribute of this Thermostat instance.

        :return: The value of the extended_runtime attribute of this
        Thermostat instance.
        :rtype: ExtendedRuntime
        """

        return self._extended_runtime

    @property
    def electricity(self):
        """
        Gets the electricity attribute of this Thermostat instance.

        :return: The value of the electricity attribute of this
        Thermostat instance.
        :rtype: Electricity
        """

        return self._electricity

    @property
    def devices(self):
        """
        Gets the devices attribute of this Thermostat instance.

        :return: The value of the devices attribute of this Thermostat
        instance.
        :rtype: List[Device]
        """

        return self._devices

    @property
    def location(self):
        """
        Gets the location attribute of this Thermostat instance.

        :return: The value of the location attribute of this Thermostat
        instance.
        :rtype: Location
        """

        return self._location

    @location.setter
    def location(self, location):
        """
        Sets the location attribute of this Thermostat instance.

        :param location: The location value to set for the location
        attribute of this Thermostat instance.
        :type: Location
        """

        self._location = location

    @property
    def energy(self):
        """
        Gets the energy attribute of this Thermostat instance.

        :return: The value of the energy attribute of this Thermostat
        instance.
        :rtype: Energy
        """

        return self._energy

    @energy.setter
    def energy(self, energy):
        """
        Sets the energy attribute of this Thermostat instance.

        :param energy: The energy value to set for the energy attribute
        of this Thermostat instance.
        :type: Energy
        """

        self._energy = energy

    @property
    def technician(self):
        """
        Gets the technician attribute of this Thermostat instance.

        :return: The value of the technician attribute of this
        Thermostat instance.
        :rtype: Technician
        """

        return self._technician

    @property
    def utility(self):
        """
        Gets the utility attribute of this Thermostat instance.

        :return: The value of the utility attribute of this Thermostat
        instance.
        :rtype: Utility
        """

        return self._utility

    @property
    def management(self):
        """
        Gets the management attribute of this Thermostat instance.

        :return: The value of the management attribute of this
        Thermostat instance.
        :rtype: Management
        """

        return self._management

    @property
    def weather(self):
        """
        Gets the weather attribute of this Thermostat instance.

        :return: The value of the weather attribute of this Thermostat
        instance.
        :rtype: Weather
        """

        return self._weather

    @property
    def events(self):
        """
        Gets the events attribute of this Thermostat instance.

        :return: The value of the events attribute of this Thermostat
        instance.
        :rtype: List[Event]
        """

        return self._events

    @property
    def program(self):
        """
        Gets the program attribute of this Thermostat instance.

        :return: The value of the program attribute of this Thermostat
        instance.
        :rtype: Program
        """

        return self._program

    @program.setter
    def program(self, program):
        """
        Sets the program attribute of this Thermostat instance.

        :param program: The program value to set for the program
        attribute of this Thermostat instance.
        :type: Program
        """

        self._program = program

    @property
    def house_details(self):
        """
        Gets the house_details attribute of this Thermostat instance.

        :return: The value of the house_details attribute of this
        Thermostat instance.
        :rtype: HouseDetails
        """

        return self._house_details

    @house_details.setter
    def house_details(self, house_details):
        """
        Sets the house_details attribute of this Thermostat instance.

        :param house_details: The house_details value to set for the
        house_details attribute of this Thermostat instance.
        :type: HouseDetails
        """

        self._house_details = house_details

    @property
    def oem_cfg(self):
        """
        Gets the oem_cfg attribute of this Thermostat instance.

        :return: The value of the oem_cfg attribute of this Thermostat
        instance.
        :rtype: ThermostatOemCfg
        """

        return self._oem_cfg

    @oem_cfg.setter
    def oem_cfg(self, oem_cfg):
        """
        Sets the oem_cfg attribute of this Thermostat instance.

        :param oem_cfg: The oem_cfg value to set for the oem_cfg
        attribute of this Thermostat instance.
        :type: ThermostatOemCfg
        """

        self._oem_cfg = oem_cfg

    @property
    def equipment_status(self):
        """
        Gets the equipment_status attribute of this Thermostat instance.

        :return: The value of the equipment_status attribute of this
        Thermostat instance.
        :rtype: six.text_type
        """

        return self._equipment_status

    @property
    def notification_settings(self):
        """
        Gets the notification_settings attribute of this Thermostat
        instance.

        :return: The value of the notification_settings attribute of
        this Thermostat instance.
        :rtype: NotificationSettings
        """

        return self._notification_settings

    @notification_settings.setter
    def notification_settings(self, notification_settings):
        """
        Sets the notification_settings attribute of this Thermostat
        instance.

        :param notification_settings: The notification_settings value to
        set for the notification_settings attribute of this Thermostat
        instance.
        :type: NotificationSettings
        """

        self._notification_settings = notification_settings

    @property
    def privacy(self):
        """
        Gets the privacy attribute of this Thermostat instance.

        :return: The value of the privacy attribute of this Thermostat
        instance.
        :rtype: ThermostatPrivacy
        """

        return self._privacy

    @privacy.setter
    def privacy(self, privacy):
        """
        Sets the privacy attribute of this Thermostat instance.

        :param privacy: The privacy value to set for the privacy
        attribute of this Thermostat instance.
        :type: ThermostatPrivacy
        """

        self._privacy = privacy

    @property
    def version(self):
        """
        Gets the version attribute of this Thermostat instance.

        :return: The value of the version attribute of this Thermostat
        instance.
        :rtype: Version
        """

        return self._version

    @property
    def security_settings(self):
        """
        Gets the security_settings attribute of this Thermostat
        instance.

        :return: The value of the security_settings attribute of this
        Thermostat instance.
        :rtype: SecuritySettings
        """

        return self._security_settings

    @security_settings.setter
    def security_settings(self, security_settings):
        """
        Sets the security_settings attribute of this Thermostat
        instance.

        :param security_settings: The security_settings value to set for
        the security_settings attribute of this Thermostat instance.
        :type: SecuritySettings
        """

        self._security_settings = security_settings

    @property
    def filter_subscription(self):
        """
        Gets the filter_subscription attribute of this Thermostat
        instance.

        :return: The value of the filter_subscription attribute of this
        Thermostat instance.
        :rtype: ApiFilterSubscription
        """

        return self._filter_subscription

    @filter_subscription.setter
    def filter_subscription(self, filter_subscription):
        """
        Sets the filter_subscription attribute of this Thermostat
        instance.

        :param filter_subscription: The filter_subscription value to set
        for the filter_subscription attribute of this Thermostat
        instance.
        :type: ApiFilterSubscription
        """

        self._filter_subscription = filter_subscription

    @property
    def remote_sensors(self):
        """
        Gets the remote_sensors attribute of this Thermostat instance.

        :return: The value of the remote_sensors attribute of this
        Thermostat instance.
        :rtype: List[RemoteSensor]
        """

        return self._remote_sensors class EcobeeAuthorizeResponse(EcobeeObject):
    __slots__ = ['_ecobee_pin', '_code', '_scope', '_expires_in', '_interval']

    attribute_name_map = {
        'ecobee_pin': 'ecobeePin',
        'ecobeePin': 'ecobee_pin',
        'code': 'code',
        'scope': 'scope',
        'expires_in': 'expires_in',
        'interval': 'interval',
    }

    attribute_type_map = {
        'ecobee_pin': 'six.text_type',
        'code': 'six.text_type',
        'scope': 'six.text_type',
        'expires_in': 'int',
        'interval': 'int',
    }

    def __init__(self, ecobee_pin, code, scope, expires_in, interval):
        """
        Construct an EcobeeAuthorizeResponse instance

        :param ecobee_pin: The PIN a user enters in the web portal
        :param code: The authorization token needed to request the
        access and refresh tokens
        :param scope: The requested Scope from the original request
        :param expires_in: The number of minutes until the PIN expires
        :param interval: The minimum amount of seconds which must pass
        between polling attempts for a token
        """
        self._ecobee_pin = ecobee_pin
        self._code = code
        self._scope = scope
        self._expires_in = expires_in
        self._interval = interval

    @property
    def ecobee_pin(self):
        """
        Gets the ecobee_pin attribute of this EcobeeAuthorizeResponse
        instance.

        :return: The value of the ecobee_pin attribute of this
        EcobeeAuthorizeResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._ecobee_pin

    @property
    def code(self):
        """
        Gets the code attribute of this EcobeeAuthorizeResponse
        instance.

        :return: The value of the code attribute of this
        EcobeeAuthorizeResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._code

    @property
    def scope(self):
        """
        Gets the scope attribute of this EcobeeAuthorizeResponse
        instance.

        :return: The value of the scope attribute of this
        EcobeeAuthorizeResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._scope

    @property
    def expires_in(self):
        """
        Gets the expires_in attribute of this EcobeeAuthorizeResponse
        instance.

        :return: The value of the expires_in attribute of this
        EcobeeAuthorizeResponse instance.
        :rtype: int
        """
        return self._expires_in

    @property
    def interval(self):
        """
        Gets the interval attribute of this EcobeeAuthorizeResponse
        instance.

        :return: The value of the interval attribute of this
        EcobeeAuthorizeResponse instance.
        :rtype: int
        """
        return self._interval class EcobeeCreateRuntimeReportJobResponse(EcobeeStatusResponse):
    __slots__ = ['_job_id', '_job_status']

    attribute_name_map = {
        'job_id': 'jobId',
        'jobId': 'job_id',
        'job_status': 'jobStatus',
        'jobStatus': 'job_status',
        'status': 'status',
    }

    attribute_type_map = {
        'job_id': 'six.text_type',
        'job_status': 'six.text_type',
        'status': 'Status',
    }

    def __init__(self, job_id, job_status, status):
        """
        Construct a EcobeeCreateRuntimeReportJobResponse instance

        :param job_id: The generated id for the created runtime report
        job
        :param job_status: The status of the created runtime report
        job
        :param status: The api response code
        """
        self._job_id = job_id
        self._job_status = job_status
        EcobeeStatusResponse.__init__(self, status)

    @property
    def job_id(self):
        """
        Gets the job_id attribute of this
        EcobeeCreateRuntimeReportJobResponse instance.

        :return: The value of the job_id attribute of this
        EcobeeCreateRuntimeReportJobResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._job_id

    @property
    def job_status(self):
        """
        Gets the job_status attribute of this
        EcobeeCreateRuntimeReportJobResponse instance.

        :return: The value of the job_status attribute of this
        EcobeeCreateRuntimeReportJobResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._job_status class EcobeeGroupsResponse(EcobeeStatusResponse):
    __slots__ = ['_groups']

    attribute_name_map = {'groups': 'groups', 'status': 'status'}

    attribute_type_map = {'groups': 'List[Group]', 'status': 'Status'}

    def __init__(self, groups, status):
        """
        Construct a EcobeeGroupsResponse instance

        :param groups: The list of Groups returned by the request
        :param status: The api response code
        """
        self._groups = groups
        EcobeeStatusResponse.__init__(self, status)

    @property
    def groups(self):
        """
        Gets the groups attribute of this EcobeeGroupsResponse instance.

        :return: The value of the groups attribute of this
        EcobeeGroupsResponse instance.
        :rtype: List[Group]
        """
        return self._groups class EcobeeIssueDemandResponsesResponse(EcobeeStatusResponse):
    __slots__ = ['_demand_response_ref']

    attribute_name_map = {
        'demand_response_ref': 'demandResponseRef',
        'demandResponseRef': 'demand_response_ref',
        'status': 'status',
    }

    attribute_type_map = {'demand_response_ref': 'six.text_type', 'status': 'Status'}

    def __init__(self, demand_response_ref, status):
        """
        Construct a EcobeeIssueDemandResponsesResponse instance

        :param demand_response_ref: The unique demand response reference
        ID
        :param status: The api response code
        """
        self._demand_response_ref = demand_response_ref
        EcobeeStatusResponse.__init__(self, status)

    @property
    def demand_response_ref(self):
        """
        Gets the demand_response_ref attribute of this
        EcobeeIssueDemandResponsesResponse instance.

        :return: The value of the demand_response_ref attribute of this
        EcobeeIssueDemandResponsesResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._demand_response_ref class EcobeeListDemandResponsesResponse(EcobeeStatusResponse):
    __slots__ = ['_demand_response_list']

    attribute_name_map = {
        'demand_response_list': 'drList',
        'drList': 'demand_response_list',
        'status': 'status',
    }

    attribute_type_map = {
        'demand_response_list': 'List[DemandResponse]',
        'status': 'Status',
    }

    def __init__(self, demand_response_list, status):
        """
        Construct a EcobeeListDemandResponsesResponse instance

        :param demand_response_list: The list of demand responses which
        have not yet expired
        :param status: The api response code
        """
        self._demand_response_list = demand_response_list
        EcobeeStatusResponse.__init__(self, status)

    @property
    def demand_response_list(self):
        """
        Gets the demand_response_list attribute of this
        EcobeeListDemandResponsesResponse instance.

        :return: The value of the demand_response_list attribute of this
        EcobeeListDemandResponsesResponse instance.
        :rtype: List[DemandResponse]
        """
        return self._demand_response_list class EcobeeListHierarchySetsResponse(EcobeeStatusResponse):
    __slots__ = ['_sets']

    attribute_name_map = {'sets': 'sets', 'status': 'status'}

    attribute_type_map = {'sets': 'List[HierarchySet]', 'status': 'Status'}

    def __init__(self, sets, status):
        """
        Construct a EcobeeListHierarchySetsResponse instance

        :param sets: The list of hierarchy management sets
        :param status: The api response code
        """
        self._sets = sets
        EcobeeStatusResponse.__init__(self, status)

    @property
    def sets(self):
        """
        Gets the sets attribute of this EcobeeListHierarchySetsResponse
        instance.

        :return: The value of the sets attribute of this
        EcobeeListHierarchySetsResponse instance.
        :rtype: List[HierarchySet]
        """
        return self._sets class EcobeeListHierarchyUsersResponse(EcobeeStatusResponse):
    __slots__ = ['_users', '_privileges']

    attribute_name_map = {
        'users': 'users',
        'privileges': 'privileges',
        'status': 'status',
    }

    attribute_type_map = {
        'users': 'List[HierarchyUser]',
        'privileges': 'List[HierarchyPrivilege]',
        'status': 'Status',
    }

    def __init__(self, users, status, privileges=None):
        """
        Construct a EcobeeListHierarchyUsersResponse instance

        :param users: The list of users in the company
        :param privileges: List of hierarchy privileges if requested
        :param status: The api response code
        """
        self._users = users
        self._privileges = privileges
        EcobeeStatusResponse.__init__(self, status)

    @property
    def users(self):
        """
        Gets the users attribute of this
        EcobeeListHierarchyUsersResponse instance.

        :return: The value of the users attribute of this
        EcobeeListHierarchyUsersResponse instance.
        :rtype: List[HierarchyUser]
        """
        return self._users

    @property
    def privileges(self):
        """
        Gets the privileges attribute of this
        EcobeeListHierarchyUsersResponse instance.

        :return: The value of the privileges attribute of this
        EcobeeListHierarchyUsersResponse instance.
        :rtype: List[HierarchyPrivilege]
        """
        return self._privileges class EcobeeListRuntimeReportJobStatusResponse(EcobeeStatusResponse):
    __slots__ = ['_jobs']

    attribute_name_map = {'jobs': 'jobs', 'status': 'status'}

    attribute_type_map = {'jobs': 'List[ReportJob]', 'status': 'Status'}

    def __init__(self, jobs, status):
        """
        Construct a EcobeeListRuntimeReportJobStatusResponse instance

        :param jobs: The list of report jobs for the corresponding
        request
        :param status: The api response code
        """
        self._jobs = jobs
        EcobeeStatusResponse.__init__(self, status)

    @property
    def jobs(self):
        """
        Gets the jobs attribute of this
        EcobeeListRuntimeReportJobStatusResponse instance.

        :return: The value of the jobs attribute of this
        EcobeeListRuntimeReportJobStatusResponse instance.
        :rtype: List[ReportJob]
        """
        return self._jobs class EcobeeMeterReportsResponse(EcobeeStatusResponse):
    __slots__ = ['_report_list']

    attribute_name_map = {
        'report_list': 'reportList',
        'reportList': 'report_list',
        'status': 'status',
    }

    attribute_type_map = {'report_list': 'List[MeterReport]', 'status': 'Status'}

    def __init__(self, report_list, status):
        """
        Construct a EcobeeMeterReportsResponse instance

        :param report_list: A list of thermostat meter reports
        :param status: The api response code
        """
        self._report_list = report_list
        EcobeeStatusResponse.__init__(self, status)

    @property
    def report_list(self):
        """
        Gets the report_list attribute of this
        EcobeeMeterReportsResponse instance.

        :return: The value of the report_list attribute of this
        EcobeeMeterReportsResponse instance.
        :rtype: List[MeterReport]
        """
        return self._report_list class EcobeeRuntimeReportsResponse(EcobeeStatusResponse):
    __slots__ = [
        '_start_date',
        '_start_interval',
        '_end_date',
        '_end_interval',
        '_columns',
        '_report_list',
        '_sensor_list',
    ]

    attribute_name_map = {
        'start_date': 'startDate',
        'startDate': 'start_date',
        'start_interval': 'startInterval',
        'startInterval': 'start_interval',
        'end_date': 'endDate',
        'endDate': 'end_date',
        'end_interval': 'endInterval',
        'endInterval': 'end_interval',
        'columns': 'columns',
        'report_list': 'reportList',
        'reportList': 'report_list',
        'sensor_list': 'sensorList',
        'sensorList': 'sensor_list',
        'status': 'status',
    }

    attribute_type_map = {
        'start_date': 'six.text_type',
        'start_interval': 'int',
        'end_date': 'six.text_type',
        'end_interval': 'int',
        'columns': 'six.text_type',
        'report_list': 'List[RuntimeReport]',
        'sensor_list': 'List[RuntimeSensorReport]',
        'status': 'Status',
    }

    def __init__(
        self,
        start_date,
        start_interval,
        end_date,
        end_interval,
        columns,
        report_list,
        sensor_list,
        status,
    ):
        """
        Construct a EcobeeRuntimeReportsResponse instance

        :param start_date: The report UTC start date
        :param start_interval: The report start interval
        :param end_date: The report UTC end date
        :param end_interval: The report end interval
        :param columns: The CSV list of column names from the request
        :param report_list: A list of runtime reports
        :param sensor_list: A list of runtime sensor reports
        :param status: The api response code
        """
        self._start_date = start_date
        self._start_interval = start_interval
        self._end_date = end_date
        self._end_interval = end_interval
        self._columns = columns
        self._report_list = report_list
        self._sensor_list = sensor_list
        EcobeeStatusResponse.__init__(self, status)

    @property
    def start_date(self):
        """
        Gets the start_date attribute of this
        EcobeeRuntimeReportsResponse instance.

        :return: The value of the start_date attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._start_date

    @property
    def start_interval(self):
        """
        Gets the start_interval attribute of this
        EcobeeRuntimeReportsResponse instance.

        :return: The value of the start_interval attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: int
        """
        return self._start_interval

    @property
    def end_date(self):
        """
        Gets the end_date attribute of this EcobeeRuntimeReportsResponse
        instance.

        :return: The value of the end_date attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._end_date

    @property
    def end_interval(self):
        """
        Gets the end_interval attribute of this
        EcobeeRuntimeReportsResponse instance.

        :return: The value of the end_interval attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: int
        """
        return self._end_interval

    @property
    def columns(self):
        """
        Gets the columns attribute of this EcobeeRuntimeReportsResponse
        instance.

        :return: The value of the columns attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._columns

    @property
    def report_list(self):
        """
        Gets the report_list attribute of this
        EcobeeRuntimeReportsResponse instance.

        :return: The value of the report_list attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: List[RuntimeReport]
        """
        return self._report_list

    @property
    def sensor_list(self):
        """
        Gets the report_list attribute of this
        EcobeeRuntimeReportsResponse instance.

        :return: The value of the report_list attribute of this
        EcobeeRuntimeReportsResponse instance.
        :rtype: List[RuntimeSensorReport]
        """
        return self._sensor_list class EcobeeStatusResponse(EcobeeObject):
    __slots__ = ['_status']

    attribute_name_map = {'status': 'status'}

    attribute_type_map = {'status': 'Status'}

    def __init__(self, status):
        """
        Construct a EcobeeStatusResponse instance

        :param status: The api response code
        """
        self._status = status

    @property
    def status(self):
        """
        Gets the status attribute of this EcobeeStatusResponse instance.

        :return: The value of the status attribute of this
        EcobeeStatusResponse instance.
        :rtype: Status
        """
        return self._status class EcobeeThermostatResponse(EcobeeStatusResponse):
    __slots__ = ['_page', '_thermostat_list']

    attribute_name_map = {
        'page': 'page',
        'thermostat_list': 'thermostatList',
        'thermostatList': 'thermostat_list',
        'status': 'status',
    }

    attribute_type_map = {
        'page': 'Page',
        'thermostat_list': 'List[Thermostat]',
        'status': 'Status',
    }

    def __init__(self, page, thermostat_list, status):
        """
        Construct a EcobeeThermostatResponse instance

        :param page: The page information for the response
        :param thermostat_list: The list of thermostats returned by the
        request
        :param status: The api response code
        """
        self._page = page
        self._thermostat_list = thermostat_list
        EcobeeStatusResponse.__init__(self, status)

    @property
    def page(self):
        """
        Gets the page attribute of this EcobeeThermostatResponse
        instance.

        :return: The value of the page attribute of this
        EcobeeThermostatResponse instance.
        :rtype: Page
        """
        return self._page

    @property
    def thermostat_list(self):
        """
        Gets the thermostat_list attribute of this
        EcobeeThermostatResponse instance.

        :return: The value of the thermostat_list attribute of this
        EcobeeThermostatResponse instance.
        :rtype: List[Thermostat]
        """
        return self._thermostat_list class EcobeeThermostatsSummaryResponse(EcobeeStatusResponse):
    __slots__ = ['_revision_list', '_thermostat_count', '_status_list']

    attribute_name_map = {
        'revision_list': 'revisionList',
        'revisionList': 'revision_list',
        'thermostat_count': 'thermostatCount',
        'thermostatCount': 'thermostat_count',
        'status_list': 'statusList',
        'statusList': 'status_list',
        'status': 'status',
    }

    attribute_type_map = {
        'revision_list': 'List[six.text_type]',
        'thermostat_count': 'int',
        'status_list': 'List[six.text_type]',
        'status': 'Status',
    }

    def __init__(self, revision_list, thermostat_count, status_list, status):
        """
        Construct a EcobeeThermostatsSummaryResponse instance

        :param revision_list: The list of CSV revision values
        :param thermostat_count: Number of thermostats listed in the
        Revision List
        :param status_list: The list of CSV status values
        :param status: The api response code
        """
        self._revision_list = revision_list
        self._thermostat_count = thermostat_count
        self._status_list = status_list
        EcobeeStatusResponse.__init__(self, status)

    @property
    def revision_list(self):
        """
        Gets the revision_list attribute of this
        EcobeeThermostatsSummaryResponse instance.

        :return: The value of the revision_list attribute of this
        EcobeeThermostatsSummaryResponse instance.
        :rtype: List[six.text_type] (This is List[unicode()] in Python 2
        and List[str] in Python 3)
        """
        return self._revision_list

    @property
    def thermostat_count(self):
        """
        Gets the thermostat_count attribute of this
        EcobeeThermostatsSummaryResponse instance.

        :return: The value of the thermostat_count attribute of this
        EcobeeThermostatsSummaryResponse instance.
        :rtype: int
        """
        return self._thermostat_count

    @property
    def status_list(self):
        """
        Gets the status_list attribute of this
        EcobeeThermostatsSummaryResponse instance.

        :return: The value of the status_list attribute of this
        EcobeeThermostatsSummaryResponse instance.
        :rtype: List[six.text_type] (This is List[unicode()] in Python 2
        and List[str] in Python 3)
        """
        return self._status_list class EcobeeTokensResponse(EcobeeObject):
    __slots__ = [
        '_access_token',
        '_token_type',
        '_expires_in',
        '_refresh_token',
        '_scope',
    ]

    attribute_name_map = {
        'access_token': 'access_token',
        'token_type': 'token_type',
        'expires_in': 'expires_in',
        'refresh_token': 'refresh_token',
        'scope': 'scope',
    }

    attribute_type_map = {
        'access_token': 'six.text_type',
        'token_type': 'six.text_type',
        'expires_in': 'int',
        'refresh_token': 'six.text_type',
        'scope': 'six.text_type',
    }

    def __init__(self, access_token, token_type, expires_in, refresh_token, scope):
        """
        Construct a EcobeeTokensResponse instance

        :param access_token: The token to be used to encapsulate the
        authorization scope and credentials
        :param token_type: Type of token
        :param expires_in: The number of minutes until the PIN expires
        :param refresh_token: The token to be used to refresh an expired
        access_token
        :param scope: The requested Scope from the original request
        """
        self._access_token = access_token
        self._token_type = token_type
        self._expires_in = expires_in
        self._refresh_token = refresh_token
        self._scope = scope

    @property
    def access_token(self):
        """
        Gets the access_token attribute of this EcobeeTokensResponse
        instance.

        :return: The value of the access_token attribute of this
        EcobeeTokensResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._access_token

    @property
    def token_type(self):
        """
        Gets the token_type attribute of this EcobeeTokensResponse
        instance.

        :return: The value of the token_type attribute of this
        EcobeeTokensResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._token_type

    @property
    def expires_in(self):
        """
        Gets the expires_in attribute of this EcobeeTokensResponse
        instance.

        :return: The value of the expires_in attribute of this
        EcobeeTokensResponse instance.
        :rtype: int
        """
        return self._expires_in

    @property
    def refresh_token(self):
        """
        Gets the refresh_token attribute of this EcobeeTokensResponse
        instance.

        :return: The value of the refresh_token attribute of this
        EcobeeTokensResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._refresh_token

    @property
    def scope(self):
        """
        Gets the scope attribute of this EcobeeTokensResponse instance.

        :return: The value of the scope attribute of this
        EcobeeTokensResponse instance.
        :rtype: six.text_type (This is unicode() in Python 2 and str in
        Python 3)
        """
        return self._scope class Utilities(object):
    __slots__ = []

    _class_name_map = {'tou': 'TimeOfUse'}

    @classmethod
    def dictionary_to_object(
        cls,
        data,
        property_type,
        response_properties,
        parent_classes=[],
        indent=0,
        is_top_level=False,
    ):
        if isinstance(data, dict):
            for (i, key) in enumerate(data):
                if isinstance(data[key], dict):  # Object
                    # Append class of object to parent_classes
                    if len(parent_classes) > 1:
                        try:
                            parent_classes.append(
                                getattr(
                                    sys.modules[__name__],
                                    '{0}{1}'.format(key[:1].upper(), key[1:]),
                                )
                            )
                        except AttributeError:
                            parent_classes.append(
                                getattr(
                                    sys.modules[__name__],
                                    '{0}'.format(cls._class_name_map[key]),
                                )
                            )

                        # Nested object (i.e. This object is passed as
                        # an argument to its parent constructor
                        # (__init__) and must be passed as a keyword
                        # argument)
                        #
                        # This object is parent_classes[-1]
                        #
                        # This object's parent is parent_classes[-2]
                        generated_code = '{0}{1}={2}(\n'.format(
                            ' ' * indent,
                            parent_classes[-2].attribute_name_map[key],
                            parent_classes[-1].__name__,
                        )
                        response_properties[parent_classes[0]].append(generated_code)
                    else:
                        # Top level object
                        parent_classes = [key]
                        parent_classes.append(
                            getattr(
                                sys.modules[__name__],
                                '{0}{1}'.format(key[:1].upper(), key[1:]),
                            )
                        )

                        response_properties[parent_classes[0]] = []
                        generated_code = '{0}{1}(\n'.format(
                            ' ' * indent, parent_classes[-1].__name__
                        )
                        response_properties[parent_classes[0]].append(generated_code)

                    cls.dictionary_to_object(
                        data[key],
                        property_type,
                        response_properties,
                        parent_classes,
                        indent + 4,
                    )

                    generated_code = '{0})'.format(' ' * indent)
                    response_properties[parent_classes[0]].append(generated_code)

                    # The parent object's constructor will have a
                    # trailing ',' if its last argument is an object
                    generated_code = ',\n' if len(parent_classes) > 2 else '\n'
                    response_properties[parent_classes[0]].append(generated_code)

                    parent_classes.pop()
                elif isinstance(data[key], list):  # List
                    if len(parent_classes) > 1:
                        # Nested list (i.e. This list is passed as an
                        # argument to its parent constructor (__init__)
                        # and must be passed as a keyword argument)
                        generated_code = '{0}{1}=[\n'.format(
                            ' ' * indent, parent_classes[-1].attribute_name_map[key]
                        )
                        response_properties[parent_classes[0]].append(generated_code)
                    else:
                        # Top level list
                        parent_classes = [key]
                        response_properties[parent_classes[0]] = []

                        generated_code = '{0}[\n'.format(' ' * indent)
                        response_properties[parent_classes[0]].append(generated_code)

                    for (j, list_entry) in enumerate(data[key]):
                        parent_class_appended = False

                        if len(parent_classes) > 1:
                            # Get type of nested attribute (user defined
                            # object, list of user defined objects, or
                            # built-in data type)
                            class_name = parent_classes[-1].attribute_type_map[
                                parent_classes[-1].attribute_name_map[key]
                            ]

                            if class_name.find('List') != -1:
                                try:
                                    # Append class of user defined
                                    # object within list to
                                    # parent_classes (e.g. if attribute
                                    # type is List[Device], then append
                                    # Device to parent_classes
                                    parent_classes.append(
                                        getattr(sys.modules[__name__], class_name[5:-1])
                                    )
                                    parent_class_appended = True
                                except AttributeError:
                                    # No need to do any special handling
                                    # of built-in data types lists (e.g.
                                    # if attribute type is List[str],
                                    # the literal value is used
                                    pass
                        else:
                            # Top level list. Map the parent class from
                            # the property_type dictionary
                            parent_classes.append(property_type[key])
                            parent_class_appended = True

                        if parent_class_appended:
                            # De-serialize list of user defined objects
                            generated_code = '{0}{1}(\n'.format(
                                ' ' * (indent + 4), parent_classes[-1].__name__
                            )
                            response_properties[parent_classes[0]].append(
                                generated_code
                            )

                            cls.dictionary_to_object(
                                list_entry,
                                property_type,
                                response_properties,
                                parent_classes,
                                indent + 8,
                            )

                            parent_classes.pop()

                            generated_code = '{0})'.format(' ' * (indent + 4))
                            response_properties[parent_classes[0]].append(
                                generated_code
                            )
                        else:
                            # De-serialize user defined object or
                            # built-in data type
                            cls.dictionary_to_object(
                                list_entry,
                                property_type,
                                response_properties,
                                parent_classes,
                                indent + 4,
                            )

                        generated_code = ',\n' if j != len(data[key]) - 1 else '\n'
                        response_properties[parent_classes[0]].append(generated_code)

                    generated_code = '{0}]'.format(' ' * indent)
                    response_properties[parent_classes[0]].append(generated_code)

                    generated_code = ',\n' if i != len(data) - 1 else '\n'
                    response_properties[parent_classes[0]].append(generated_code)
                else:  # Object attributes
                    generated_code = ' ' * indent
                    response_properties[parent_classes[0]].append(generated_code)

                    if parent_classes:
                        try:
                            argument_name = parent_classes[-1].attribute_name_map[key]
                            if (
                                argument_name
                                in list(zip(*inspect.getmembers(builtins)))[0]
                                or argument_name in keyword.kwlist
                            ):
                                argument_name = '{0}_'.format(argument_name)

                            generated_code = '{0}={1!r}'.format(
                                argument_name, data[key]
                            )
                            response_properties[parent_classes[0]].append(
                                generated_code
                            )
                        except KeyError:
                            logger.error(
                                'Missing attribute in class %s\n'
                                'Attribute name  => %s\n'
                                'Attribute value => %s\n\n'
                                'Please open a new issue here '
                                '(https://github.com/sfanous/Pyecobee/issues/new)',
                                parent_classes[-1].__name__,
                                key,
                                data[key],
                            )

                            continue
                    else:
                        generated_code = '{0}={1!r}'.format(key, data[key])
                        response_properties[parent_classes[0]].append(generated_code)

                    generated_code = ',\n' if i != len(data) - 1 else '\n'
                    response_properties[parent_classes[0]].append(generated_code)
        elif isinstance(data, list):
            generated_code = '{0}[\n'.format(' ' * indent)
            response_properties[parent_classes[0]].append(generated_code)

            for (i, list_entry) in enumerate(data):
                if i:
                    generated_code = ',\n'
                    response_properties[parent_classes[0]].append(generated_code)

                cls.dictionary_to_object(
                    list_entry,
                    property_type,
                    response_properties,
                    parent_classes,
                    indent + 4,
                )

            generated_code = '\n{0}]'.format(' ' * indent)
            response_properties[parent_classes[0]].append(generated_code)
        else:  # Built-in data type
            if isinstance(data, bool):
                generated_code = '{0}bool({1!r})'.format(' ' * indent, format(data))
            elif isinstance(data, int):
                generated_code = '{0}int({1!r})'.format(' ' * indent, format(data))
            else:
                generated_code = '{0}{1!r}'.format(' ' * indent, format(data))

            response_properties[parent_classes[0]].append(generated_code)

        if is_top_level:
            return eval(''.join(response_properties[parent_classes[0]]))

        return None

    @classmethod
    def make_http_request(
        cls, requests_http_method, url, headers=None, params=None, json_=None, timeout=5
    ):
        try:
            logger.debug(
                'Request\n'
                '[Method]\n'
                '========\n%s\n\n'
                '[URL]\n'
                '=====\n%s\n'
                '%s%s%s'.strip(),
                requests_http_method.__name__.upper(),
                url,
                '\n'
                '[Query Parameters]\n'
                '==================\n{0}\n'.format(
                    '\n'.join(
                        [
                            '{0:32} => {1!s}'.format(key, params[key])
                            for key in sorted(params)
                        ]
                    )
                )
                if params is not None
                else '',
                '\n'
                '[Headers]\n'
                '=========\n{0}\n'.format(
                    '\n'.join(
                        [
                            '{0:32} => {1!s}'.format(header, headers[header])
                            for header in sorted(headers)
                        ]
                    )
                )
                if headers is not None
                else '',
                '\n'
                '[JSON]\n'
                '======\n{0}\n'.format(json.dumps(json_, sort_keys=True, indent=2))
                if json_ is not None
                else '',
            )

            return requests_http_method(
                url, headers=headers, params=params, json=json_, timeout=timeout
            )
        except requests.exceptions.RequestException:
            (type_, value_, traceback_) = sys.exc_info()
            logger.error(
                '\n'.join(traceback.format_exception(type_, value_, traceback_))
            )

            six.reraise(EcobeeRequestsException, value_, traceback_)

    @classmethod
    def object_to_dictionary(cls, object_, class_):
        dictionary = {object_.__class__.__name__: {}}

        for attribute_name in object_.slots():
            attribute_value = getattr(object_, attribute_name)

            if attribute_value is not None:
                if isinstance(attribute_value, list):
                    dictionary[object_.__class__.__name__][
                        class_.attribute_name_map[attribute_name[1:]]
                    ] = []

                    for entry in attribute_value:
                        if hasattr(entry, '__slots__'):
                            dictionary[object_.__class__.__name__][
                                class_.attribute_name_map[attribute_name[1:]]
                            ].append(cls.object_to_dictionary(entry, type(entry)))
                        else:
                            dictionary[object_.__class__.__name__][
                                class_.attribute_name_map[attribute_name[1:]]
                            ].append(entry)
                else:
                    try:
                        getattr(sys.modules[__name__], type(attribute_value).__name__)

                        dictionary[object_.__class__.__name__][
                            class_.attribute_name_map[attribute_name[1:]]
                        ] = cls.object_to_dictionary(
                            attribute_value, type(attribute_value)
                        )
                    except AttributeError:
                        dictionary[object_.__class__.__name__][
                            class_.attribute_name_map[attribute_name[1:]]
                        ] = attribute_value

        return dictionary[object_.__class__.__name__]

    @classmethod
    def process_http_response(cls, response, response_class):
        if response.status_code == requests.codes.ok:
            response_object = cls.dictionary_to_object(
                {response_class.__name__: response.json()},
                {response_class.__name__: response_class},
                {response_class.__name__: None},
                is_top_level=True,
            )

            logger.debug(
                'EcobeeResponse:\n'
                '[JSON]\n'
                '======\n'
                '%s\n'
                '\n'
                '[Object]\n'
                '========\n'
                '%s'.strip(),
                json.dumps(response.json(), sort_keys=True, indent=2),
                response_object.pretty_format(),
            )

            return response_object

        try:
            if 'error' in response.json():
                error_response = cls.dictionary_to_object(
                    {'EcobeeErrorResponse': response.json()},
                    {'EcobeeErrorResponse': EcobeeErrorResponse},
                    {'EcobeeErrorResponse': None},
                    is_top_level=True,
                )

                raise EcobeeAuthorizationException(
                    'ecobee authorization error encountered for URL => {0}\n'
                    'HTTP error code => {1}\n'
                    'Error type => {2}\n'
                    'Error description => {3}\n'
                    'Error URI => {4}'.format(
                        response.request.url,
                        response.status_code,
                        error_response.error,
                        error_response.error_description,
                        error_response.error_uri,
                    ),
                    error_response.error,
                    error_response.error_description,
                    error_response.error_uri,
                )

            if 'status' in response.json():
                status = cls.dictionary_to_object(
                    {'Status': response.json()['status']},
                    {'Status': Status},
                    {'Status': None},
                    is_top_level=True,
                )

                raise EcobeeApiException(
                    'ecobee API error encountered for URL => {0}\n'
                    'HTTP error code => {1}\n'
                    'Status code => {2}\n'
                    'Status message => {3}'.format(
                        response.request.url,
                        response.status_code,
                        status.code,
                        status.message,
                    ),
                    status.code,
                    status.message,
                )

            raise EcobeeHttpException(
                'HTTP error encountered for URL => {0}\n'
                'HTTP error code => {1}'.format(
                    response.request.url, response.status_code
                )
            )
        except EcobeeException as ecobee_exception:
            logger.exception(
                '%s raised:\n', type(ecobee_exception).__name__, exc_info=True
            )

            raise
import json
import logging
import numbers
import pytz
import requests
import six
from datetime import date
from datetime import datetime
from datetime import timedelta
from pyecobee.ecobee_object import EcobeeObject
from pyecobee.enumerations import AckType
from pyecobee.enumerations import FanMode
from pyecobee.enumerations import HoldType
from pyecobee.enumerations import PlugState
from pyecobee.enumerations import Scope
from pyecobee.enumerations import SelectionType
from pyecobee.objects.demand_management import DemandManagement
from pyecobee.objects.demand_response import DemandResponse
from pyecobee.objects.function import Function
from pyecobee.objects.group import Group
from pyecobee.objects.hierarchy_privilege import HierarchyPrivilege
from pyecobee.objects.hierarchy_user import HierarchyUser
from pyecobee.objects.selection import Selection
from pyecobee.objects.thermostat import Thermostat
from pyecobee.responses import EcobeeAuthorizeResponse
from pyecobee.responses import EcobeeCreateRuntimeReportJobResponse
from pyecobee.responses import EcobeeGroupsResponse
from pyecobee.responses import EcobeeIssueDemandResponsesResponse
from pyecobee.responses import EcobeeListDemandResponsesResponse
from pyecobee.responses import EcobeeListHierarchySetsResponse
from pyecobee.responses import EcobeeListHierarchyUsersResponse
from pyecobee.responses import EcobeeListRuntimeReportJobStatusResponse
from pyecobee.responses import EcobeeMeterReportsResponse
from pyecobee.responses import EcobeeRuntimeReportsResponse
from pyecobee.responses import EcobeeStatusResponse
from pyecobee.responses import EcobeeThermostatResponse
from pyecobee.responses import EcobeeThermostatsSummaryResponse
from pyecobee.responses import EcobeeTokensResponse
from pyecobee.utilities import Utilities
                'than 31 days'
            )
        if not isinstance(columns, six.string_types):
            raise TypeError(
                'columns must be an instance of {0}'.format(six.string_types)
            )
        if not isinstance(include_sensors, bool):
            raise TypeError('include_sensors must be an instance of {0}'.format(bool))

        utc = pytz.utc
        start_date_time = start_date_time.astimezone(utc)
        end_date_time = end_date_time.astimezone(utc)

        dictionary = {
            'selection': Utilities.object_to_dictionary(selection, type(selection)),
            'startDate': '{0}-{1:02}-{2:02}'.format(
                start_date_time.year, start_date_time.month, start_date_time.day
            ),
            'startInterval': (start_date_time.hour * 12)
            + (start_date_time.minute // 5),
            'endDate': '{0}-{1:02}-{2:02}'.format(
                end_date_time.year, end_date_time.month, end_date_time.day
            ),
            'endInterval': end_date_time.hour * 12 + (end_date_time.minute // 5),
            'columns': columns,
            'includeSensors': include_sensors,
        }

        response = Utilities.make_http_request(
            requests.get,
            EcobeeService.RUNTIME_REPORT_URL,
            headers={
                'Authorization': 'Bearer {0}'.format(self._access_token),
                'Content-Type': 'application/json;charset=UTF-8',
            },
            params={
                'format': 'json',
                'body': json.dumps(dictionary, sort_keys=True, indent=2),
            },
            timeout=timeout,
        )

        return Utilities.process_http_response(response, EcobeeRuntimeReportsResponse)

    def request_groups(self, selection, timeout=5):
        """
        The request_groups method retrieves the Group and grouping data
        for the Thermostats registered to the particular User. The User
        here refers to the calling application's user authorization.

        :param selection: The selection criteria for the request. Must
        have selection_type = 'registered'.
        :param timeout: Number of seconds requests will wait to
        establish a connection and to receive a response
        :return: A GroupResponse object
        :rtype: EcobeeGroupsResponse
        :raises EcobeeApiException: If the request results in an ecobee
        API error response
        :raises EcobeeRequestsException: If an exception is raised by
        the underlying requests module
        :raises TypeError: If selection is not an instance of Selection
        :raises ValueError: If selection.selection_type is not
        "registered"
        """
        if not isinstance(selection, Selection):
            raise TypeError('selection must be an instance of {0}'.format(Selection))
        if selection.selection_type != SelectionType.REGISTERED.value:
            raise ValueError(
                'selection.selection_type must be set to {0}'.format(
                    SelectionType.REGISTERED.value
                )
            )

        dictionary = {
            'selection': Utilities.object_to_dictionary(selection, type(selection))
        }

        response = Utilities.make_http_request(
            requests.get,
            EcobeeService.GROUP_URL,
            headers={
                'Authorization': 'Bearer {0}'.format(self._access_token),
                'Content-Type': 'application/json;charset=UTF-8',
            },
            params={
                'format': 'json',
                'body': json.dumps(dictionary, sort_keys=True, indent=2),
            },
            timeout=timeout,
        )

        return Utilities.process_http_response(response, EcobeeGroupsResponse)

    def update_groups(self, selection, groups, timeout=5):
        """
        The update_groups method permits the modification of any
        writable Group object properties.

        :param selection: The selection criteria for the request
        :param groups: The list of Groups to update
        :param timeout: Number of seconds requests will wait to
        establish a connection and to receive a response
        :return: A GroupResponse object
        :rtype: EcobeeGroupsResponse
        :raises EcobeeApiException: If the request results in an ecobee
        API error response
        :raises EcobeeRequestsException: If an exception is raised by
        the underlying requests module
        :raises TypeError: If selection is not an instance of Selection,
        groups is not a list, or any member of groups is not an instance
        of Group
        """
        if not isinstance(selection, Selection):
            raise TypeError('selection must be an instance of {0}'.format(Selection))
        if not isinstance(groups, list):
            raise TypeError('groups must be an instance of {0}'.format(list))
        for group in groups:
            if not isinstance(group, Group):
                raise TypeError(
                    'All members of groups must be a an instance of '

                    '{0}'.format(Group)