Skip to content

Commit

Permalink
Merge pull request #1223 from bytefloater/main
Browse files Browse the repository at this point in the history
Rework and Refinements to 'custom_card_sisimomo_printer'
  • Loading branch information
basbruss committed Apr 3, 2023
2 parents 07adf0f + fd16cad commit 458585d
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 31 deletions.
71 changes: 61 additions & 10 deletions custom_cards/custom_card_sisimomo_printer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,59 @@ The card has support any number of ink sensors under the state of the printer. T
Author: [Sisimomo](https://github.com/sisimomo) (based on [hiddevanbrussel pictures](https://community.home-assistant.io/t/lovelace-ui-minimalist/322687/203))
Version: 0.1.0

Contributors:

- [ByteFloater](https://github.com/bytefloater) Version 0.2.0

## Changelog

<details>
<summary>0.1.0</summary>
Initial release.
<details open>
<summary>0.1.0 - Initial Release</summary>

- Initial release

</details>
<details open>
<summary>0.2.0 - Added additional cases</summary>

- Added support for other cartridge types (tricolor)
- Added further error checking for previously uncaught states
- Added support for the IPP 'unavailable' state
- Added CSS for better theming of error screens
- Added card string translation files
- Changed `text-transform` of label to capitalize
- Changed `ulm_unavailable` to `ulm_translation_unavailable`
- Removed some unnecessary inline stylings
- Fixed the handling of unavailable and idle state styling

</details>

## Card options

| Options | Required | Notes |
| Options | Required | Description |
|--------------|------------------|----------------|
| entity | :material-check: | The entity_id for the large card |

## Variables

| Variable | Required | Notes |
| Variable | Required | Description |
|----------------------------------------|------------------|----------------|
| printer_name | :material-close: | If not provide, will use the friendly name of the provided entity |
| cartridges | :material-close: | A list of `Cartridge entity` object (see below) |
| printer_name | :material-close: | The chosen display name of the printer. <br> If not provided, will use the friendly name of the provided entity. |
| cartridges | :material-close: | A list of `Cartridge entity` objects. (See below) |

## Cartridge entity

| Variable | Required | Notes | Requirement |
| Variable | Required | Description | Requirement |
|------------|------------------|----------------|-------------|
| label | :material-check: | The label for the ink sensor. For better aesthetic, keep this string short eg: "BK", "Y", "M", "C", "PB" | |
| entity_id | :material-check: | The entity_id of the ink sensor | Must be a value between 0-100 (percentage) |
| color | :material-close: | The color of the ink bar | Must be a [CSS Legal Color Value](https://www.w3schools.com/cssref/css_colors_legal.asp). |
| entity_id | :material-check: | The entity_id of the ink sensor | Must be a value between 0-100 (percentage). |
| type | :material-close: | The type of cartridge associated with the ink sensor | Must be either 'unicolor' or 'tricolor'. <br> If not provided, 'unicolor' is assumed for backwards compatibility. |
| color | :material-check: | The color of the ink bar | For unicolor cartridges, must be a single [CSS Legal Color Value](https://www.w3schools.com/cssref/css_colors_legal.asp). For tricolor cartridges, 3 colours are required. (See usage for more info) |

## Usage

### Unicolor Printers

```yaml
- type: "custom:button-card"
template: "custom_card_sisimomo_printer"
Expand All @@ -56,24 +79,52 @@ Version: 0.1.0
cartridges:
- label: "BK"
entity_id: sensor.printer_black_ink
type: unicolor
color: "black"
- label: "B"
entity_id: sensor.printer_photo_black_ink
type: unicolor
color: "black"
- label: "Y"
entity_id: sensor.printer_yellow_ink
type: unicolor
color: "rgba(var(--color-yellow), 1)"
- label: "M"
entity_id: sensor.printer_magenta_ink
type: unicolor
color: "#F84B7A"
- label: "C"
entity_id: sensor.printer_cyan_ink
type: unicolor
color: "#427EDE"
- label: "PB"
entity_id: sensor.printer_photo_blue_ink
type: unicolor
color: "#9272BE"
```
### Tricolor Printers
```yaml
- type: "custom:button-card"
template: custom_card_sisimomo_printer
entity: sensor.canon_mg3600_series
variables:
ulm_card_printer_name: Canon MG3650
cartridges:
- label: "Col"
entity_id: sensor.canon_mg3600_series_black
type: tricolor
color:
- cyan
- magenta
- yellow
- label: "BK"
entity_id: sensor.canon_mg3600_series_black
type: unicolor
color: black
```
## Template code
??? note "Template Code"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
---
custom_card_sisimomo_printer:
template: "ulm_language_variables"
template:
- "ulm_translation_engine"
- "ulm_language_variables"
variables:
printer_name: "[[[ entity.attributes.friendly_name; ]]]"
ulm_idle: "idle"
show_icon: false
show_label: false
show_name: false
Expand All @@ -24,18 +29,24 @@ custom_card_sisimomo_printer:
type: "custom:button-card"
template: |
[[[
return entity.state.toLowerCase() != variables.ulm_idle && entity.state.toLowerCase() != variables.ulm_unavailable ? [ "icon_info", "blue_no_state" ] : [ "icon_info" ];
return (
entity.state.toLowerCase() != variables.ulm_idle.toLowerCase()
&& entity.state.toLowerCase() != variables.ulm_translation_unavailable.toLowerCase()
? [ "icon_info", "blue_no_state" ] : [ "icon_info" ]
);
]]]
tap_action:
action: "more-info"
label: "[[[ return entity.state; ]]]"
name: "[[[ return variables.printer_name !== undefined ? variables.printer_name : entity.attributes.friendly_name; ]]]"
name: "[[[ return variables.printer_name; ]]]"
entity: "[[[ return entity.entity_id; ]]]"
styles:
card:
- padding: "0"
- "--mdc-ripple-press-opacity": 0.12
- cursor: "pointer"
label:
- text-transform: "capitalize"
cartridges: |
[[[
// Source: https://stackoverflow.com/a/56266358
Expand All @@ -45,55 +56,115 @@ custom_card_sisimomo_printer:
return s.color !== '';
}
let toner_info_available = true;
if (variables.cartridges !== undefined ? Array.isArray(variables.cartridges) && variables.cartridges.length > 0 : false) {
let errorArray = [];
variables.cartridges.forEach(cartridge => {
let index = variables.cartridges.indexOf(cartridge);
let valid_cartridge_types = ['unicolor', 'tricolor']
// Confirm that the label is provided.
if (cartridge.label === undefined) {
errorArray.push(`cartridges.[${index}].label: You must provide a value.`);
}
// Confirm that the color is provided and is a valid color css.
if (cartridge.color === undefined) {
// Confirm that a valid cartridge type is provided, if not default to 'unicolor'
// for backwards compatibility with older configuration files
if (cartridge.type === undefined) {
cartridge.type = 'unicolor'
} else if (!valid_cartridge_types.includes(cartridge.type)) {
errorArray.push(`cartridges.[${index}].type: You must provide a valid cartridge type`);
}
// Confirm that the color is provided and is valid color css.
if (cartridge.color !== undefined) {
if (cartridge.type === 'unicolor') {
if (typeof cartridge.color === 'string' || cartridge.color instanceof String ? !isColor(cartridge.color) : false) {
errorArray.push(`cartridges.[${index}].color: You must provide a single valid CSS color value.`);
}
} else if (Array.isArray(cartridge.color) && cartridge.color.length === 3 ? cartridge.type === 'tricolor' : false) {
cartridge.color.forEach(color => {
let col_index = cartridge.color.indexOf(color);
if (!isColor(String(color))) {
errorArray.push(`cartridges.[${index}].color.[${col_index}]: You must provide a single valid CSS color value.`);
}
});
} else {
errorArray.push(`cartridges.[${index}].color: Invalid combination of colour and type.`);
}
} else {
errorArray.push(`cartridges.[${index}].color: You must provide a value.`);
} else if (!isColor(cartridge.color)) {
errorArray.push(`cartridges.[${index}].color: You must provide a valid css color value.`);
}
// Confirm that the entity_id is provided, is a valid entity_id, a integer and a value between 0 and 100 inclusively.
if (cartridge.entity_id === undefined) {
errorArray.push(`cartridges.[${index}].entity_id: You must provide a value.`);
} else if (states[cartridge.entity_id] === undefined) {
errorArray.push(`cartridges.[${index}].entity_id: You must provide a existing entity_id.`);
} else if (String(states[cartridge.entity_id].state).toLowerCase() === String(variables.ulm_translation_unavailable).toLowerCase()) {
toner_info_available = false;
} else if (isNaN(states[cartridge.entity_id].state) || typeof states[cartridge.entity_id].state === "boolean") {
errorArray.push(`cartridges.[${index}].entity_id: You must provide a entity representing an integer.`);
} else if (states[cartridge.entity_id].state < 0 || states[cartridge.entity_id].state > 100) {
errorArray.push(`cartridges.[${index}].entity_id: You must provide a entity representing an integer between 0 and 100 inclusively.`);
}
});
if (errorArray.length > 0) {
return `<div style="padding: 1em;background-color: rgba(219, 68, 55, 0.75);white-space: normal;">
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
<ul style="list-style: none;padding-left: 0;">
${errorArray.map(error => `<li style="margin-top: 0.5em;">${error}</li>`).join("")}
return `<div class="error-container">
<b>Configuration Error:</b>
<ul>
${errorArray.map(error => `<li>${error}</li>`).join("")}
</ul>
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
</div>`;
}
return '<div class="wrapper">' +
variables.cartridges.map(cartridge => {
return `<div class="label">${cartridge.label}</div>
<div class="container-bar">
<div class="bar" style="background-color: ${cartridge.color};width: ${states[cartridge.entity_id].state}%;"></div>
</div>
<div class="state">${states[cartridge.entity_id].state}%</div>`;
}).join("") +
'</div>';
if (toner_info_available) {
return '<div class="wrapper">' +
variables.cartridges.map(cartridge => {
if (cartridge.type === "unicolor") {
cartridge.bar_style = `
background-color: ${cartridge.color};
width: ${states[cartridge.entity_id].state}%;
`;
} else if (cartridge.type === "tricolor") {
cartridge.bar_style = `
background: linear-gradient(
180deg,
${cartridge.color[0]},
${cartridge.color[0]} 33%,
${cartridge.color[1]} 33%,
${cartridge.color[1]} 66%,
${cartridge.color[2]} 66%,
${cartridge.color[2]}
);
width: ${states[cartridge.entity_id].state}%;
`;
}
// Removes unnecessary whitespace from inline CSS
cartridge.bar_style = cartridge.bar_style.replace(/\s{2,}/g, '')
return `
<div class="label">${cartridge.label}</div>
<div class="container-bar">
<div class="bar" style="${cartridge.bar_style}"></div>
</div>
<div class="state">${states[cartridge.entity_id].state}%</div>
`;
}).join("") +
'</div>';
} else {
return `
<div class="info-unavailable">
Toner Information Unavailable
</div>
`;
}
} else {
}
]]]
style: |
/* Cartridge CSS */
div#cartridges .wrapper {
display: grid;
grid-template-columns: auto 1fr auto;
Expand All @@ -120,3 +191,32 @@ custom_card_sisimomo_printer:
filter: opacity(40%);
font-size: medium;
}
/* Error CSS */
div#cartridges .error-container {
text-align: left;
font-size: 75%;
font-family: var(--code-font-family, monospace);
padding: 10px;
background-color: rgba(219, 68, 55, 0.75);
margin-top:10px;
border-radius:8px;
}
div#cartridges .error-container ul {
list-style: none;
padding: 0;
margin: 0;
overflow-wrap: break-word;
word-wrap: break-word;
white-space: normal !important;
}
div#cartridges .error-container ul li {
margin-top: 0.5em;
}
div#cartridges .info-unavailable {
padding: 1em;
white-space: normal;
margin-top:10px;
border-radius:8px;
opacity: 60%;
}

0 comments on commit 458585d

Please sign in to comment.