Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerwyn committed Oct 9, 2023
2 parents 591e722 + c18225d commit fefcaf2
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 90 deletions.
43 changes: 23 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,24 @@ Call any service via a tile button. This custom tile feature will let you do wha

### Button Config

| Name | Type | Description |
| -------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| service | string | The service call to make, e.g. `light.toggle` or `lock.unlock`. |
| data.entity_id | string | The entity ID of the device to call the service on. If left blank will use the entity ID assigned to the tile card. |
| data | object | Additional data to pass to the service call. See the Home Assistant documentation or go to `Developer Tools > Services` to see available options for each service. |
| color | string | Custom color for the button. Should either be a color name like `red` or an rgb function like `rgb(255 0 0)`. |
| opacity | float | Opacity of the button background. Should be a number between 0 and 1. Defaults to 0.2. |
| icon | string | Material design icon to use. |
| icon_color | string | Custom color for the icon. Should either be a color name like `red` or an rgb function like `rgb(255 0 0)`. |
| label | string | String label to place underneath the icon, or by itself. |
| label_color | string | Custom color for the string label. Should either be a color name like `red` or an rgb function like `rgb(255 0 0)`. |
### Service Call Options

| Name | Type | Description |
| ------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| service | string | The service call to make, e.g. `light.toggle` or `lock.unlock`. |
| target | object | The entity IDs, device IDs, or area IDs to call the service on. If left blank will use the entity ID assigned to the tile card. |
| data | object | Additional data to pass to the service call. See the Home Assistant documentation or go to `Developer Tools > Services` to see available options for each service. |

#### Style Options

| Name | Type | Description |
| ----------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| color | string | Custom color for the button. Should either be a color name like `red` or an rgb function like `rgb(255 0 0)`. |
| opacity | float | Opacity of the button background. Should be a number between 0 and 1. Defaults to 0.2. |
| icon | string | Material design icon to use. |
| icon_color | string | Custom color for the icon. Should either be a color name like `red` or an rgb function like `rgb(255 0 0)`. |
| label | string | String label to place underneath the icon, or by itself. |
| label_color | string | Custom color for the string label. Should either be a color name like `red` or an rgb function like `rgb(255 0 0)`. |

## Examples

Expand Down Expand Up @@ -78,58 +85,54 @@ features:
icon: mdi:lightbulb
icon_color: orange
label: Bulb 1
data:
target:
entity_id: light.chandelier_bulb_1
- service: light.toggle
icon: mdi:lightbulb
icon_color: yellow
label: Bulb 2
data:
target:
entity_id: light.chandelier_bulb_2
- service: light.toggle
icon: mdi:lightbulb
icon_color: green
label: Bulb 3
data:
target:
entity_id: light.chandelier_bulb_3
- service: light.toggle
icon: mdi:lightbulb
icon_color: blue
label: Bulb 4
data:
target:
entity_id: light.chandelier_bulb_4
- service: light.toggle
icon: mdi:lightbulb
icon_color: purple
label: Bulb 5
data:
target:
entity_id: light.chandelier_bulb_5
- type: custom:service-call
buttons:
- service: light.turn_on
color: red
xicon_color: rgb(255 0 0)
label: Red
label_color: red
data:
color_name: red
- service: light.turn_on
color: green
icon_color: rgb(0 255 0)
label: Green
label_color: green
data:
color_name: green
- service: light.turn_on
color: blue
icon_color: rgb(0 0 255)
label: Blue
label_color: blue
data:
color_name: blue
- service: light.turn_on
color: white
icon_color: rgb(255 255 255)
label: White
label_color: white
data:
Expand Down
22 changes: 9 additions & 13 deletions dist/service-call-tile-feature.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "service-call-tile-feature",
"version": "1.1.0",
"version": "1.2.0",
"description": "Service Call Tile Feature for Home Assistant Tile Card",
"main": "./dist/service-call-tile-feature.js",
"scripts": {
Expand Down
39 changes: 24 additions & 15 deletions src/models/interfaces/IConfig.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
export interface IConfig {
type: string;
buttons: [
{
service: string;
data?: {
entity_id?: string;
[key: string]: string | number | boolean | undefined;
};
color?: string;
opacity?: number;
icon?: string;
icon_color?: string;
label?: string;
label_color?: string;
},
];
buttons: IButton[];
}

export interface IButton extends IServiceCall, IStyle {}

export interface IServiceCall {
service: string;
data?: {
[key: string]: string | string[] | number | boolean;
};
target?: {
entity_id?: string | string[];
device_id?: string | string[];
area_id?: string | string[];
};
}

export interface IStyle {
color?: string;
opacity?: number;
icon?: string;
icon_color?: string;
label?: string;
label_color?: string;
}
105 changes: 64 additions & 41 deletions src/service-call-tile-feature.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { version } from '../package.json';
import { LitElement, TemplateResult, html, css } from 'lit';
import { property } from 'lit/decorators.js';
import { HomeAssistant } from 'custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket';
import { IConfig } from './models/interfaces';

console.info(
`%c SERVICE-CALL-TILE-FEATURE v${version}`,
'color: white; font-weight: bold; background: cornflowerblue',
);

class ServiceCallTileFeature extends LitElement {
@property({ attribute: false })
hass!: HomeAssistant;
Expand All @@ -30,7 +36,6 @@ class ServiceCallTileFeature extends LitElement {
buttons: [
{
service: '',
data: {},
},
],
};
Expand All @@ -40,6 +45,14 @@ class ServiceCallTileFeature extends LitElement {
if (!config) {
throw new Error('Invalid configuration');
}
config = JSON.parse(JSON.stringify(config));
for (const button of config.buttons) {
// Merge target and data fields
button.data = {
...(button.data || {}),
...(button.target || {}),
};
}
this.config = config;
}

Expand All @@ -50,14 +63,53 @@ class ServiceCallTileFeature extends LitElement {
'-1',
);
const button = this.config.buttons[i];
const [domain, service] = button.service.split('.');

const data = button.data || {};
if (
!('entity_id' in data) &&
!('device_id' in data) &&
!('area_id' in data)
) {
data['entity_id'] = this.stateObj.entity_id;
}

this.hass.callService(domain, service, data);
}

const data = JSON.parse(JSON.stringify(button.data || {}));
if (!('entity_id' in data) || data.entity_id == '') {
data.entity_id = this.stateObj.entity_id;
renderBackground(itemid: number, color?: string, opacity?: number) {
let colorStyle = ``;
let opacityStyle = ``;
if (color) {
colorStyle = `background-color: ${color};`;
}
if (opacity) {
opacityStyle = `opacity: ${opacity};`;
}
const [domain, entity] = button.service.split('.');
const style = `${colorStyle}${opacityStyle}`;

return html`<button
class="button"
itemid=${itemid}
@click=${this._press}
style="${style}"
></button>`;
}

this.hass.callService(domain, entity, data);
renderIcon(icon: string, color?: string) {
let style = ``;
if (color) {
style = `color: ${color};`;
}
return html`<ha-icon .icon=${icon} style="${style}"></ha-icon>`;
}

renderLabel(text: string, color?: string) {
let style = ``;
if (color) {
style = `color: ${color};`;
}
return html`<div class="label" style="${style}">${text}</div>`;
}

render() {
Expand All @@ -69,48 +121,20 @@ class ServiceCallTileFeature extends LitElement {
for (const [i, entry] of this.config.buttons.entries()) {
const button: TemplateResult[] = [];

// Button color and opacity
let color = ``;
let opacity = ``;
if ('color' in entry) {
color = `background-color: ${entry.color};`;
}
if ('opacity' in entry) {
opacity = `opacity: ${entry.opacity};`;
}
const style = `${color}${opacity}`;
button.push(
html`<button
class="button"
itemid=${i}
@click=${this._press}
style="${style}"
></button>`,
);
// Button/Background
button.push(this.renderBackground(i, entry.color, entry.opacity));

// Icon
if ('icon' in entry) {
let iconStyle = ``;
if ('icon_color' in entry) {
iconStyle = `color: ${entry.icon_color};`;
}
button.push(
html`<ha-icon
.icon=${entry.icon}
style="${iconStyle}"
></ha-icon>`,
this.renderIcon(entry.icon as string, entry.icon_color),
);
}

// Label
if ('label' in entry) {
let labelStyle = ``;
if ('label_color' in entry) {
labelStyle = `color: ${entry.label_color};`;
}
button.push(
// prettier-ignore
html`<div class="label" style="${labelStyle}">${entry.label}</div>`,
this.renderLabel(entry.label as string, entry.label_color),
);
}

Expand All @@ -129,7 +153,8 @@ class ServiceCallTileFeature extends LitElement {
flex-flow: row;
justify-content: center;
align-items: center;
padding: 0 12px 12px 12px;
padding: 0 12px 12px;
gap: 12px;
width: auto;
}
.container {
Expand All @@ -142,7 +167,6 @@ class ServiceCallTileFeature extends LitElement {
width: 100%;
border-radius: 10px;
border: none;
margin: 0 6px;
padding: 0px;
box-sizing: border-box;
line-height: 0;
Expand Down Expand Up @@ -189,7 +213,6 @@ class ServiceCallTileFeature extends LitElement {
width: inherit;
font-family: inherit;
font-size: 12px;
bottom: 2px;
}
`;
}
Expand Down

0 comments on commit fefcaf2

Please sign in to comment.