Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 5 additions & 1 deletion homeassistant/components/playstation_network/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
from .coordinator import PlaystationNetworkConfigEntry, PlaystationNetworkCoordinator
from .helpers import PlaystationNetwork

PLATFORMS: list[Platform] = [Platform.MEDIA_PLAYER, Platform.SENSOR]
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
Platform.MEDIA_PLAYER,
Platform.SENSOR,
]


async def async_setup_entry(
Expand Down
71 changes: 71 additions & 0 deletions homeassistant/components/playstation_network/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Binary Sensor platform for PlayStation Network integration."""

from __future__ import annotations

from collections.abc import Callable
from dataclasses import dataclass
from enum import StrEnum

from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .coordinator import PlaystationNetworkConfigEntry, PlaystationNetworkData
from .entity import PlaystationNetworkServiceEntity

PARALLEL_UPDATES = 0


@dataclass(kw_only=True, frozen=True)
class PlaystationNetworkBinarySensorEntityDescription(BinarySensorEntityDescription):
"""PlayStation Network binary sensor description."""

is_on_fn: Callable[[PlaystationNetworkData], bool]


class PlaystationNetworkBinarySensor(StrEnum):
"""PlayStation Network binary sensors."""

PS_PLUS_STATUS = "ps_plus_status"


Comment thread
frenck marked this conversation as resolved.
BINARY_SENSOR_DESCRIPTIONS: tuple[
PlaystationNetworkBinarySensorEntityDescription, ...
] = (
PlaystationNetworkBinarySensorEntityDescription(
key=PlaystationNetworkBinarySensor.PS_PLUS_STATUS,
translation_key=PlaystationNetworkBinarySensor.PS_PLUS_STATUS,
is_on_fn=lambda psn: psn.profile["isPlus"],
),
)


async def async_setup_entry(
hass: HomeAssistant,
config_entry: PlaystationNetworkConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the binary sensor platform."""
coordinator = config_entry.runtime_data
async_add_entities(
PlaystationNetworkBinarySensorEntity(coordinator, description)
for description in BINARY_SENSOR_DESCRIPTIONS
)


class PlaystationNetworkBinarySensorEntity(
PlaystationNetworkServiceEntity,
BinarySensorEntity,
):
"""Representation of a PlayStation Network binary sensor entity."""

entity_description: PlaystationNetworkBinarySensorEntityDescription

@property
def is_on(self) -> bool:
"""Return the state of the binary sensor."""

return self.entity_description.is_on_fn(self.coordinator.data)
36 changes: 36 additions & 0 deletions homeassistant/components/playstation_network/entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Base entity for PlayStation Network Integration."""

from typing import TYPE_CHECKING

from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN
from .coordinator import PlaystationNetworkCoordinator


class PlaystationNetworkServiceEntity(CoordinatorEntity[PlaystationNetworkCoordinator]):
"""Common entity class for PlayStationNetwork Service entities."""

_attr_has_entity_name = True
Comment thread
JackJPowell marked this conversation as resolved.

def __init__(
self,
coordinator: PlaystationNetworkCoordinator,
entity_description: EntityDescription,
) -> None:
"""Initialize PlayStation Network Service Entity."""
super().__init__(coordinator)
if TYPE_CHECKING:
assert coordinator.config_entry.unique_id
self.entity_description = entity_description
self._attr_unique_id = (
f"{coordinator.config_entry.unique_id}_{entity_description.key}"
)
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, coordinator.config_entry.unique_id)},
name=coordinator.data.username,
entry_type=DeviceEntryType.SERVICE,
manufacturer="Sony Interactive Entertainment",
)
5 changes: 5 additions & 0 deletions homeassistant/components/playstation_network/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
"default": "mdi:sony-playstation"
}
},
"binary_sensor": {
"ps_plus_status": {
"default": "mdi:shape-plus-outline"
}
},
"sensor": {
"trophy_level": {
"default": "mdi:trophy-award"
Expand Down
35 changes: 4 additions & 31 deletions homeassistant/components/playstation_network/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from dataclasses import dataclass
from datetime import datetime
from enum import StrEnum
from typing import TYPE_CHECKING

from homeassistant.components.sensor import (
SensorDeviceClass,
Expand All @@ -15,18 +14,12 @@
)
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util import dt as dt_util

from .const import DOMAIN
from .coordinator import (
PlaystationNetworkConfigEntry,
PlaystationNetworkCoordinator,
PlaystationNetworkData,
)
from .coordinator import PlaystationNetworkConfigEntry, PlaystationNetworkData
from .entity import PlaystationNetworkServiceEntity

PARALLEL_UPDATES = 0

Expand Down Expand Up @@ -146,32 +139,12 @@ async def async_setup_entry(


class PlaystationNetworkSensorEntity(
CoordinatorEntity[PlaystationNetworkCoordinator], SensorEntity
PlaystationNetworkServiceEntity,
SensorEntity,
):
"""Representation of a PlayStation Network sensor entity."""

entity_description: PlaystationNetworkSensorEntityDescription
coordinator: PlaystationNetworkCoordinator

_attr_has_entity_name = True

def __init__(
self,
coordinator: PlaystationNetworkCoordinator,
description: PlaystationNetworkSensorEntityDescription,
) -> None:
"""Initialize a sensor entity."""
super().__init__(coordinator)
self.entity_description = description
if TYPE_CHECKING:
assert coordinator.config_entry.unique_id
self._attr_unique_id = f"{coordinator.config_entry.unique_id}_{description.key}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, coordinator.config_entry.unique_id)},
name=coordinator.data.username,
entry_type=DeviceEntryType.SERVICE,
manufacturer="Sony Interactive Entertainment",
)

@property
def native_value(self) -> StateType | datetime:
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/playstation_network/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
}
},
"entity": {
"binary_sensor": {
"ps_plus_status": {
"name": "Subscribed to PlayStation Plus"
}
},
"sensor": {
"trophy_level": {
"name": "Trophy level"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# serializer version: 1
# name: test_sensors[binary_sensor.testuser_subscribed_to_playstation_plus-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.testuser_subscribed_to_playstation_plus',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Subscribed to PlayStation Plus',
'platform': 'playstation_network',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': <PlaystationNetworkBinarySensor.PS_PLUS_STATUS: 'ps_plus_status'>,
'unique_id': 'my-psn-id_ps_plus_status',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[binary_sensor.testuser_subscribed_to_playstation_plus-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'testuser Subscribed to PlayStation Plus',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.testuser_subscribed_to_playstation_plus',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
42 changes: 42 additions & 0 deletions tests/components/playstation_network/test_binary_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Test the Playstation Network binary sensor platform."""

from collections.abc import Generator
from unittest.mock import patch

import pytest
from syrupy.assertion import SnapshotAssertion

from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er

from tests.common import MockConfigEntry, snapshot_platform


@pytest.fixture(autouse=True)
def binary_sensor_only() -> Generator[None]:
"""Enable only the binary sensor platform."""
with patch(
"homeassistant.components.playstation_network.PLATFORMS",
[Platform.BINARY_SENSOR],
):
yield


@pytest.mark.usefixtures("mock_psnawpapi")
async def test_sensors(
hass: HomeAssistant,
config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
) -> None:
"""Test setup of the PlayStation Network binary sensor platform."""

config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()

assert config_entry.state is ConfigEntryState.LOADED

await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)