Skip to content

Commit

Permalink
Merge pull request #7 from igor-panteleev/develop
Browse files Browse the repository at this point in the history
Release v1.2.0
  • Loading branch information
igor-panteleev authored Jul 29, 2024
2 parents 4c06223 + e9936ed commit 5fd49ce
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 227 deletions.
134 changes: 43 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
[![hacs_badge][hacs_shield]][hacs]
[![GitHub Latest Release][releases_shield]][latest_release]

[hacs_shield]: https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge
[hacs]: https://github.com/hacs/integration

[releases_shield]: https://img.shields.io/github/release/igor-panteleev/lovelace-qr-code-card.svg?style=for-the-badge
[latest_release]: https://github.com/igor-panteleev/lovelace-qr-code-card/releases/latest

# Lovelace QRCode Generator card
This card provides a possibility to generate QRCode in Home Assistant interface.

Expand All @@ -19,88 +13,46 @@ This card provides a possibility to generate QRCode in Home Assistant interface.

## Configuration

<table>
<tr>
<th>Key</th>
<th>Type</th>
<th>Required</th>
<th>Default</th>
<th>Description</th>
</tr>
<tr>
<td colspan="5" style="text-align: center">
General options
</td>
</tr>
<tr>
<td><code>title</code></td>
<td>string</td>
<td>no</td>
<td>empty</td>
<td>Title for the card</td>
</tr>
<tr>
<td><code>source</code></td>
<td>string</td>
<td>yes</td>
<td><i>text</i></td>
<td>Card source type. Options: <code>text</code>, <code>entity</code>, <code>wifi</code></td>
</tr>
<tr>
<td colspan="5" style="text-align: center">
Text mode options
</td>
</tr>
<tr>
<td><code>text</code></td>
<td>string</td>
<td>yes</td>
<td><i>QRCode example text</i></td>
<td>Text that will be used for QRCode generation</td>
</tr>
<tr>
<td colspan="5" style="text-align: center">
Entity mode options
</td>
</tr>
<tr>
<td><code>entity</code></td>
<td>string</td>
<td>yes</td>
<td>empty</td>
<td>Entity that will be used for QRCode generation</td>
</tr>
<tr>
<td colspan="5" style="text-align: center">
Wi-Fi mode options
</td>
</tr>
<tr>
<td><code>auth_type</code></td>
<td>string</td>
<td>yes</td>
<td>empty</td>
<td>Wi-Fi network authentication type. Options: <code>WEP</code>, <code>WPA</code>, <code>nopass</code></td>
</tr>
<tr>
<td><code>ssid</code></td>
<td>string</td>
<td>yes</td>
<td>empty</td>
<td>Wi-Fi network ssid</td>
</tr>
<tr>
<td><code>password</code></td>
<td>string</td>
<td>yes (except <code>nopass</code> authentication)</td>
<td>empty</td>
<td>Wi-Fi network password</td>
</tr>
<tr>
<td><code>is_hidden</code></td>
<td>boolean</td>
<td>no</td>
<td>empty</td>
<td>Is Wi-Fi network is hidden</td>
</tr>
</table>
### Main config

| Key | Type | Required | Default | Description |
|-----------------------|------------------------------------------|-----------------|---------------------|-------------------------------------------------------------------------|
| *Generic options* |
| `title` | string | no | empty | Title for the card |
| `source` | string | yes | `text` | Card source type.<br/>Options: `text,` `entity`, `wifi` |
| *Text mode options* |
| `text` | string | yes | QRCode example text | Text that will be used for QRCode generation |
| *Entity mode options* |
| `entity` | string | yes | empty | Entity that will be used for QRCode generation |
| *Wi-Fi mode options* |
| `auth_type` | string | yes | empty | Wi-Fi network authentication type.<br/>Options: `WEP`, `WPA`, `nopass` |
| `ssid` | string \| [EntityConfig](#entity-config) | yes | empty | Wi-Fi network ssid |
| `password` | string \| [EntityConfig](#entity-config) | yes<sup>1</sup> | empty | Wi-Fi network password |
| `is_hidden` | boolean | no | empty | Is Wi-Fi network is hidden |

<sup>1</sup>Required for `WEP` and `WPA` authentication

### Entity Config

| Key | Type | Required | Description |
|-------------|--------|----------|--------------------------------------------------------------------------|
| `entity` | string | yes | Entity to get state from |
| `attribute` | string | no | Enables usage of a configured attribute instead of state of given entity |


### Example WiFi config
```yaml
type: custom:qr-code-card
source: wifi
title: My Awesom WiFi
auth_type: WPA
ssid: my_awesom_wifi
password:
entity: input_text.my_super_secure_password
```
[hacs_shield]: https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge
[hacs]: https://github.com/hacs/integration
[releases_shield]: https://img.shields.io/github/release/igor-panteleev/lovelace-qr-code-card.svg?style=for-the-badge
[latest_release]: https://github.com/igor-panteleev/lovelace-qr-code-card/releases/latest
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "qr-code-card",
"version": "v1.1.0",
"version": "v1.2.0",
"description": "QR code card",
"keywords": [
"home-assistant",
Expand Down
43 changes: 39 additions & 4 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "./types/types";
import { localizeWithHass } from "./localize/localize";
import { SourceType } from "./models/source-type";
import { AuthenticationType, is_password_protected } from "./models/authentication-type";
import { AuthenticationType, isPasswordProtected } from "./models/authentication-type";
import { EDITOR_CUSTOM_ELEMENT_NAME } from "./const";

Check warning on line 16 in src/editor.ts

View workflow job for this annotation

GitHub Actions / Test build

'EDITOR_CUSTOM_ELEMENT_NAME' is defined but never used

Check warning on line 16 in src/editor.ts

View workflow job for this annotation

GitHub Actions / Prepare release

'EDITOR_CUSTOM_ELEMENT_NAME' is defined but never used


Expand Down Expand Up @@ -54,24 +54,39 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {

get _ssid(): string {
const config = this._config as WiFiSourceConfig | undefined;
return config?.ssid || "";
if (typeof config?.ssid === "string") {
return config?.ssid || "";
}
return ""
}

get _password(): string {
const config = this._config as WiFiSourceConfig | undefined;
return config?.password || "";
if (typeof config?.password === "string") {
return config?.password || "";
}
return "";
}

get _is_hidden(): boolean {
const config = this._config as WiFiSourceConfig | undefined;
return config?.is_hidden || false;
}

get _is_debug(): boolean {
const config = this._config as QRCodeCardConfig | undefined;
return config?.debug || false;
}

get _entity(): string {
const config = this._config as EntitySourceConfig | undefined;
return config?.entity || ""
}

private _isDisabled(): boolean {
return this._config?.source === SourceType.WIFI && (typeof this._config?.ssid !== "string" || typeof this._config?.password !== "string");
}

private _localize(ts: TranslatableString): string {
return localizeWithHass(ts, this.hass, this._config);
}
Expand All @@ -81,6 +96,13 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
return html``;
}

if (this._isDisabled()) {
return html`
<div class="card-config">
<div class="error">${this._localize("editor.yaml_mode")}</div>
</div>`;
}

const entities = Object.keys(this.hass.states);

return html`
Expand Down Expand Up @@ -139,7 +161,7 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
.configValue=${"ssid"}
@input=${this._valueChanged}></ha-textfield>
</div>
${is_password_protected(this._auth_type) ? html`
${isPasswordProtected(this._auth_type) ? html`
<div class="values">
<ha-textfield
.type=${this._unmaskedPassword ? "text" : "password"}
Expand Down Expand Up @@ -183,6 +205,15 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
})}
</ha-select>
</div>` : ""}
<div class="values">
<ha-formfield .label=${this._localize("editor.label.is_debug")}>
<ha-switch
.checked=${this._is_debug}
.configValue=${"debug"}
@change=${this._valueChanged}></ha-switch>
</ha-formfield>
</div>
</div>
`;
}
Expand Down Expand Up @@ -250,6 +281,10 @@ export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
color: var(--secondary-text-color);
direction: var(--direction);
}
.error {
color: var(--error-color);
}
`;
}
}
18 changes: 18 additions & 0 deletions src/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import QRCode from "qrcode";

import { DataUrl } from "./types/types";
import { TranslatableError } from "./models/error";

const quality = {
margin: 1,
width: 500
}

export async function generateQR(inputString: string): Promise<DataUrl> {
try {
return QRCode.toDataURL(inputString, quality);
}
catch (e: unknown) {
throw new TranslatableError("generation.unknown_error")
}
}
30 changes: 24 additions & 6 deletions src/localize/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"auth_type": "Authentication type (required)",
"ssid": "SSID (required)",
"password": "Password (required)",
"is_hidden": "Hidden SSID"
"is_hidden": "Hidden SSID",
"is_debug": "Debug mode (Show value for QR code)"
},
"title": {
"show_password": "Show password",
Expand All @@ -30,9 +31,13 @@
"WPA": "WPA",
"nopass": "None"
}
}
},
"yaml_mode": "Configuring SSID and password from entity is not supported in visual editor mode. Please switch to code editor mode."
},
"validation": {
"debug": {
"invalid": "Debug mode must be true or false"
},
"source": {
"missing": "Missing property: source",
"invalid": "Invalid source type"
Expand All @@ -45,16 +50,29 @@
"invalid": "Invalid authentication type"
},
"ssid": {
"missing": "Missing property: ssid"
"missing": "Missing property: ssid",
"unknown_type": "Unsupported data type for SSID: {type}",
"unknown_entity": "Entity specified for SSID is unknown: {entity}",
"unknown_attribute": "Attribute specified for SSID is unknown: {attribute}",
"unavailable": "Entity specified for SSID is unavailable: {entity}"
},
"password": {
"missing": "Missing property: password"
"missing": "Missing property: password",
"unknown_type": "Unsupported data type for password: {type}",
"unknown_entity": "Entity specified for password is unknown: {entity}",
"unknown_attribute": "Attribute specified for password is unknown: {attribute}",
"unavailable": "Entity specified for password is unavailable: {entity}"
},
"entity": {
"missing": "Missing property: entity"
"missing": "Missing property: entity",
"unknown_type": "Unsupported data type for entity: {type}",
"unknown_entity": "Unknown entity: {entity}",
"unknown_attribute": "Attribute specified for entity is unknown: {attribute}",
"unavailable": "Entity is unavailable: {entity}"
}
},
"generation": {
"error": "An error occurred while generating QR-Code"
"error": "An error occurred while generating QR-Code: {message}",
"unknown_error": "An error occurred while generating QR-Code"
}
}
2 changes: 1 addition & 1 deletion src/models/authentication-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export enum AuthenticationType {

const PasswordAuthenticationTypes = [AuthenticationType.WEP, AuthenticationType.WPA];

export function is_password_protected(auth_type: AuthenticationType | undefined): boolean {
export function isPasswordProtected(auth_type: AuthenticationType | undefined): boolean {
return auth_type !== undefined && PasswordAuthenticationTypes.includes(auth_type);
}
Loading

0 comments on commit 5fd49ce

Please sign in to comment.