Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion homeassistant/components/switch/broadlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
'rm2_pro_plus_bl', 'rm_mini_shate']
SP1_TYPES = ['sp1']
SP2_TYPES = ['sp2', 'honeywell_sp2', 'sp3', 'spmini2', 'spminiplus']
MP1_TYPES = ['mp1-1', 'mp1-2', 'mp1-3', 'mp1-4']

SWITCH_TYPES = RM_TYPES + SP1_TYPES + SP2_TYPES
SWITCH_TYPES = RM_TYPES + SP1_TYPES + SP2_TYPES + MP1_TYPES

SWITCH_SCHEMA = vol.Schema({
vol.Optional(CONF_COMMAND_OFF, default=None): cv.string,
Expand Down Expand Up @@ -136,6 +137,16 @@ def _send_packet(call):
elif switch_type in SP2_TYPES:
broadlink_device = broadlink.sp2((ip_addr, 80), mac_addr)
switches = [BroadlinkSP2Switch(friendly_name, broadlink_device)]
elif switch_type in MP1_TYPES:
broadlink_device = broadlink.mp1((ip_addr, 80), mac_addr)
if switch_type == "mp1-1":
switches = [BroadlinkMP1Switch(friendly_name, broadlink_device, 1)]
if switch_type == "mp1-2":
switches = [BroadlinkMP1Switch(friendly_name, broadlink_device, 2)]
if switch_type == "mp1-3":
switches = [BroadlinkMP1Switch(friendly_name, broadlink_device, 3)]
if switch_type == "mp1-4":
switches = [BroadlinkMP1Switch(friendly_name, broadlink_device, 4)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not all mp1 switches have 4 slots?
Then I think we always should add all 4 slots.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup. I updated the code to add all 4 slots and changed device type to mp1 only. New config should be like this

- platform: broadlink
  host: 192.168.0.x
  mac: xx:xx:xx:xx:xx:xx
  type: mp1
  friendly_name: 'MP 1'
  slots:
    # friendly name of slots - optional
    # if not set, slot name will be switch's friendly_name + 'slot {slot_index}'. e.g 'MP 1 slot 1'
    slot_1: 'TV slot'
    slot_2: 'Xbox slot'
    slot_3: 'Fan slot'
    slot_4: 'Speaker slot'


broadlink_device.timeout = config.get(CONF_TIMEOUT)
try:
Expand Down Expand Up @@ -268,3 +279,56 @@ def _update(self, retry=2):
if state is None and retry > 0:
return self._update(retry-1)
self._state = state


class BroadlinkMP1Switch(BroadlinkRMSwitch):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add new BroadlinkMP1Switch class to control 4 slots

"""Representation of an Broadlink switch."""

def __init__(self, friendly_name, device, slot):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slot param is used to define slot to control

"""Initialize the switch."""
super().__init__(friendly_name, device, None, None)
self._command_on = 1
self._command_off = 0
self._slot = slot

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line contains whitespace

@property
def assumed_state(self):
"""Return true if unable to access real state of entity."""
return False

def _sendpacket(self, packet, retry=2):
"""Send packet to device."""
try:
self._device.set_power(self._slot, packet)
except (socket.timeout, ValueError) as error:
if retry < 1:
_LOGGER.error(error)
return False
if not self._auth():
return False
return self._sendpacket(packet, max(0, retry-1))
return True

@property
def should_poll(self):
"""Polling needed."""
return True

def update(self):
"""Synchronize state with switch."""
self._update()

def _update(self, retry=2):
try:
states = self._device.check_power()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we here will ask for the same data 4 times (once for each slot).
You should make a data object that you can pass to the init function instead of the device object. The data object should handle the check_power call.
Here is an example: https://github.com/home-assistant/home-assistant/blob/38071501b421627dadbceb4bbdced195ac4ec620/homeassistant/components/switch/digitalloggers.py#L137

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

state = states['s' + str(self._slot)]
except (socket.timeout, ValueError) as error:
if retry < 1:
_LOGGER.error(error)
return
if not self._auth():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try to get this kind of logic added to the broadlink lib that is being used? It would be more suitable to be added there.

@giangvo giangvo Sep 13, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would do it in other PR and let people who know more about broadlink lib do it. I am not familiar with it :(

return
return self._update(max(0, retry-1))
if state is None and retry > 0:
return self._update(max(0, retry-1))
self._state = state