Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to 1.4.0 #267

Merged
merged 21 commits into from
Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f0531e3
Sync dev with master (#246)
alandtse Jul 5, 2019
d1ed479
Sync dev with master (#252)
alandtse Jul 13, 2019
5846371
fix(media_player): remove unused MEDIA_PLAYER_SCHEMA (#261)
alandtse Aug 4, 2019
c560742
fix(media_player): alternative serial numbers not recognized for mobi…
alandtse Aug 4, 2019
2b26a12
Fix TypeError exception for regions without Guard (#245)
alandtse Aug 4, 2019
4cc934c
fix(guard): add 1s delay for guard state check after voice activity (…
alandtse Aug 4, 2019
ff6483e
Add basic switch support (do not disturb, repeat, shuffle)
alandtse Jun 23, 2019
54afcfd
feat(switches): add code to update state changes
alandtse Aug 4, 2019
a10d7e6
fix(guard): increase delay to check state on voice
alandtse Aug 7, 2019
e8ab5d1
fix(guard): schedule HA update after processing voice
alandtse Aug 7, 2019
f213820
chore(guard): obfuscate email in debug message
alandtse Aug 7, 2019
f84d2ba
fix(guard): add additional checks for failed guard access
alandtse Aug 7, 2019
9a388f5
fix(media_player): fix bug where get_last_called called before init
alandtse Aug 7, 2019
c38a753
fix(captcha): add captcha to handle OTP selection page
alandtse Aug 7, 2019
04299d7
style(configurator): update messaging
alandtse Aug 7, 2019
4b552f6
chore(alexapy): update to 0.7.1
alandtse Aug 7, 2019
6b70764
Merge pull request #263 from alandtse/switches
alandtse Aug 7, 2019
d0d7a9b
fix(wshandler): properly handle entryId does not contain #
alandtse Aug 8, 2019
a8479e3
chore(const): bump version
alandtse Aug 8, 2019
241bc1c
fix(switch): add unique_id function
alandtse Aug 8, 2019
021962d
style(switch): clean up whitespace
alandtse Aug 8, 2019
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
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**System details**
- Home-assistant (version):
- Hassio (Yes/No): (Please note you may have to restart hassio 2-3 times to load the latest version of alexapy after an update. This looks like a HA bug).
- alexa_media (version from `const.py` or HA startup):
- alexapy (version from `pip show alexapy` or HA startup):

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
92 changes: 74 additions & 18 deletions custom_components/alexa_media/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,15 @@ def setup_platform_callback(hass, config, login, callback_data):
request_configuration and configuration_callback
"""
_LOGGER.debug(("Status: %s got captcha: %s securitycode: %s"
" Claimsoption: %s VerificationCode: %s"),
" Claimsoption: %s AuthSelectOption: %s "
" VerificationCode: %s"),
login.status,
callback_data.get('captcha'),
callback_data.get('securitycode'),
callback_data.get('claimsoption'),
callback_data.get('authselectoption'),
callback_data.get('verificationcode'))
login.login(captcha=callback_data.get('captcha'),
securitycode=callback_data.get('securitycode'),
claimsoption=callback_data.get('claimsoption'),
verificationcode=callback_data.get('verificationcode'))
login.login(data=callback_data)
test_login_status(hass, config, login,
setup_platform_callback)

Expand All @@ -136,14 +135,24 @@ def configuration_callback(callback_data):
login, callback_data)
status = login.status
email = login.email
# links = ""
footer = ""
if 'error_message' in status and status['error_message']:
footer = ('\n<b>NOTE: Actual Amazon error message in red below. '
'Remember password will be provided automatically'
' and Amazon error message normally appears first!</b>')
# if login.links:
# links = '\n\nGo to link with link# (e.g. link0)\n' + login.links
# Get Captcha
if (status and 'captcha_image_url' in status and
status['captcha_image_url'] is not None):
config_id = configurator.request_config(
"Alexa Media Player - Captcha - {}".format(email),
configuration_callback,
description=('Please enter the text for the captcha.'
' Please enter anything if the image is missing.'
' Please hit confirm to reload image.'
# + links
+ footer
),
description_image=status['captcha_image_url'],
submit_caption="Confirm",
Expand All @@ -154,7 +163,9 @@ def configuration_callback(callback_data):
config_id = configurator.request_config(
"Alexa Media Player - 2FA - {}".format(email),
configuration_callback,
description=('Please enter your Two-Factor Security code.'),
description=('Please enter your Two-Factor Security code.'
# + links
+ footer),
submit_caption="Confirm",
fields=[{'id': 'securitycode', 'name': 'Security Code'}]
)
Expand All @@ -166,20 +177,38 @@ def configuration_callback(callback_data):
"Alexa Media Player - Verification Method - {}".format(email),
configuration_callback,
description=('Please select the verification method. '
'(e.g., sms or email).<br />{}').format(
options
),
'(e.g., sms or email).\n{}'.format(options)
# + links
+ footer),
submit_caption="Confirm",
fields=[{'id': 'claimsoption', 'name': 'Option'}]
)
else:
configuration_callback({})
elif (status and 'authselect_required' in status and
status['authselect_required']): # Get picker method
options = status['authselect_message']
if options:
config_id = configurator.request_config(
"Alexa Media Player - OTP Method - {}".format(email),
configuration_callback,
description=('Please select the OTP method. '
'(e.g., 0, 1).<br />{}'.format(options)
# + links
+ footer),
submit_caption="Confirm",
fields=[{'id': 'authselectoption', 'name': 'Option'}]
)
else:
configuration_callback({})
elif (status and 'verificationcode_required' in status and
status['verificationcode_required']): # Get picker method
config_id = configurator.request_config(
"Alexa Media Player - Verification Code - {}".format(email),
configuration_callback,
description=('Please enter received verification code.'),
description=('Please enter received verification code.'
# + links
+ footer),
submit_caption="Confirm",
fields=[{'id': 'verificationcode', 'name': 'Verification Code'}]
)
Expand Down Expand Up @@ -218,6 +247,9 @@ def test_login_status(hass, config, login,
elif ('claimspicker_required' in login.status and
login.status['claimspicker_required']):
_LOGGER.debug("Creating configurator to select verification option")
elif ('authselect_required' in login.status and
login.status['authselect_required']):
_LOGGER.debug("Creating configurator to select OTA option")
elif ('verificationcode_required' in login.status and
login.status['verificationcode_required']):
_LOGGER.debug("Creating configurator to enter verification code")
Expand Down Expand Up @@ -263,6 +295,7 @@ def update_devices():
devices = AlexaAPI.get_devices(login_obj)
bluetooth = AlexaAPI.get_bluetooth(login_obj)
preferences = AlexaAPI.get_device_preferences(login_obj)
dnd = AlexaAPI.get_dnd_state(login_obj)
_LOGGER.debug("%s: Found %s devices, %s bluetooth",
hide_email(email),
len(devices) if devices is not None else '',
Expand Down Expand Up @@ -320,6 +353,14 @@ def update_devices():
_LOGGER.debug("Locale %s found for %s",
device['locale'],
hide_serial(device['serialNumber']))

for dev in dnd['doNotDisturbDeviceStatusList']:
if dev['deviceSerialNumber'] == device['serialNumber']:
device['dnd'] = dev['enabled']
_LOGGER.debug("DND %s found for %s",
device['dnd'],
hide_serial(device['serialNumber']))

(hass.data[DATA_ALEXAMEDIA]
['accounts']
[email]
Expand Down Expand Up @@ -455,15 +496,21 @@ def ws_handler(message_obj):
serial = None
if command == 'PUSH_ACTIVITY':
# Last_Alexa Updated
serial = (json_payload
['key']
['entryId']).split('#')[2]
last_called = {
'serialNumber': serial,
'timestamp': json_payload['timestamp']
}
if (json_payload
['key']
['entryId']).find('#') != -1:
serial = (json_payload
['key']
['entryId']).split('#')[2]
last_called = {
'serialNumber': serial,
'timestamp': json_payload['timestamp']
}
if (serial and serial in existing_serials):
update_last_called(login_obj, last_called)
hass.bus.fire(('{}_{}'.format(DOMAIN,
hide_email(email)))[0:32],
{'push_activity': json_payload})
elif command == 'PUSH_AUDIO_PLAYER_STATE':
# Player update
serial = (json_payload['dopplerId']['deviceSerialNumber'])
Expand Down Expand Up @@ -500,6 +547,15 @@ def ws_handler(message_obj):
hass.bus.fire(('{}_{}'.format(DOMAIN,
hide_email(email)))[0:32],
{'bluetooth_change': bluetooth_state})
elif command == 'PUSH_MEDIA_QUEUE_CHANGE':
# Player availability update
serial = (json_payload['dopplerId']['deviceSerialNumber'])
if (serial and serial in existing_serials):
_LOGGER.debug("Updating media_player queue %s",
json_payload)
hass.bus.fire(('{}_{}'.format(DOMAIN,
hide_email(email)))[0:32],
{'queue_state': json_payload})
if (serial and serial not in existing_serials
and serial not in (hass.data[DATA_ALEXAMEDIA]
['accounts']
Expand Down
13 changes: 9 additions & 4 deletions custom_components/alexa_media/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from homeassistant.const import (STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.event import call_later

from . import DATA_ALEXAMEDIA
from . import DOMAIN as ALEXA_DOMAIN
Expand All @@ -36,7 +37,7 @@ def setup_platform(hass, config, add_devices_callback,
# type: AlexaAlarmControlPanel
if not (alexa_client and alexa_client.unique_id):
_LOGGER.debug("%s: Skipping creation of uninitialized device: %s",
account,
hide_email(account),
alexa_client)
continue
devices.append(alexa_client)
Expand Down Expand Up @@ -83,14 +84,15 @@ def __init__(self, login, hass):
self._should_poll = False
self._attrs = {}

data = self.alexa_api.get_guard_details(self._login)
try:
from simplejson import JSONDecodeError
data = self.alexa_api.get_guard_details(self._login)
guard_dict = (data['locationDetails']
['locationDetails']['Default_Location']
['amazonBridgeDetails']['amazonBridgeDetails']
['LambdaBridge_AAA/OnGuardSmartHomeBridgeService']
['applianceDetails']['applianceDetails'])
except KeyError:
except (KeyError, TypeError, JSONDecodeError):
guard_dict = {}
for key, value in guard_dict.items():
if value['modelName'] == "REDROCK_GUARD_PANEL":
Expand All @@ -116,7 +118,9 @@ def _handle_event(self, event):

Used instead of polling.
"""
self.refresh()
if 'push_activity' in event.data:
call_later(self.hass, 2, lambda _:
self.refresh(no_throttle=True))

@util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
def refresh(self):
Expand Down Expand Up @@ -152,6 +156,7 @@ def refresh(self):
else:
self._state = STATE_ALARM_DISARMED
_LOGGER.debug("%s: Alarm State: %s", self.account, self.state)
self.schedule_update_ha_state()

def alarm_disarm(self, code=None):
# pylint: disable=unexpected-keyword-arg
Expand Down
5 changes: 3 additions & 2 deletions custom_components/alexa_media/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""
from datetime import timedelta

__version__ = '1.3.1'
__version__ = '1.4.0'
PROJECT_URL = "https://github.com/keatontaylor/alexa_media_player/"
ISSUE_URL = "{}issues".format(PROJECT_URL)

Expand All @@ -24,7 +24,8 @@
ALEXA_COMPONENTS = [
'media_player',
'notify',
'alarm_control_panel'
'alarm_control_panel',
'switch'
]

CONF_ACCOUNTS = 'accounts'
Expand Down
2 changes: 1 addition & 1 deletion custom_components/alexa_media/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"documentation": "https://github.com/keatontaylor/alexa_media_player/wiki",
"dependencies": [],
"codeowners": ["@keatontaylor", "@alandtse"],
"requirements": ["alexapy==0.7.0"]
"requirements": ["alexapy==0.7.1"]
}
Loading