-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
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
Add PlayStation Network Integration #133901
base: dev
Are you sure you want to change the base?
Conversation
Do you get a separate unique id for every playstation? |
Yes and no. I can pull a list of registered devices and they do have a unique deviceId. However, the call to return the user state (What game are they playing, are they online), only returns the device type (PS4, PS5) which is not associated to any particular deviceId. I also question the validity of the registered device data. I've had two PS4s over the years but I only have one entry in the response. I do have entries for my three PS3 systems though. I meant to mention this in the original pull request, and I'll add it there now too, but I'm working with an undocumented and "unofficial" api. The psnawp project reverse engineered it from the android PlayStation Mobile app. The end result is that I'm left to infer some things rather than read it in the docs. |
self.entity_description = MediaPlayerEntityDescription( | ||
key=platform, | ||
translation_key="playstation", | ||
device_class=MediaPlayerDeviceClass.RECEIVER, | ||
name=self.coordinator.user.online_id, | ||
has_entity_name=True, | ||
) | ||
self._attr_unique_id = ( | ||
f"{coordinator.config_entry.unique_id}_{self.entity_description.key}" | ||
) | ||
self._attr_device_info = DeviceInfo( | ||
identifiers={(DOMAIN, self.coordinator.user.account_id)}, | ||
name=self.coordinator.user.online_id, | ||
manufacturer="Sony Interactive Entertainment", | ||
model="PlayStation Network", | ||
) | ||
|
||
@property | ||
def name(self) -> str: | ||
"""Name getter.""" | ||
return PLATFORM_MAP[self.entity_description.key] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.entity_description = MediaPlayerEntityDescription( | |
key=platform, | |
translation_key="playstation", | |
device_class=MediaPlayerDeviceClass.RECEIVER, | |
name=self.coordinator.user.online_id, | |
has_entity_name=True, | |
) | |
self._attr_unique_id = ( | |
f"{coordinator.config_entry.unique_id}_{self.entity_description.key}" | |
) | |
self._attr_device_info = DeviceInfo( | |
identifiers={(DOMAIN, self.coordinator.user.account_id)}, | |
name=self.coordinator.user.online_id, | |
manufacturer="Sony Interactive Entertainment", | |
model="PlayStation Network", | |
) | |
@property | |
def name(self) -> str: | |
"""Name getter.""" | |
return PLATFORM_MAP[self.entity_description.key] | |
self.entity_description = MediaPlayerEntityDescription( | |
key=platform, | |
translation_key="playstation", | |
device_class=MediaPlayerDeviceClass.RECEIVER, | |
name=None, | |
has_entity_name=True, | |
) | |
self._attr_unique_id = ( | |
f"{coordinator.config_entry.unique_id}_{self.entity_description.key}" | |
) | |
self._attr_device_info = DeviceInfo( | |
via_device={(DOMAIN, coordinator.config_entry.unique_id)}, | |
identifiers={(DOMAIN, self._attr_unique_id)}, | |
name=PLATFORM_MAP[self.entity_description.key], | |
manufacturer="Sony Interactive Entertainment", | |
model=PLATFORM_MAP[self.entity_description.key], | |
) | |
IMHO each console type should be represented as individual device, and media player as the main entity, doesn't need a name, it can be set to None. via_device
should added maybe later when more entities are added to the integration, this would link the devices to the psn account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could be missing something, but doesn't this limit the user to adding a single account? When setup this way, each entity is named after only the device (PlayStation X) but what happens when I add my second PSN account? Now I have two devices that would be named the same. This is of course solvable, but it lead me to think it was the wrong approach. The device in this scenario is the user's PSN account, not the physical hardware. I think this makes sense since we are not able to directly talk to the console. We only get details that pertain to it via the playstation network. All the other sensors that the custom integration provides also aren't console dependent but are associated with the user account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Home Assistant would name it media_player.playstation_5_2
, there won't be any conflicts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, but isn't that "wrong"? In the UI, there is no affordance for the user to differentiate them. They are both named "PlayStation 5" and the entity ID only differs with an _2. Which one is associated with my primary account and which one with my alt account?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's quite usual behaviour, many integrations name entities by their device model, sometimes also manufacturer name prepended. Users can rename entities afterwards however they want.
Proposed change
This change adds support for integrating with the PlayStation Network. In this first release (my first HA PR), I have attempted to remove all unneeded code (no entity base class since I only have a single platform) but anticipate adding it, and refactoring elsewhere to follow home assistant conventions in subsequent pull requests. The integration contains a single platform (Media Player), is setup fully via the UI, supplies unique IDs, and attempts to follow all current Home Assistant best practices.
Type of change
Additional information
When reviewing this integration, please keep in mind that it represents a user on the playstation network and not the PlayStation console itself. It is structured around allowing the user to associate multiple PSN accounts and the device names are setup to match this. This integration started its life as a custom component and has about ~400 users. For a look at what this may evolve into, here is a link to the custom repository.
This initial release of the PlayStation Network Integration exposes a media player based on the user's registered systems with the playstation network. One will be created for any PS4 systems and another for any PS5 systems. However, due to api limitations, it is not possible to pull data for more than a single console at a time nor do I have dates for when a console was last active. Given these limitations I'd like to discuss what the Home Assistant team believes is the best course of action to take in this regard:
A quality_scale.yaml file is included and I did my best to conform to all bronze level items. Some are marked as done, like common-modules, that still have pending tasks (the creation of entity.py for instance) but was skipped for this initial release. If this is the wrong approach, please let me know.
The integration communicates with the PlayStation Network via a supplied NPSSO token that the config flow walks the user through obtaining (along with the documentation referenced in PR#36520.
This integration relies on the PSNAWP project which was reversed engineered from the PlayStation Mobile app and is not endorsed or supported by Sony.
This PR wouldn't have been possible without the amazing help and guidance from @tr4nt0r. He put in so much time and effort to ensure this first PR go smoothly.
The associated brand images were included for the custom integration and are still up to date. Brands PR
Checklist
ruff format homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
.To help with the load of incoming pull requests: