For a long time I used a template that calculated extra print costs (1 euro) for every 10 pages ( = one block) I printed to much, now my printer cost for extra pages went from 1 euro to 1.5 euro.
The template uses an input number that I set in my lovelace.
# The cost of each overprint block, in £
# SET THIS ACCORDING TO YOUR PLAN
hp_printer_pages_overprint_block_cost:
name: "HP Printer - Over Print Block Cost"
min: 0
max: 50
step: 0.01
unit_of_measurement: "EUR"
icon: "mdi:currency-eur"
mode: box
I have changes the input from 1 to 1.5, however the calculation keep setting +1 for every 10 pages (1 block) for overprinting instead of + 1.5.
can someone see whats wrong in this template?
# The cost so far of the pages that have been printed over the standard Available plus Rollover Available
# Calculated when each page is printed, and at the start of each new Instant Ink period
# CHANGE THE CURRENCY CODE AS APPROPRIATE
- name: "HP Printer - Pages Overprint Cost"
unique_id: "template_hp_printer_pages_overprint_cost"
unit_of_measurement: "EUR"
device_class: monetary
state_class: total
icon: "mdi:currency-eur"
state: >
{% if states('sensor.hp_printer_pages_total_printed') or states('input_datetime.hp_printer_this_period_start_date') %}
{% if states('sensor.hp_printer_pages_overprint') | int == 0 %}
0
{% elif states('sensor.hp_printer_pages_overprint') | int > 0 and ( (states('sensor.hp_printer_pages_overprint') | int - 1) % states('input_number.hp_printer_pages_overprint_block_size') | int == 0 ) %}
{{ (1 + ((states('sensor.hp_printer_pages_overprint') | int - 1) / states('input_number.hp_printer_pages_overprint_block_size') | int)) | multiply( states('input_number.hp_printer_pages_overprint_block_cost') | int) | int }}
{% else %}
{{ (1 + ((states('sensor.hp_printer_pages_overprint') | int - 1) / states('input_number.hp_printer_pages_overprint_block_size') | int)) | multiply( states('input_number.hp_printer_pages_overprint_block_cost') | int) | int }}
{% endif %}
{% endif %}
availability: >
{{ is_number(states('sensor.hp_printer_pages_total_printed'))
and has_value('input_datetime.hp_printer_this_period_start_date')
and is_number(states('sensor.hp_printer_pages_overprint'))
and is_number(states('input_number.hp_printer_pages_overprint_block_size'))
and is_number(states('input_number.hp_printer_pages_overprint_block_cost')) }}
Using int definitely won’t work: that’ll turn 1.5 into 1.
Your template is overly long and complicated. Please explain in simple words what each of the entities represents and what the template needs to return.
I think it reduces to something like this, as your {% elif %} and {% else %} templates are identical. You probably don’t need the two branches at all but I cba to figure it out.
state: >
{% set printed = states('sensor.hp_printer_pages_total_printed') %}
{% set start_date = states('input_datetime.hp_printer_this_period_start_date') %}
{% set overprint = states('sensor.hp_printer_pages_overprint')|int(0) %}
{% set op_block_size = states('input_number.hp_printer_pages_overprint_block_size')|int(0) %}
{% set op_block_cost = states('input_number.hp_printer_pages_overprint_block_cost')|float(0) %}
{% if printed or start_date %}
{% if overprint == 0 %}
0
{% else %}
(1 + ((overprint - 1) / op_block_size)|int * op_block_cost %}
{% endif %}
{% endif %}
It is part of a whole package (i will place the code below).
Please explain in simple words what each of the entities represents and what the template needs to return.
I have a print plan with 50 page a month, when I ‘overprint’ above those 50 I always paid 1,- extra costs, the price is now changed to 1,5 and as of this my old template does not work anymore, I have changed the op_block_cost to 1,5 but it still rounds to 1, 2, 3 (or 1.0, 2.0, 3.0 now)
The op_block_size is the amount of pages (for example 10 pages should add 1,5 euro extra to the op_block_cost)
---
#
# /config/integrations/custom_packages/hp_printer/instant_ink_print_plan.yaml
#
##################################################################################################################
# Inputs
##################################################################################################################
# Inputs for the HP Ink Print Plan
input_number:
# The total number of pages that had been printed at the start of this period of the printing plan
# Set by an automation
hp_printer_pages_printed_at_month_start:
name: "HP Printer - Pages Printed at month start"
min: 0
max: 50000
step: 1
icon: "mdi:printer"
mode: box
# The current monthly allowance number of pages
# SET THIS ONCE FOR THE INAUGURAL RUN, and after then it is set by an automation
hp_printer_pages_monthly_available:
name: "HP Printer - Monthly Pages Available in Plan"
min: 15
max: 500
step: 1
icon: "mdi:printer"
mode: box
# The number of pages that remain of the rollover allowance for this month
# SET THIS ONCE FOR THE INAUGURAL RUN, and after then it is set by an automation
hp_printer_pages_rollover_available:
name: "HP Printer - Available Rollover Pages"
min: 0
max: 600
step: 1
icon: "mdi:printer"
mode: box
# The maximum number of rollover pages allowed.
# SET THIS ACCORDING TO YOUR PLAN
hp_printer_pages_rollover_monthly_max:
name: "HP Printer - Monthly Maximum Rollover Pages"
min: 0
max: 600
step: 1
icon: "mdi:printer"
mode: box
# The number of pages in each overprint block, when
# the Monthly Allowance plus Rollover are exceeded
# SET THIS ACCORDING TO YOUR PLAN
hp_printer_pages_overprint_block_size:
name: "HP Printer - Over Print Block Size"
min: 0
max: 100
step: 1
icon: "mdi:printer"
mode: box
# The cost of each overprint block, in €
# SET THIS ACCORDING TO YOUR PLAN
hp_printer_pages_overprint_block_cost:
name: "HP Printer - Over Print Block Cost"
min: 0
max: 50
step: 0.01
unit_of_measurement: "EUR"
icon: "mdi:currency-eur"
mode: box
# The number of total available pages remaining to trigger a notification
hp_printer_pages_total_remaining_notification:
name: "HP Printer - Pages Notification"
min: 1
max: 100
step: 1
icon: "mdi:printer"
mode: box
##################################################################################################################
# Input DateTime
##################################################################################################################
input_datetime:
# The start date of this period of the print plan
# SET THIS ONCE FOR THE INAUGURAL RUN, and after then it is set by an automation
hp_printer_this_period_start_date:
name: "HP Printer - This Period Start Date"
has_date: true
has_time: false
icon: "mdi:calendar"
##################################################################################################################
# Input Select
##################################################################################################################
input_select:
# SET THIS ACCORDING TO YOUR PLAN
hp_printer_print_plan:
name: "HP Printer - Print Plan"
options:
- Free
- Paid
initial: Paid
icon: "mdi:printer"
##################################################################################################################
# Template Sensor
##################################################################################################################
template:
# Energie DSMR Readings and Prices
- sensor:
# The number of standaard available pages remaining for this period
# Calculated when each page is printed, and at the start of each new Instant Ink period
- name: "HP Printer - Pages Available Remaining"
unique_id: "template_hp_printer_pages_available_remaining"
icon: "mdi:file-outline"
state: >
{% if states('input_datetime.hp_printer_this_period_start_date') %}
{% if states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int - states('sensor.hp_printer_pages_total_printed') | int >= 0 %}
{{ states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int - states('sensor.hp_printer_pages_total_printed') | int }}
{% else %}
0
{% endif %}
{% endif %}
availability: >
{{ has_value('input_datetime.hp_printer_this_period_start_date')
and is_number(states('input_number.hp_printer_pages_printed_at_month_start'))
and is_number(states('input_number.hp_printer_pages_monthly_available'))
and is_number(states('sensor.hp_printer_pages_total_printed')) }}
# The number of rollover pages remaining for this period.
# Calculated when each page is printed, when the Rollover Pages reset, and at the start of each new Instant Ink period
- name: "HP Printer - Pages Rollover Remaining"
unique_id: "template_hp_printer_pages_rollover_remaining"
icon: "mdi:note-plus-outline"
state: >
{% if states('input_datetime.hp_printer_this_period_start_date') %}
{% if states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int - states('sensor.hp_printer_pages_total_printed') | int < 0 and states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int + states('input_number.hp_printer_pages_rollover_available') | int - states('sensor.hp_printer_pages_total_printed') | int >= 0 %}
{{ states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int + states('input_number.hp_printer_pages_rollover_available') | int - states('sensor.hp_printer_pages_total_printed') | int }}
{% elif states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int - states('sensor.hp_printer_pages_total_printed') | int < 0 and states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int + states('input_number.hp_printer_pages_rollover_available') | int - states('sensor.hp_printer_pages_total_printed') | int < 0 %}
0
{% else %}
{{ states('input_number.hp_printer_pages_rollover_available') | int }}
{% endif %}
{% endif %}
availability: >
{{ has_value('input_datetime.hp_printer_this_period_start_date')
and is_number(states('input_number.hp_printer_pages_printed_at_month_start'))
and is_number(states('input_number.hp_printer_pages_monthly_available'))
and is_number(states('sensor.hp_printer_pages_total_printed'))
and is_number(states('input_number.hp_printer_pages_rollover_available')) }}
# Total number of bundled plus rollover pages remainig for this period
- name: "HP Printer - Pages Total Remaining"
unique_id: "template_hp_printer_pages_total_remaining"
icon: "mdi:file-check-outline"
state: "{{ states('sensor.hp_printer_pages_available_remaining') | int + states('sensor.hp_printer_pages_rollover_remaining') | int }}"
availability: >
{{ is_number(states('sensor.hp_printer_pages_available_remaining'))
and is_number(states('sensor.hp_printer_pages_rollover_remaining')) }}
# The number pages printed over and above the Monthly Available plus the Rollover Available
# Calculated when each page is printed, and at the start of each new Instant Ink period
- name: "HP Printer - Pages Overprint"
unique_id: "template_hp_printer_pages_overprint"
icon: "mdi:text-box-remove"
state: >
{% if states('input_datetime.hp_printer_this_period_start_date') %}
{% if states('input_number.hp_printer_pages_printed_at_month_start') | int + states('input_number.hp_printer_pages_monthly_available') | int + states('input_number.hp_printer_pages_rollover_available') | int < states('sensor.hp_printer_pages_total_printed') | int %}
{{ states('sensor.hp_printer_pages_total_printed') | int - states('input_number.hp_printer_pages_rollover_available') | int - states('input_number.hp_printer_pages_monthly_available') | int - states('input_number.hp_printer_pages_printed_at_month_start') | int }}
{% else %}
0
{% endif %}
{% endif %}
availability: >
{{ has_value('input_datetime.hp_printer_this_period_start_date')
and is_number(states('input_number.hp_printer_pages_printed_at_month_start'))
and is_number(states('input_number.hp_printer_pages_monthly_available'))
and is_number(states('input_number.hp_printer_pages_rollover_available'))
and is_number(states('sensor.hp_printer_pages_total_printed')) }}
# The cost so far of the pages that have been printed over the standard Available plus Rollover Available
# Calculated when each page is printed, and at the start of each new Instant Ink period
# CHANGE THE CURRENCY CODE AS APPROPRIATE
- name: "HP Printer - Pages Overprint Cost"
unique_id: "template_hp_printer_pages_overprint_cost"
unit_of_measurement: "EUR"
device_class: monetary
state_class: total
icon: "mdi:currency-eur"
state: >
{% if states('sensor.hp_printer_pages_total_printed') or states('input_datetime.hp_printer_this_period_start_date') %}
{% if states('sensor.hp_printer_pages_overprint')|int(0) == 0 %}
0
{% else %}
{{ (1 + ((states('sensor.hp_printer_pages_overprint')|int(0) - 1) / states('input_number.hp_printer_pages_overprint_block_size')|int(0))|int * states('input_number.hp_printer_pages_overprint_block_cost')|float(0)) }}
{% endif %}
{% endif %}
availability: >
{{ is_number(states('sensor.hp_printer_pages_total_printed'))
and has_value('input_datetime.hp_printer_this_period_start_date')
and is_number(states('sensor.hp_printer_pages_overprint'))
and is_number(states('input_number.hp_printer_pages_overprint_block_size'))
and is_number(states('input_number.hp_printer_pages_overprint_block_cost')) }}
# The number of pages remaining for this month in the chargeable Over Printed area
- name: "HP Printer - Pages Overprint Remaining"
unique_id: "template_hp_printer_pages_overprint_remaining"
icon: "mdi:note-alert"
state: >
{% if states('sensor.hp_printer_pages_overprint') | int == 0 or (states('sensor.hp_printer_pages_overprint') | int % states('input_number.hp_printer_pages_overprint_block_size') | int == 0) %}
0
{% else %}
{{ states('input_number.hp_printer_pages_overprint_block_size') | int - (states('sensor.hp_printer_pages_overprint') | int % states('input_number.hp_printer_pages_overprint_block_size') | int) }}
{% endif %}
availability: >
{{ is_number(states('sensor.hp_printer_pages_overprint'))
and is_number(states('input_number.hp_printer_pages_overprint_block_size')) }}
# Next Renewal Date
# WILL NOT WORK FOR 29th, 30th, 31st OF THE MONTH
# The number of pages remaining for this month in the chargeable Over Printed area
- name: "HP Printer - Next Renewal Date"
icon: "mdi:calendar-start"
unique_id: "template_hp_printer_next_renewal_date"
state: >
{% if (states('input_datetime.hp_printer_this_period_start_date').split("-") [1] | int + 1 > 12) %}
{{ (states('input_datetime.hp_printer_this_period_start_date').split("-") [0] | int + 1) | string + "-01-" + states('input_datetime.hp_printer_this_period_start_date').split("-") [2] }}
{% else %}
{{ states('input_datetime.hp_printer_this_period_start_date').split("-") [0] | int | string + "-" + ('%02d' % (states('input_datetime.hp_printer_this_period_start_date').split("-") [1] | int + 1)) + "-" + states('input_datetime.hp_printer_this_period_start_date').split("-") [2] }}
{% endif %}
availability: "{{ has_value('input_datetime.hp_printer_this_period_start_date') }}"
# Used to track days remaining of HP Ink Printer Pages period
# Needs to have the date sensors installed as per: https://www.home-assistant.io/integrations
# Use of sensor.date ought to force a daily update, according to https://www.home-assistant.io/integrations/template/
- name: "HP Printer - This Period Days Remaining"
unique_id: "template_hp_printer_this_period_days_remaining"
icon: "mdi:calendar-clock"
state: "{% set dt = states('sensor.hp_printer_next_renewal_date') | as_datetime or today_at() %} {{ (dt | as_local - today_at()).days }}"
availability: "{{ has_value('sensor.hp_printer_next_renewal_date') }}"
# Makes use of HP Printer integration: https://github.com/elad-bar/ha-hpprinter
# Convert the total pages printed from sensor.hp_printer_printer_totaal_aantal_pagina_s to a useable value
- name: "HP Printer - Pages Total Printed"
unique_id: "template_hp_printer_pages_total_printed"
icon: "mdi:file-document-check"
state: "{{ states('sensor.envy_inspire_7200e_all_in_one_printer_series_192_168_20_21_printer_totaal_aantal_pagina_s') | int }}"
availability: "{{ is_number(states('sensor.envy_inspire_7200e_all_in_one_printer_series_192_168_20_21_printer_totaal_aantal_pagina_s')) }}"
##
## ONLY if you can not use the HP Printer integration: https://github.com/elad-bar/ha-hpprinter
##
## Updated to UI or use MultiScrape (Install via HACS)
##
##multiscrape:
## - name: "HP Printer Scraper"
## resource: "http://192.168.20.21/DevMgmt/ProductUsageDyn.xml"
## scan_interval: 60
## verify_ssl: false
## sensor:
## - name: "HP ENVY 7220e Total Pages Printed"
## unique_id: "multiscrape_hp_printer_pages_total_printed"
## select: 'dd\:TotalImpressions[PEID="5082"]'
## value_template: >-
## {% if value == "" %}
## 0
## {% else %}
## {{ value }}
## {% endif %}
##################################################################################################################
# Binary Sensors
##################################################################################################################
## ONLY if you can not use the HP Printer integration: https://github.com/elad-bar/ha-hpprinter
## Set via UI ##
## Ping the Printer ##
##binary_sensor:
## - platform: ping
## host: 192.168.20.21
## name: "hp-envy-7220e"
## count: 2
## scan_interval: 30
##
##################################################################################################################
# Automations
##################################################################################################################
automation:
# Reset Pages at new Period
- id: "automation_printer_page_reset"
alias: "Printer - Page Reset"
description: >
Sets: - Total number of pages printed at the start of the period -
Start Date of this period (to store a date to calculate the next one) - Maximum
Rollover Allowance value for this month - Rollover Remaining to new Maximum Rollover
Allowance value for this month - Rollover from overprint pages.
triggers:
- trigger: time
at: "00:00:00"
conditions:
- condition: template
value_template: "{{ now().day | int == states('input_datetime.hp_printer_this_period_start_date') [-2:] | int }}"
actions:
- action: input_number.set_value
target:
entity_id: input_number.hp_printer_pages_rollover_available
data_template:
value:
"{% if is_state('input_select.hp_printer_print_plan' , 'Free') %}
{% if states('sensor.hp_printer_pages_overprint_remaining') | int > 0 %}
{{ states('sensor.hp_printer_pages_overprint_remaining') | int }}
{% else %}
{{ states('sensor.hp_printer_pages_rollover_remaining') | int }}
{% endif %}
{% else %}
{% if states('sensor.hp_printer_pages_overprint') | int > 0 and (states('sensor.hp_printer_pages_overprint') | int % states('input_number.hp_printer_pages_overprint_block_size') | int) > 0 %}
{{ states('input_number.hp_printer_pages_overprint_block_size') | int - (states('sensor.hp_printer_pages_overprint') | int % states('input_number.hp_printer_pages_overprint_block_size') | int) }}
{% elif states('sensor.hp_printer_pages_total_remaining')|int > states('input_number.hp_printer_pages_rollover_monthly_max') | int %}
{{ states('input_number.hp_printer_pages_rollover_monthly_max') | int }}
{% else %}
{{ states('sensor.hp_printer_pages_total_remaining') | int }}
{% endif %}
{% endif %}"
- action: input_number.set_value
target:
entity_id: input_number.hp_printer_pages_printed_at_month_start
data_template:
value: "{{ states('sensor.hp_printer_pages_total_printed') }}"
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.hp_printer_this_period_start_date
data_template:
date: "{{ states('sensor.date') }}"
``
Put the whole template that isn’t giving the desired result (the bit under state:) into Developer Tools / Template and work on it there.
You have a lot of |int filters in your templates, so I’m not surprised it’s rounding. A blanket change to |float might be a good starting point to see if that fixes it, then you can revert the true integers (like page counts).
I replaced all sensors with values, and it seems something is wrong or wrong formatted in the calculation. When i round the multiply to 1 or 2 or 3 it works, but not with .5
Float / int makes no difference, always a wrong result with .5
You do not need most of those ints and floats. 55 is already a number: 55|int does nothing.
The only time you need to use those are to convert entity states, which are always strings, into numbers.
In your third example, both your elif and your else templates end with an int.
Your calculations are still too complex for me to work out what’s going on. Try replacing each entity with a variable name like in my first response above. By putting the appropriate ints and floats at that level, you then don’t need them in the calculations.