Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e9f593c
Fixing surround programs in RX-V481
fr3nd Dec 9, 2018
5f2692b
Added support for SERVER source playback
spahlimi Jan 4, 2019
7ef9d95
Remove trailing whitespace
spahlimi Jan 13, 2019
9c3025d
Search for specific menu tag
raffidil Jun 25, 2019
6f8418e
Added new partymode property to get & set Party Mode feature
Dec 22, 2019
80d5e4b
Added new partymode property to get & set Party Mode feature
Dec 22, 2019
9586195
Testing CI
Dec 22, 2019
5742e7a
Merge branch 'add_partymode' of https://github.com/bugmanch/rxv into …
bugmanch Dec 22, 2019
a42ee05
Testing CI again
bugmanch Dec 22, 2019
8051897
Extract serial number from SSDP
postlund Oct 27, 2020
e96d2b9
drop unsupported python versions and fix tox/py.test
wuub Jan 19, 2021
b0a4435
move to setup.cfg only project
wuub Jan 19, 2021
143280e
don't use deprecated way of instantiation RXV(IP) in tests
wuub Jan 19, 2021
c40109c
replace testtools with standard unittest
wuub Jan 19, 2021
2fb1c6b
setup gh actions build
wuub Jan 19, 2021
e9a760e
bring back flake8
wuub Jan 19, 2021
c76b725
improve envlist
wuub Jan 19, 2021
625ea0c
simplify badges for now
wuub Jan 19, 2021
7d4c20c
Merge pull request #70 from wuub/modernize-rxv
wuub Jan 19, 2021
65ba4cd
master -> main
wuub Jan 19, 2021
572be1b
remove travis config
wuub Jan 19, 2021
1058b2c
add manifest checks, clean manifest and remove makefile
wuub Jan 19, 2021
eacd172
Merge pull request #71 from wuub/manifest-cleanup
wuub Jan 19, 2021
7133db9
Merge branch 'main' into master
wuub Jan 19, 2021
74602ba
Merge pull request #55 from fr3nd/master
wuub Jan 19, 2021
0577bae
Merge branch 'main' into patch-1
wuub Jan 19, 2021
f3e0fbc
Merge pull request #60 from raffidil/patch-1
wuub Jan 19, 2021
2313d3a
Merge branch 'main' into serial_number
wuub Jan 19, 2021
b2e64cc
Merge pull request #66 from postlund/serial_number
wuub Jan 19, 2021
a7c35a8
Merge branch 'main' into master
wuub Jan 19, 2021
cef7b1b
Merge pull request #56 from spahlimi/master
wuub Jan 19, 2021
db43e1d
Merge branch 'main' into add_partymode
wuub Jan 19, 2021
1d9d72c
fix whitespace to make flake8 happy
wuub Jan 19, 2021
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
29 changes: 29 additions & 0 deletions .github/workflows/tox.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Tests

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]

steps:
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox tox-gh-actions
- name: Test with tox
run: tox
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include *.rst
include Makefile
recursive-include tests *.py
recursive-include tests *.xml
12 changes: 0 additions & 12 deletions Makefile

This file was deleted.

9 changes: 3 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
rxv
===
.. image:: https://travis-ci.org/wuub/rxv.svg?branch=master
:target: https://travis-ci.org/wuub/rxv
.. image:: https://badge.fury.io/py/rxv.svg
:target: https://badge.fury.io/py/rxv

.. image:: https://landscape.io/github/wuub/rxv/master/landscape.svg?style=flat
:target: https://landscape.io/github/wuub/rxv/master
:alt: Code Health

Automation Library for Yamaha RX-V473, RX-V573, RX-V673, RX-V773 receivers
Automation Library for Yamaha receivers

Installation
============
Expand Down
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[build-system]
requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4"]
build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
write_to = "rxv/version.py"
1 change: 0 additions & 1 deletion requirements.txt

This file was deleted.

1 change: 1 addition & 0 deletions rxv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version.py
10 changes: 1 addition & 9 deletions rxv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,4 @@

def find(timeout=1.5):
"""Find all Yamah receivers on local network using SSDP search."""
return [
RXV(
ctrl_url=ri.ctrl_url,
model_name=ri.model_name,
friendly_name=ri.friendly_name,
unit_desc_url=ri.unit_desc_url
)
for ri in ssdp.discover(timeout=timeout)
]
return [RXV(**ri._asdict()) for ri in ssdp.discover(timeout=timeout)]
59 changes: 56 additions & 3 deletions rxv/rxv.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, play=False, stop=False, pause=False,
YamahaCommand = '<YAMAHA_AV cmd="{command}">{payload}</YAMAHA_AV>'
Zone = '<{zone}>{request_text}</{zone}>'
BasicStatusGet = '<Basic_Status>GetParam</Basic_Status>'
PartyMode = '<System><Party_Mode><Mode>{state}</Mode></Party_Mode></System>'
PowerControl = '<Power_Control><Power>{state}</Power></Power_Control>'
PowerControlSleep = '<Power_Control><Sleep>{sleep_value}</Sleep></Power_Control>'
Input = '<Input><Input_Sel>{input_name}</Input_Sel></Input>'
Expand All @@ -67,6 +68,8 @@ def __init__(self, play=False, stop=False, pause=False,
VolumeMute = '<Volume><Mute>{state}</Mute></Volume>'
SelectNetRadioLine = '<NET_RADIO><List_Control><Direct_Sel>Line_{lineno}'\
'</Direct_Sel></List_Control></NET_RADIO>'
SelectServerLine = '<SERVER><List_Control><Direct_Sel>Line_{lineno}'\
'</Direct_Sel></List_Control></SERVER>'

HdmiOut = '<System><Sound_Video><HDMI><Output><OUT_{port}>{command}</OUT_{port}>'\
'</Output></HDMI></Sound_Video></System>'
Expand All @@ -84,15 +87,16 @@ def __init__(self, play=False, stop=False, pause=False,
class RXV(object):

def __init__(self, ctrl_url, model_name="Unknown",
zone="Main_Zone", friendly_name='Unknown',
unit_desc_url=None):
serial_number=None, zone="Main_Zone",
friendly_name='Unknown', unit_desc_url=None):
if re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}", ctrl_url):
# backward compatibility: accept ip address as a contorl url
warnings.warn("Using IP address as a Control URL is deprecated")
ctrl_url = 'http://%s/YamahaRemoteControl/ctrl' % ctrl_url
self.ctrl_url = ctrl_url
self.unit_desc_url = unit_desc_url or re.sub('ctrl$', 'desc.xml', ctrl_url)
self.model_name = model_name
self.serial_number = serial_number
self.friendly_name = friendly_name
self._inputs_cache = None
self._zones_cache = None
Expand Down Expand Up @@ -330,7 +334,7 @@ def surround_programs(self):
if source_xml is None:
return False

setup = source_xml.find('.//*[@Title_1="Setup"]')
setup = source_xml.find('.//Menu[@Title_1="Setup"]')
if setup is None:
return False

Expand Down Expand Up @@ -590,6 +594,22 @@ def volume_fade(self, final_vol, sleep=0.5):
self.volume = val
time.sleep(sleep)

@property
def partymode(self):
request_text = PartyMode.format(state=GetParam)
response = self._request('GET', request_text, False)
pmode = response.find('System/Party_Mode/Mode').text
assert pmode in ["On", "Off"]
return pmode == "On"

@partymode.setter
def partymode(self, state):
assert state in [True, False]
new_state = "On" if state else "Off"
request_text = PartyMode.format(state=new_state)
response = self._request('PUT', request_text, False)
return response

@property
def mute(self):
request_text = VolumeMute.format(state=GetParam)
Expand Down Expand Up @@ -642,6 +662,39 @@ def net_radio(self, path):
# print("Sleeping because we are not ready yet")
time.sleep(1)

def _direct_sel_server(self, lineno):
request_text = SelectServerLine.format(lineno=lineno)
return self._request('PUT', request_text, zone_cmd=False)

def server(self, path):
"""Play from specified server

This lets you play a SERVER address in a single command
with by encoding it with > as separators. For instance:

Server>Playlists>GoodVibes

This code is copied from the net_radio function.

TODO: better error handling if we some how time out
"""
layers = path.split(">")
self.input = "SERVER"

for attempt in range(20):
menu = self.menu_status()
if menu.ready:
for line, value in menu.current_list.items():
if value == layers[menu.layer - 1]:
lineno = line[5:]
self._direct_sel_server(lineno)
if menu.layer == len(layers):
return
break
else:
# print("Sleeping because we are not ready yet")
time.sleep(1)

@property
def sleep(self):
request_text = PowerControlSleep.format(sleep_value=GetParam)
Expand Down
12 changes: 10 additions & 2 deletions rxv/ssdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,15 @@
"{urn:schemas-upnp-org:device-1-0}device"
"/{urn:schemas-upnp-org:device-1-0}friendlyName"
)
SERIAL_NUMBER_QUERY = (
"{urn:schemas-upnp-org:device-1-0}device"
"/{urn:schemas-upnp-org:device-1-0}serialNumber"
)

RxvDetails = namedtuple("RxvDetails", "ctrl_url unit_desc_url, model_name friendly_name")
RxvDetails = namedtuple(
"RxvDetails",
"ctrl_url unit_desc_url, model_name friendly_name serial_number"
)


def discover(timeout=1.5):
Expand Down Expand Up @@ -85,8 +92,9 @@ def rxv_details(location):
unit_desc_url = urljoin(url_base_el.text, unit_desc_url_local)
model_name = res.find(MODEL_NAME_QUERY).text
friendly_name = res.find(FRIENDLY_NAME_QUERY).text
serial_number = res.find(SERIAL_NUMBER_QUERY).text

return RxvDetails(ctrl_url, unit_desc_url, model_name, friendly_name)
return RxvDetails(ctrl_url, unit_desc_url, model_name, friendly_name, serial_number)


if __name__ == '__main__':
Expand Down
88 changes: 88 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,94 @@
[metadata]
name = rxv
description = Automation Library for Yamaha RX-V473, RX-V573, RX-V673, RX-V773 receivers
long_description = file: README.md
long_description_content_type = text/x-rst
maintainer = Wojciech Bederski
maintainer-email = github@wuub.net
author = Wojciech Bederski
author-email = github@wuub.net
url = https://github.com/wuub/rxv
project_urls =
Source=https://github.com/wuub/rxv
Tracker=https://github.com/wuub/rxv/issues
platforms = any
license = BSD
license_file = LICENSE
classifiers =
Development Status :: 5 - Production/Stable
Framework :: tox
Intended Audience :: Developers
License :: OSI Approved :: BSD License
Operating System :: OS Independent
Topic :: Home Automation,
Topic :: Software Development :: Libraries
Topic :: Utilities
Programming Language :: Python :: 3
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: Implementation :: CPython


[options]
zip_safe = False
include_package_data = True
packages = find:
install_requires =
requests
defusedxml

[options.extras_require]
testing =
black
flake8
mock
pytest
pytest-cov
pytest-timeout
requests-mock

[wheel]
universal = 1

[tox:tox]
minversion = 3.7
isolated_build = true
skip_missing_interpreters = true
envlist =
flake8
manifest
py{37,38,39}

[gh-actions]
python =
3.7: py37
3.8: py38, flake8, manifest
3.9: py39

[coverage:run]
source_pkgs=
rxv

[testenv]
extras = testing
commands = py.test --cov --cov-report=term --cov-report=xml {posargs}

[testenv:flake8]
description = run flake8 under {basepython}
commands = flake8 rxv/ tests/
extras = testing

[testenv:manifest]
basepython = python3.8
deps = check-manifest
skip_install = true
commands = check-manifest

[check-manifest]
ignore =
rxv/version.py

[flake8]
exclude = .cache,.git,.tox,.eggs,build,docs/*,*.egg-info
max-line-length = 100
Expand Down
52 changes: 0 additions & 52 deletions setup.py

This file was deleted.

6 changes: 0 additions & 6 deletions test-requirements.txt

This file was deleted.

Loading