Hi,
Inspired by the posts above, I made an implementation of Instant Ink which should cover the monthly allowance, rollover and over-print scenarios. It uses only native HA components: sensors, input_date, input_number, and an automation.
Edit: Updates are available below, for
- The Automation that resets and rolls-over values on the anniversary day.
- Template Sensors, to remove the dependency on the deprecated ‘entity_id’ attribute.
- Another option to calculate the next month renewal date (useful in HASSOS).
Also note that if your renewal date is on the 29th, 30th, or 31st, of the month, the ‘Next Renewal Date’ calculation will go askew where the number of days in the next month is less than that date - Feel free to offer a fix!
It all hangs off a page of XML that’s provided by the printer - which I suspect is used by HP for the same purpose - and is found at: http://[Printer IP]/DevMgmt/ProductUsageDyn.xml.
Diving into the configuration, I have base information in input_number and input_datetime objects, which allows them to be set using cards in the front end of Home Assistant:
# 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 the automation - id: '1588925532080'; alias: HP Envy 5540 Page Reset.
hp_envy_5540_pages_at_month_start:
name: Printed Pages Total at month start
min: 500
max: 10000
step: 1
icon: mdi:printer
mode: box
# The current monthly allowance number of pages
# Set manually in a front-end card
hp_envy_5540_pages_monthly_allowance:
name: Monthly Allowance Pages
min: 15
max: 300
step: 5
icon: mdi:printer
mode: box
# The maximum number of rollover pages allowed
# Set manually in a front-end card
hp_envy_5540_pages_rollover_monthly_max_allowance:
name: Rollover Maximum Pages
min: 0
max: 600
step: 5
icon: mdi:printer
mode: box
# The rollover allowance for this month
# Set by the automation - id: '1588925532080'; alias: HP Envy 5540 Page Reset.
hp_envy_5540_pages_rollover_allowance:
name: Rollover Allowance Pages
min: 0
max: 600
step: 5
icon: mdi:printer
mode: box
# The number of pages in each overprint block, when the Monthly Allowance plus Rollover are exceeded
# Set manually in a front-end card
hp_envy_5540_pages_overprint_block_size:
name: Over Print Block Size
min: 0
max: 100
step: 5
icon: mdi:printer
mode: box
# The cost of each overprint block, as a decimal
# Set manually in a front-end card
hp_envy_5540_pages_overprint_block_cost:
name: Over Print Block Cost
min: 0
max: 50
step: 0.05
icon: mdi:currency-gbp
mode: box
# The start date of this period of the print plan
# Set by the automation - id: '1588925532080'; alias: HP Envy 5540 Page Reset.
input_datetime:
hp_envy_5540_this_period_start_date:
name: This Period Start Date
has_date: true
has_time: false
icon: mdi:calendar
Here I have some sensors to detect the total number of pages printed (using the printer’s XML service), and the next period renewal date. Note that I have my sensors in a separate config file from configuration.yaml.
# Gets the HP Printer Total Pages Printed from the printer's web service
# Needs package, 'xml-twig-tools', to be installed in Raspbian
# Inspired by: https://community.home-assistant.io/t/command-line-sensor-with-a-value-template-struggling/125957/3
- platform: command_line
name: "HP Envy 5540 Total Pages Printed"
command: "xml_grep 'dd:TotalImpressions[@PEID=\"5082\"]' http://<Printer IP>/DevMgmt/ProductUsageDyn.xml --text_only"
value_template: "{{ value }}"
#
# Gets the HP Ink Next Allowance Period Start Date, using the command line to do the calculation.
# The command line method is simpler for handling date arithmetic
- platform: command_line
name: "HP Envy 5540 Next Renewal Date"
command: "date -d '{{ states('input_datetime.hp_envy_5540_this_period_start_date') }} 1 month' +%Y-%m-%d"
value_template: "{{ value }}"
#
Now come the sensors to detect the number of pages remaining in the various buckets.
Generally the calculations are along the lines of:
‘Number of pages printed at the start of the period’
plus ‘Number of pages of this month’s allowance’
[plus ‘Number of pages of this month’s rollover allowance’]
minus ‘Number of pages printed right now’
# 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/time_date/
# Use of sensor.date forces a daily update
hp_envy_5540_allowance_days_remaining:
friendly_name: "Allowance Days Remaining"
value_template: >-
{{ ((as_timestamp(strptime(states('sensor.hp_envy_5540_next_renewal_date'), '%Y-%m-%d'))|int - as_timestamp(strptime(states('sensor.date'), '%Y-%m-%d'))|int ) / 86400)|int }}
#
# The number of allowance pages remaining for this period
# Calculated when each page is printed, and at the start of each new Instant Ink period
hp_envy_5540_pages_allowance_remaining:
friendly_name: "Allowance Pages Remaining"
value_template: >-
{% if states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int >= 0 %}
{{ states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int }}
{% else %}
0
{% endif %}
entity_id: sensor.hp_envy_5540_total_pages_printed,input_datetime.hp_envy_5540_this_period_start_date
#
# The number of rollover pages remaining for this period.
# Calculated when each page is printed, when the Rollover Allowance is reset, and at the start of each new Instant Ink period
hp_envy_5540_pages_rollover_remaining:
friendly_name: "Rollover Pages Remaining"
value_template: >-
{% if states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int < 0 and states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int + states('input_number.hp_envy_5540_pages_rollover_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int >= 0 %}
{{ states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int + states('input_number.hp_envy_5540_pages_rollover_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int }}
{% elif states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int < 0 and states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int + states('input_number.hp_envy_5540_pages_rollover_allowance')|int - states('sensor.hp_envy_5540_total_pages_printed')|int < 0 %}
0
{% elif 1==1 %}
{{ states('input_number.hp_envy_5540_pages_rollover_allowance')|int }}
{% endif %}
entity_id: sensor.hp_envy_5540_total_pages_printed,input_datetime.hp_envy_5540_this_period_start_date
#
# The number pages printed over and above the Monthly Allowance plus the Rollover Allowance
# Calculated when each page is printed, and at the start of each new Instant Ink period
hp_envy_5540_pages_overprint:
friendly_name: "Over Allowance Prints"
value_template: >-
{% if states('input_number.hp_envy_5540_pages_at_month_start')|int + states('input_number.hp_envy_5540_pages_monthly_allowance')|int + states('input_number.hp_envy_5540_pages_rollover_allowance')|int < states('sensor.hp_envy_5540_total_pages_printed')|int %}
{{ states('sensor.hp_envy_5540_total_pages_printed')|int - states('input_number.hp_envy_5540_pages_rollover_allowance')|int - states('input_number.hp_envy_5540_pages_monthly_allowance')|int - states('input_number.hp_envy_5540_pages_at_month_start')|int }}
{% else %}
0
{% endif %}
entity_id: sensor.hp_envy_5540_total_pages_printed,input_datetime.hp_envy_5540_this_period_start_date
#
# The cost so far of the pages that have been printed over the Allowance plus Rollover
# Calculated when each page is printed, and at the start of each new Instant Ink period
hp_envy_5540_pages_overprint_cost:
friendly_name: "Over Allowance Cost"
value_template: >-
{% if states('sensor.hp_envy_5540_pages_overprint')|int > 0 %}
{{ (1 + (states('sensor.hp_envy_5540_pages_overprint')|int / states('input_number.hp_envy_5540_pages_overprint_block_size')|int)) | multiply( states('input_number.hp_envy_5540_pages_overprint_block_cost')|int)|int }}
{% else %}
0
{% endif %}
entity_id: sensor.hp_envy_5540_total_pages_printed,input_datetime.hp_envy_5540_this_period_start_date
Finally, there’s an automation which runs at the start of each ink period, which here is the 3rd day of the month. This cannot be edited in the front end.
- id: '1582325531280'
alias: HP Envy 5540 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'
trigger:
- at: 00:00:00
platform: time
condition:
- condition: template
value_template: '{{ now().day|int == states(''input_datetime.hp_envy_5540_this_period_start_date'')[-2:]|int }}'
action:
- service: input_number.set_value
entity_id: input_number.hp_envy_5540_pages_at_month_start
data_template:
value: '{{ states(''sensor.hp_envy_5540_total_pages_printed'') }}'
- service: input_datetime.set_datetime
entity_id: input_datetime.hp_envy_5540_this_period_start_date
data_template:
date: '{{ states(''sensor.date'') }}'
- service: input_number.set_value
entity_id: input_number.hp_envy_5540_pages_rollover_allowance
data_template:
value: "{% if states('sensor.hp_envy_5540_pages_allowance_remaining')|int +\
\ states('sensor.hp_envy_5540_pages_rollover_remaining')|int > states('input_number.hp_envy_5540_pages_rollover_monthly_max_allowance')|int\
\ %}\n {{ states('input_number.hp_envy_5540_pages_rollover_monthly_max_allowance')|int\
\ }}\n{% else %}\n {{ states('sensor.hp_envy_5540_pages_allowance_remaining')|int\
\ + states('sensor.hp_envy_5540_pages_rollover_remaining')|int }}\n{% endif\
\ %}"
Earlier I mentioned a card that can be placed on the front end, and here it is:
cards:
- entities:
- entity: input_datetime.hp_envy_5540_this_period_start_date
- entity: input_number.hp_envy_5540_pages_at_month_start
- entity: input_number.hp_envy_5540_pages_monthly_allowance
- entity: input_number.hp_envy_5540_pages_rollover_allowance
- entity: input_number.hp_envy_5540_pages_overprint_block_size
- entity: input_number.hp_envy_5540_pages_overprint_block_cost
title: HP Envy 5540 Instant Ink Configuration
type: entities
type: vertical-stack
And to display the current values…
cards:
- entities:
- entity: sensor.hp_envy_5540_allowance_days_remaining
- entity: sensor.hp_envy_5540_pages_allowance_remaining
- entity: sensor.hp_envy_5540_pages_rollover_remaining
- entity: sensor.hp_envy_5540_pages_overprint
- entity: sensor.hp_envy_5540_pages_overprint_cost
title: HP Envy 5540 Instant Ink Status
type: entities
type: vertical-stack
So hopefully this will help some folks.
Also hopefully there are no bugs or typos!