What is Grocy?
If you're running HASS IO, you may have seen an add-on from Franck called Grocy. This little gem is a stock management system for the home. Grocy allows you to know how much of a product you have at home, and to track when items are due to expire. For example how many litres of milk you have at home, and when it will expire.
The recipes feature of Grocy is where it all comes together. Once you put in the ingredients required for a meal, Grocy can tell you what ingredients you have on hand to make that meal, or allow you to add missing items to the shopping list. When you cook a recipe, by the click of a button, Grocy will reduce the stock levels of those products and keep track of your remaining stock.
For those times when you don't use a fixed recipe, there is also the ability to "consume" items in Grocy. This is where you can tell Grocy you just drank a can of Fosters, so it knows how much you have left in stock.
For the most part this is great, but if you want to take full advantage of Grocy it does require you to login and track your usage of items regularly. This can get quite annoying if you need to open your phone each time you use an egg from the fridge or wake up in the night for a glass of milk. This is where we can leverage our smart home controller, in my case Home Assistant, to automate the consumption of items in Grocy.
Together with Rohan Karamandi, hear me break down the latest Home Assistant release and talk with other users of Home Assistant across the open-source community.
Setting up Home Assistant
One of the things I love about Home Assistant is its flexibility to integrate with other systems and software. There's a whole bunch of ways to integrate things, from HTTP with REST sensors and switches, to MQTT.
To make things easier, I'm going to use a Shell Command, which will make a cURL request to the Grocy REST API to consume an item. I want to be able to re-use as much code as possible, so I'm going to use template data to dynamically send data to this cURL request. This will come in handy later.
To begin, lets start with our shell command, and I'll explain what this is doing.
shell_command:
grocy_consume_item: "curl -X POST http://{{server_ip}}:9283/api/stock/products/{{product_id}}/consume -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'GROCY-API-KEY: {{grocy_key}}' -H 'cache-control: no-cache' -d '{ \"amount\": {{amount}}, \"transaction_type\": \"consume\", \"spoiled\": false }'"
In this command, I've got some parameters wrapped in {{brackets}}. These will allow us to use the same shell command in our scripts and automations moving forward. Let's break down these parameters.
We'll use this shell command throughout the next few scenarios.
{{server_ip}} | The IP address of the server where Grocy is running. If running on the same machine as Home Assistant, this could be 127.0.0.1 |
---|---|
{{PRODUCT_ID}} | The Grocy ID of the product to be consumed. You can get this from the URL of the edit product page inside Grocy. |
{{grocy_key}} | The API key for your Grocy install. Get this from your Grocy settings page |
{{AMOUNT}} | The amount you wish to consume. This depends on the product. |
Dishwashing Tablets
If you've previously read my blog on making dishwashers and washing machines smart, you'll know that my smart home knows the state of my dishwasher. This means that my home also knows when we start the dishwasher.
With this information, we can get Home Assistant to tell Grocy when we have used a dishwashing tablet.

Setting up Grocy
First we need to create a product in Grocy for dishwashing tablets. For this I've created a new Quantity Unit called tablet. Once I've created a product in Grocy, I then use the inventory to record how many dishwashing tablets I have in the house.

There's a couple of things going on in this screenshot, so let me explain.
The minimum stock amount is defined when you create your item in Grocy. Once I have less than 60 dishwashing tablets in stock, Grocy will mark the item as low in stock and prompt me to add this to my shopping list.
Next up is the QU Purchase or Quantity Purchase. Here you'll notice I've created a Quantity Unit in Grocy called 80pk Box. This is because you don't go to the supermarket and ask for 1 dishwashing tablet. You buy them in packs. For me, the brand I like to use always comes in an 80pk box. For this reason, the QU Factor is set to 80. This means when I purchase 1 box of dishwashing tablets, Grocy will automatically add 80 tablets in stock.
Finally the Product Group is handy for the shopping list feature. Items will be grouped together nicely, so when you're in the supermarket you can have your shopping list arranged into the aisles.
Once we've created the product we can use the Inventory feature of Grocy to tell Grocy how many tablets we have in stock already. Once Grocy knows how many dishwashing tablets are in the house, its time to tell Home Assistant to consume (remove 1 tablet from stock) each time the dishwasher starts.
Home Assistant
To start off simple, each time my dishwasher goes into the Running state, I want Home Assistant to remove 1 tablet from Grocy. To do that, I'll use the following automation.
#dishwasher.yaml
- alias: Dishwasher consume tablet running
trigger:
- platform: state
entity_id: sensor.dishwasher_status
to: 'Running'
action:
- service: shell_command.grocy_consume_item
data:
server_ip: 127.0.0.1
grocy_key: GROCY123APIKEY
product_id: 59
amount: 1
Pretty basic, right? Using those template variables in the shell command, we can also use Home Assistant secrets as variables. This way if your product ID for dishwashing tablets changes in the future, you've just got one place to update.
Although now I have a problem. Let's take a look at the diagram from my Dishwasher state automation.

In this diagram, we can see that the state can go back to Running in the middle of a cycle. This means each time the power drops and comes back up, Home Assistant will remove a dishwashing tablet from my stock, even though I haven't put another tablet in the dishwasher.
I need to stop this from happening. So let's go ahead and make a small change to our automation above.
#dishwasher.yaml
- alias: Dishwasher consume tablet running
trigger:
- platform: state
entity_id: sensor.dishwasher_status
to: 'Running'
action:
- service: shell_command.grocy_consume_item
data:
server_ip: 127.0.0.1
grocy_key: GROCY
product_id: 59
amount: 1
- service: homeassistant.turn_off
entity_id: automation.dishwasher_consume_tablet_running
This will turn the automation off once it has been run. Now we need another automation to turn this back on once the dishwasher door has been opened.
#dishwasher.yaml
- alias: Dishwasher consume tablet enable
trigger:
- platform: state
entity_id: sensor.dishwasher_status
to: Dirty
condition:
condition: and
conditions:
- condition: state
entity_id: sensor.dishwasher_status
state: Dirty
- condition: state
entity_id: automation.dishwasher_consume_tablet_running
state: 'off'
action:
- service: homeassistant.turn_on
entity_id: automation.dishwasher_consume_tablet_running
Now Home Assistant will automatically remove a dishwashing tablet from my stock levels when the dishwasher is run. Grocy will prompt me to buy tablets when stock levels get below my set threshold.
Washing Machine
So the dishwasher was pretty simple. But what about something a tiny bit more complicated? The washing machine needs to manage two items. Washing Powder and Fabric Softener. However unlike the dIshwasher, these are different amounts. Washing powder is measured in weight, whilst the Fabric Softener is measured in litres.
This makes things slightly tricky. For my washing powder, I can easily use a kitchen scale to weigh how much a scoop of powder consumes. Luckily for the liquid, it mentions there are 25 washes in the bottle. Using this, we can do some maths to work out how much Home Assistant should subtract each time the washing machine is turned on.
2000ml / 25 washes = 80ml per wash
From there, we can then plug these into our Home Assistant automations.
#washing.yaml
- alias: Washing Machine Powder Consume
trigger:
- platform: state
entity_id: sensor.washing_machine_status
to: 'Running'
action:
# Consume washing detergent / fabric softener
- service: shell_command.grocy_consume_item
data:
server_ip: 127.0.0.1
grocy_key: GROCYKEY
product_id: 24
amount: 80
# Consume washing powder
- service: shell_command.grocy_consume_item
data:
server_ip: 127.0.0.1
grocy_key: GROCYKEY
product_id: 23
amount: 45
- service: homeassistant.turn_off
entity_id: automation.washing_machine_powder_consume
In Grocy I've set these items up with the right purchase and consumption units like the dishwashing tablets.

Regular Consumables
So far we've automated things where Home Assistant can "see" them being consumed. But what about other things that Home Assistant can't see via sensors?
For daily things, we can setup timed automations to execute at a certain time. For example every day at 9am, remove a breakfast bar from stock, but only if it is a workday.
#grocy.yaml
- alias: Consume breakfast bar on Work Day
trigger:
- platform: time
at: '08:00:00'
condition:
condition: and
conditions:
- condition: state
entity_id: binary_sensor.workday_sensor
state: 'on'
action:
- service: shell_command.grocy_consume_item
data_template:
server_ip: 127.0.0.1
grocy_key: GROCYKEY
product_id: 32
amount: 1
For items consumed on an ad-hoc basis, we can use the Home Assistant interface. This would be particularly helpful for a tablet like an Amazon Fire Tablet mounted to a wall in the kitchen.
We can easily create scripts, which can be used to tell Grocy to consume items when called. Here's a script which will remove 100ml of Milk from stock when executed.
#grocy.yaml
script:
grocy_consume_milk:
alias: Consume Glass of Milk
sequence:
- service: shell_command.grocy_consume_single_item
data:
server_ip: 127.0.0.1
grocy_key: GROCYKEY
product_id: 4
amount: 0.1 #Grocy tracks Milk in litres, so mark 0.1 litres as consumed
Which can appear in Lovelace with an entity card like:

Alerting when item below threshold
Grocy has the ability to mark items in its interface when they are below a threshold. However this requires you to open the Grocy interface. It would be better if Home Assistant could send you a notification when your stock levels have reached a certain point.
We can easily do this with a REST Sensor, and some automations. We'll need to use a full URL to the Grocy API for this.
#grocy.yaml
sensor:
- platform: rest
resource: http://127.0.0.1:9283/api/stock/products/52
headers:
GROCY-API-KEY: GROCYKEY
name: Dishwashing Tablets
value_template: '{{ value_json.stock_amount }}'
scan_interval: 3600
json_attributes:
- last_purchased
Now we'll setup an automation to send a notification at 9:30pm if there are less than 10 dIshwashing tablets in stock.
#grocy.yaml
automation:
- alias: Alert when Dishwashing tablets below threshold
trigger:
- platform: time
at: '21:30:00'
condition:
condition: and
conditions:
- condition: numeric_state
entity_id: sensor.dishwashing_tablets
below: 10
- condition: time
before: '23:00:00'
after: '20:00:00'
action:
- service: notify.phil
data:
message: Oh no you need to buy Dishwashing tablets!
title: Dishwashing Tablets
Maybe instead of bugging me at 9:30pm when the grocery store is closed, Home Assistant could just add the item to my shopping list once. There are several different systems Home Assistant can integrate with for this. For example you may choose to send an email to Todoist. For the sake of simplicity, I'm going to use the Home Assistant shopping list for this example.
#dishwashing.yaml
automation:
- alias: Dishwashing tablets shopping list add
trigger:
- platform: state
entity_id: sensor.dishwashing_tablets
state: 10
condition:
condition: and
conditions:
- condition: state
entity_id: sensor.dishwashing_tablets
state: 10
action:
- service: shopping_list.add_item
data:
name: Dishwashing Tablets
You can also automate marking the items as done once the stock amount returns to a normal threshold
#dishwashing.yaml
automation:
- alias: Dishwashing tablets shopping list complete
trigger:
- platform: numeric_state
entity_id: sensor.dishwashing_tablets
above: 40
condition:
condition: and
conditions:
- condition: numeric_state
entity_id: sensor.dishwashing_tablets
above: 40
action:
- service: shopping_list.complete_item
data:
name: Dishwashing Tablets
The only problem with marking things off the Home Assistant shopping list automatically is that there is no way to check if an item exists in the Shopping List. This means each time you use a dishwashing tablet, and it goes down from 50 -> 49, 49 -> 48 this automation will get called and may throw some errors.
We can simply turn the automation off so that once the Dishwashing tablets have been marked as complete, we won't try again.
#dishwashing.yaml
automation:
- alias: Dishwashing tablets shopping list complete
trigger:
- platform: numeric_state
entity_id: sensor.dishwashing_tablets
above: 40
condition:
condition: and
conditions:
- condition: numeric_state
entity_id: sensor.dishwashing_tablets
above: 40
action:
- service: shopping_list.complete_item
data:
name: Dishwashing Tablets
- service: automation.turn_off
data:
entity_id: automation.dishwashing_tablets_shopping_list_complete
For good measure we should also turn that automation back on, once we have added the item to the shopping list.
#dishwashing.yaml
automation:
- alias: Dishwashing tablets shopping list add
trigger:
- platform: state
entity_id: sensor.dishwashing_tablets
state: 10
condition:
condition: and
conditions:
- condition: state
entity_id: sensor.dishwashing_tablets
state: 10
action:
- service: shopping_list.add_item
data:
name: Dishwashing Tablets
- service: automation.turn_on
data:
entity_id: automation.dishwashing_tablets_shopping_list_complete
Making it simple with the Grocy custom component
The examples I've given so far will work for any Home Assistant installation, because they're using core components to talk directly with the Grocy API.
There is also a custom component for Home Assistant from Sebastian Rutofski. Using the custom component, you could instead use service calls and sensors instead of relying on shell commands and REST sensors. If you're interested, you can check out that component on GitHub.
The Grocy custom component is also available for one-click install via the Home Assistant Community Store (HACS).
Going Further
So far we've got the the shopping list automated based on time, and when devices change state. However there's some other cool use cases you could use with Home Assistant. Here's some ideas...
- Use a Xiaomi Wireless button as a "consume button". Stick these near your fridge or pantry, and label the button. Each time you press the button, Home Assistant will remove the applicable item (for example 200ml of Milk, or a can of soda) from your stock levels.
- Automatically update the stock levels of the popcorn when a movie starts playing on Plex late at night.
- Remove a portion of soap or shampoo from your inventory each time someone has a shower, by taking action when a water leak sensor in your shower is activated.
- Use an ESP8266 device with a weight sensor to automatically report the stock levels of jarred items like flour or sugar directly into Grocy.
- If your device tracker GPS enters a radius near the grocery store, have Home Assistant email you any items that are below the threshold set in Home Assistant.
See the products I use in my smart home