mirror of
https://github.com/home-assistant/frontend.git
synced 2026-06-10 02:13:26 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 261e08d0ed | |||
| 2763ed22b8 | |||
| 359b56e7f3 | |||
| 0751aa0b66 | |||
| 37100069ac |
@@ -4,7 +4,8 @@ import { ensureArray } from "../array/ensure-array";
|
||||
import { isComponentLoaded } from "./is_component_loaded";
|
||||
|
||||
export const canShowPage = (hass: HomeAssistant, page: PageNavigation) =>
|
||||
isCore(page) || isLoadedIntegration(hass, page);
|
||||
(isCore(page) || isLoadedIntegration(hass, page)) &&
|
||||
(!page.filter || page.filter(hass));
|
||||
|
||||
export const isLoadedIntegration = (
|
||||
hass: HomeAssistant,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { HomeAssistant } from "../types";
|
||||
|
||||
export interface RadioFrequencyTransmitter {
|
||||
entity_id: string;
|
||||
device_id: string | null;
|
||||
config_entry_id: string | null;
|
||||
supported_frequency_ranges: [number, number][];
|
||||
supported_modulations: string[];
|
||||
}
|
||||
|
||||
interface RadioFrequencyTransmitterList {
|
||||
transmitters: RadioFrequencyTransmitter[];
|
||||
}
|
||||
|
||||
export const fetchRadioFrequencyTransmitters = (
|
||||
hass: HomeAssistant
|
||||
): Promise<RadioFrequencyTransmitterList> =>
|
||||
hass.callWS({
|
||||
type: "radio_frequency/list",
|
||||
});
|
||||
@@ -36,6 +36,7 @@ export interface PageNavigation {
|
||||
core?: boolean;
|
||||
/** Hide from non-admin users in filtered navigation and quick bar. */
|
||||
adminOnly?: boolean;
|
||||
filter?: (hass: HomeAssistant) => boolean;
|
||||
iconPath?: string;
|
||||
iconSecondaryPath?: string;
|
||||
iconViewBox?: string;
|
||||
|
||||
@@ -29,12 +29,14 @@ import {
|
||||
mdiTextBoxOutline,
|
||||
mdiTools,
|
||||
mdiUpdate,
|
||||
mdiVideoInputAntenna,
|
||||
mdiViewDashboard,
|
||||
mdiZigbee,
|
||||
mdiZWave,
|
||||
} from "@mdi/js";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { listenMediaQuery } from "../../common/dom/media_query";
|
||||
import type { CloudStatus } from "../../data/cloud";
|
||||
@@ -55,6 +57,14 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
const getHasDomainCheck = (domain: string) => {
|
||||
const prefix = `${domain}.`;
|
||||
const checkRegistry = memoizeOne((entries: HomeAssistant["entities"]) =>
|
||||
Object.values(entries).some((entry) => entry.entity_id.startsWith(prefix))
|
||||
);
|
||||
return (hass: HomeAssistant) => checkRegistry(hass.entities);
|
||||
};
|
||||
|
||||
export const configSections: Record<string, PageNavigation[]> = {
|
||||
dashboard: [
|
||||
{
|
||||
@@ -166,6 +176,15 @@ export const configSections: Record<string, PageNavigation[]> = {
|
||||
translationKey: "bluetooth",
|
||||
adminOnly: true,
|
||||
},
|
||||
{
|
||||
path: "/config/radio-frequency",
|
||||
iconPath: mdiVideoInputAntenna,
|
||||
iconColor: "#E74011",
|
||||
component: "radio_frequency",
|
||||
translationKey: "radio_frequency",
|
||||
adminOnly: true,
|
||||
filter: getHasDomainCheck("radio_frequency"),
|
||||
},
|
||||
{
|
||||
path: "/insteon",
|
||||
iconPath:
|
||||
@@ -667,6 +686,11 @@ class HaPanelConfig extends HassRouterPage {
|
||||
tag: "ha-config-section-updates",
|
||||
load: () => import("./core/ha-config-section-updates"),
|
||||
},
|
||||
"radio-frequency": {
|
||||
tag: "radio-frequency-config-dashboard",
|
||||
load: () =>
|
||||
import("./integrations/integration-panels/radio_frequency/radio-frequency-config-dashboard"),
|
||||
},
|
||||
repairs: {
|
||||
tag: "ha-config-repairs-dashboard",
|
||||
load: () => import("./repairs/ha-config-repairs-dashboard"),
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
import { mdiRadioTower } from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "../../../../../components/ha-card";
|
||||
import "../../../../../components/ha-icon-next";
|
||||
import "../../../../../components/ha-md-list";
|
||||
import "../../../../../components/ha-md-list-item";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import "../../../../../components/ha-relative-time";
|
||||
import type { RadioFrequencyTransmitter } from "../../../../../data/radio_frequency";
|
||||
import { fetchRadioFrequencyTransmitters } from "../../../../../data/radio_frequency";
|
||||
import "../../../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import { computeDeviceName } from "../../../../../common/entity/compute_device_name";
|
||||
import { computeEntityName } from "../../../../../common/entity/compute_entity_name";
|
||||
|
||||
@customElement("radio-frequency-config-dashboard")
|
||||
export class RadioFrequencyConfigDashboard extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ attribute: "is-wide", type: Boolean }) public isWide = false;
|
||||
|
||||
@state() private _transmitters: RadioFrequencyTransmitter[] = [];
|
||||
|
||||
public firstUpdated(changedProps: PropertyValues): void {
|
||||
super.firstUpdated(changedProps);
|
||||
this._fetchTransmitters();
|
||||
}
|
||||
|
||||
private async _fetchTransmitters(): Promise<void> {
|
||||
const result = await fetchRadioFrequencyTransmitters(this.hass);
|
||||
this._transmitters = result.transmitters;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.header=${this.hass.localize("ui.panel.config.radio_frequency.title")}
|
||||
back-path="/config"
|
||||
>
|
||||
<div class="container">
|
||||
<ha-card
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.radio_frequency.transmitters_count",
|
||||
{ count: this._transmitters.length }
|
||||
)}
|
||||
>
|
||||
<div class="card-content">
|
||||
${this._transmitters.length === 0
|
||||
? html`<p class="no-transmitters">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.radio_frequency.no_transmitters"
|
||||
)}
|
||||
</p>`
|
||||
: html`
|
||||
<ha-md-list>
|
||||
${this._transmitters.map((transmitter) =>
|
||||
this._renderTransmitter(transmitter)
|
||||
)}
|
||||
</ha-md-list>
|
||||
`}
|
||||
</div>
|
||||
</ha-card>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderTransmitter(
|
||||
transmitter: RadioFrequencyTransmitter
|
||||
): TemplateResult {
|
||||
const entityState = this.hass.states[transmitter.entity_id];
|
||||
const entity = this.hass.entities[transmitter.entity_id];
|
||||
const device = transmitter.device_id
|
||||
? this.hass.devices[transmitter.device_id]
|
||||
: undefined;
|
||||
const areaId = entity.area_id || (device ? device.area_id : undefined);
|
||||
const area = areaId ? this.hass.areas[areaId] : undefined;
|
||||
return html`
|
||||
<ha-md-list-item
|
||||
type=${device ? "link" : "text"}
|
||||
href=${device
|
||||
? `/config/devices/device/${transmitter.device_id}`
|
||||
: nothing}
|
||||
>
|
||||
<ha-svg-icon slot="start" .path=${mdiRadioTower}></ha-svg-icon>
|
||||
<div slot="headline">
|
||||
${device
|
||||
? computeDeviceName(device)
|
||||
: computeEntityName(
|
||||
this.hass.states[transmitter.entity_id],
|
||||
this.hass.entities,
|
||||
this.hass.devices
|
||||
)}
|
||||
</div>
|
||||
<div slot="supporting-text">
|
||||
${area ? `${area.name} · ` : ""}
|
||||
${transmitter.supported_frequency_ranges
|
||||
.map(
|
||||
([min, max]) =>
|
||||
`${parseFloat((min / 1000000).toFixed(2))}-${parseFloat((max / 1000000).toFixed(2))}MHz`
|
||||
)
|
||||
.join(", ")}
|
||||
· ${transmitter.supported_modulations.join(", ")}
|
||||
</div>
|
||||
|
||||
${device
|
||||
? html`<div slot="end">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.radio_frequency.last_used"
|
||||
)}:
|
||||
<br />
|
||||
${entityState.state === "unknown" ||
|
||||
entityState.state === "unavailable"
|
||||
? this.hass.localize(`state.default.${entityState.state}`)
|
||||
: html`
|
||||
<ha-relative-time
|
||||
.datetime=${entityState.state}
|
||||
></ha-relative-time>
|
||||
`}
|
||||
</div>`
|
||||
: nothing}
|
||||
</ha-md-list-item>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.container {
|
||||
padding: var(--ha-space-2) var(--ha-space-4) var(--ha-space-4);
|
||||
}
|
||||
|
||||
ha-card {
|
||||
margin: 0px auto var(--ha-space-4);
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
ha-card .card-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ha-md-list {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.no-transmitters {
|
||||
padding: var(--ha-space-4);
|
||||
margin: 0;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"radio-frequency-config-dashboard": RadioFrequencyConfigDashboard;
|
||||
}
|
||||
}
|
||||
@@ -1616,6 +1616,7 @@
|
||||
"zwave_js": "[%key:ui::panel::config::dashboard::zwave_js::main%]",
|
||||
"thread": "[%key:ui::panel::config::dashboard::thread::main%]",
|
||||
"bluetooth": "[%key:ui::panel::config::dashboard::bluetooth::main%]",
|
||||
"radio_frequency": "[%key:ui::panel::config::dashboard::radio_frequency::main%]",
|
||||
"knx": "[%key:ui::panel::config::dashboard::knx::main%]",
|
||||
"insteon": "[%key:ui::panel::config::dashboard::insteon::main%]",
|
||||
"voice-assistants": "[%key:ui::panel::config::dashboard::voice_assistants::main%]",
|
||||
@@ -2718,6 +2719,10 @@
|
||||
"main": "Bluetooth",
|
||||
"secondary": "Local device connectivity"
|
||||
},
|
||||
"radio_frequency": {
|
||||
"main": "Radio frequency",
|
||||
"secondary": "Control radio-based devices."
|
||||
},
|
||||
"knx": {
|
||||
"main": "KNX",
|
||||
"secondary": "Building automation standard"
|
||||
@@ -7187,6 +7192,12 @@
|
||||
"known_devices": "Known devices",
|
||||
"unknown_devices": "Unknown devices"
|
||||
},
|
||||
"radio_frequency": {
|
||||
"title": "Radio frequency",
|
||||
"transmitters_count": "{count} {count, plural,\n one {transmitter}\n other {transmitters}\n}",
|
||||
"no_transmitters": "No radio frequency transmitters found",
|
||||
"last_used": "Last used"
|
||||
},
|
||||
"dhcp": {
|
||||
"title": "DHCP discovery",
|
||||
"mac_address": "MAC address",
|
||||
|
||||
Reference in New Issue
Block a user