Ejemplo n.º 1
0
    def _handle_push_notification(self, namespace, payload, from_myself=False):
        def fire_switch_state_change(dev, channel_id, o_state, n_state,
                                     f_myself):
            if o_state != n_state:
                evt = DeviceSwitchStatusEvent(dev=dev,
                                              channel_id=channel_id,
                                              switch_state=n_state,
                                              generated_by_myself=f_myself)
                self.fire_event(evt)

        with self._state_lock:
            if namespace == TOGGLE:
                # Update the local state and fire the event only if the state actually changed
                channel_index = 0
                old_switch_state = self._state.get(channel_index)
                switch_state = payload['toggle']['onoff'] == 1
                self._state[channel_index] = switch_state
                fire_switch_state_change(self, channel_index, old_switch_state,
                                         switch_state, from_myself)
                return True

            elif namespace == TOGGLEX:
                if isinstance(payload['togglex'], list):
                    for c in payload['togglex']:
                        # Update the local state and fire the event only if the state actually changed
                        channel_index = c['channel']
                        old_switch_state = self._state.get(channel_index)
                        switch_state = c['onoff'] == 1
                        self._state[channel_index] = switch_state
                        fire_switch_state_change(self, channel_index,
                                                 old_switch_state,
                                                 switch_state, from_myself)
                        return True

                elif isinstance(payload['togglex'], dict):
                    # Update the local state and fire the event only if the state actually changed
                    channel_index = payload['togglex']['channel']
                    old_switch_state = self._state.get(channel_index)
                    switch_state = payload['togglex']['onoff'] == 1
                    self._state[channel_index] = switch_state
                    fire_switch_state_change(self, channel_index,
                                             old_switch_state, switch_state,
                                             from_myself)
                    return True

            elif namespace == REPORT:
                # Ignoring REPORT
                l.info("Report event is currently unhandled.")
                return False

            elif namespace == CONSUMPTIONX:
                # Ignoring
                l.info("ConsumptionX push event is currently ignored")
                return False

            else:
                l.error("Unknown/Unsupported namespace/command: %s" %
                        namespace)
                l.debug("Namespace: %s, Data: %s" % (namespace, payload))
                return False
Ejemplo n.º 2
0
    def _operate_door(self, channel, state, callback,
                      wait_for_sensor_confirmation):
        # If the door is already in the target status, do not execute the command.
        already_in_state = False
        with self._state_lock:
            already_in_state = self.get_status()[channel] == state

        if already_in_state and callback is None:
            l.info("Command was not executed: the door state is already %s" %
                   ("open" if state else "closed"))
            return
        elif already_in_state and callback is not None:
            callback(None, self._door_state[channel])
            return

        payload = {
            "state": {
                "channel": channel,
                "open": state,
                "uuid": self.uuid
            }
        }
        if wait_for_sensor_confirmation:
            door_event = None
            if callback is None:
                door_event = Event()

            def waiter(data):
                self.unregister_event_callback(waiter)
                if data.channel != channel:
                    return
                if callback is None:
                    door_event.set()
                else:
                    if not compare_same_states(data.door_state, state):
                        callback("Operation failed", data.door_state)
                    else:
                        callback(None, data.door_state)

            self.register_event_callback(waiter)
            self.execute_command(command="SET",
                                 namespace=GARAGE_DOOR_STATE,
                                 payload=payload,
                                 callback=None)

            if callback is None:
                door_event.wait()
                current_state = self._door_state[channel]
                if current_state != state:
                    raise Exception("Operation failed.")

        else:
            self.execute_command(command="SET",
                                 namespace=GARAGE_DOOR_STATE,
                                 payload=payload,
                                 callback=callback)