Grocy - Custom component and card(s)

Hi,

I installed the add-on via the add-on store and added the custom component via HACS.
When I restart HA and head over to the integration, I can retrieve it in the list.

However, when I try to add the integration itself by entering my local IP + the token that I’ve generated in Grocy, I’m prompted with the message “Something went wrong.” (see screenshot).

HA_Grocy_01

I must be doing something wrong, but I can’t figure out what it is :slight_smile:
I’ve tried my local IP with http, https, HA port, with/without quotes, …

Any idea/suggestions?

Try removing the trailing slash / after your ip.

I have grocy installed, I have the custom component installed, and I have the chores card configured and working. Mostly thanks to reading through older posts, so thanks!

BUT when I hit a “Track” button on the chores card, the chore gets documented as completed 5 hours in the future. When I track a chore within grocy itself, this doesn’t happen. I’m in EST time zone, so -5 hours from UTC, and I’m wondering if that’s the problem. I noticed in grocy_data.py that it uses UTC (utc = pytz.UTC) so I tried changing it to my timezone (utc = pytz.timezone(‘America/Toronto’)). Unfortunately this didn’t seem to change anything.

If anyone knows how to fix this, I’d really appreciate it!

I would also appreciate help with this time zone problem, as I cannot fix it myself.

Hadn’t had a lot of time to take a look at it, please bear with me, if I overlooked something. :slight_smile:

Grocy itself doesn’t seem to handle the date in any way, it just takes the input and expects it to be the correct localized time.

The function TrackChoreExecution found here does this:

		$trackedTime = date('Y-m-d H:i:s');

			if (array_key_exists('tracked_time', $requestBody) && (IsIsoDateTime($requestBody['tracked_time']) || IsIsoDate($requestBody['tracked_time'])))
			{
				$trackedTime = $requestBody['tracked_time'];
			}

That means, the time send to Grocy must be localized within the custom_component.

If you take a look here at async_update_overdue_chores the time is handled in UTC (that btw is the right way to deal with this). But before the time is appended to overdue_chores it should be localized.

for chore in chores:
  if chore.next_estimated_execution_time:
    now = datetime.now().replace(tzinfo=utc)
    due = chore.next_estimated_execution_time.replace(tzinfo=utc)
      if due < now:
        overdue_chores.append(chore)
return overdue_chores

Here is a snippet from the documentation about pytz:

>>> from datetime import datetime, timedelta 
>>> from pytz import timezone 
>>> import pytz 
>>> utc = pytz.utc 
>>> utc.zone 'UTC' 
>>> eastern = timezone('US/Eastern') 
>>> eastern.zone 'US/Eastern' 
>>> amsterdam = timezone('Europe/Amsterdam') 
>>> fmt = '%Y-%m-%d %H:%M:%S %Z%z'

This library only supports two ways of building a localized time. The first is to use the `localize()` method provided by the pytz library. This is used to localize a naive datetime (datetime with no timezone information):

>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0)) 
>>> print(loc_dt.strftime(fmt)) 2002-10-27 06:00:00 EST-0500

The second way of building a localized time is by converting an existing localized time using the standard `astimezone()` method:

>>> ams_dt = loc_dt.astimezone(amsterdam) 
>>> ams_dt.strftime(fmt) '2002-10-27 12:00:00 CET+0100'

I’d try something like this

for chore in chores:
  if chore.next_estimated_execution_time:
    now = datetime.now().replace(tzinfo=utc)
    due = chore.next_estimated_execution_time.replace(tzinfo=utc)
      if due < now:
        chore.next_estimated_execution_time.astimezone(est) #<- not tested, but something along these lines...
        overdue_chores.append(chore)
return overdue_chores

@teachingbirds Does this help a little bit? Hope we’re moving in the right direction here… :flushed: :crazy_face: :rofl:

EDIT: that doesn’t solve the problem where to get the correct timezone for the specific user, but that should be available from HA, shouldn’t it? :slight_smile:

The issue remains after removing the slash…
Any other things I could try?

1 Like

What does the log say?

1 Like

Probably sound reasonable :smiley: I don’t know exactly when I will be able to have time for this though.

I’ll see what I can do in the next days. :slight_smile: If I’ll find the time, I’ll send you a PR, but no promises made. :wink: :slight_smile:

1 Like

The log didn’t say anything, actually.
It was the config of the Grocy add-on.
ssl was set to ‘true’, but that prevented the integration from connecting, I guess.

Unfortunately, my programming skills are not even close to being able to contribute… but I tried using the grocy integration and have some thoughts:

  1. it would be nice if each product in the grocy database could be a sensor entity.

Example:

  • entity_id: sensor.grocy_stock_id_1_clif_bar_peanut_butter
  • friendly_name Clif Bar Peanut Butter (= whatever the user has set as product name in grocy)
  • attributes (I copied these values by looking at the grocy API; basically, use whatever is available because you never know what people might need it for)
    • “id”
    • “description”:
    • “product_group_id”
    • “active”
    • “location_id”
    • “shopping_location_id”
    • “qu_id_purchase”
    • “qu_id_stock”
    • “qu_factor_purchase_to_stock”
    • “min_stock_amount”
    • “default_best_before_days”
    • “default_best_before_days_after_open”
    • “default_best_before_days_after_freezing”
    • “default_best_before_days_after_thawing”
    • “picture_file_name”
    • “enable_tare_weight_handling”
    • “tare_weight”
    • “not_check_stock_fulfillment_for_recipes”
    • “parent_product_id”
    • “calories”
    • “cumulate_min_stock_amount_of_sub_products”
    • “due_type”
    • “quick_consume_amount”
    • “hide_on_stock_overview”
    • “row_created_timestamp”
    • “userfields”
  1. allow users to use these values in a service call

Example

- service: grocy.consume_product_from_stock
  data:
    entity_id: sensor.grocy_stock_id_1_clif_bar_peanut_butter
    amount: 1
    spoiled: false
    transaction_type: "CONSUME"
- service: grocy.add_product_to_stock
  data:
    entity_id: sensor.grocy_stock_id_1_clif_bar_peanut_butter
    amount: 3
    price: 1.99
  1. allow users to correct stock information via service call

Example: I consumed 6 items by accident, when I meant to only consume 3. Of course, I could just use the grocy.add_product_to_stock service from above to add another 3 to make up for the additional 3 I accidentally consumed; but it’d be nice to do something like this

- service: grocy.correct_stock_value
  data:
    entity_id: sensor.grocy_stock_id_1_clif_bar_peanut_butter
    current_stock: 12

Let’s say somebody used a wireless barcode scanner and meant to scan an item once, but for some weird reason, it got submitted 200 times. The stock would actually be 1 (or whatever there was previously + 1), not 200. With a correct_stock_value service, one could easily fix this - especially by creating an input_number.correct_stock_value and doing this

- service: grocy.correct_stock_value
  data:
    entity_id: sensor.grocy_stock_id_1_clif_bar_peanut_butter
    current_stock: "{{ states('input_number.correct_stock_value') }}"

Current situation

I don’t know if I set up grocy in a way that causes this (using both Home Assistant and grocy as (separate) docker services)… but I have immense trouble with the integration telling me correct stock values!

There is a zigbee button on the fridge that is supposed to keep track of the water and Club Mate bottles we have in the fridge…

In order to get the current stock, I needed to create sensors like this one

sensor:
  - platform: template
    sensors:
      helper_mate_kuehlschrank:
        friendly_name: "Mate"
        unit_of_measurement: "Flaschen"
        value_template: "{{ state_attr('sensor.grocy_stock', 'products')[2]['available_amount'] | int }}"
        # icon_template: "mdi:cup-water"
        entity_picture_template: "/local/img/bottle_mate.png"

While this would be fine, it seems like the number in brackets does not correspond with the actual product id grocy uses. The sensor.grocy_stock only returns items that currently are in stock!! So, in this case, the “Mate” drink is currently "{{ state_attr('sensor.grocy_stock', 'products')[2]['available_amount'] | int }}" and water is "{{ state_attr('sensor.grocy_stock', 'products')[1]['available_amount'] | int }}".

However, and this is bad: when there is no water left in the fridge (-> stock amount = 0), water vanishes from sensor.grocy_stock, therefore “Mate” suddenly becomes "{{ state_attr('sensor.grocy_stock', 'products')[1]['available_amount'] | int }}" (the number changed)

I don’t know how relevant this is for the rest of you. But we use TTS for this (take a bottle of water and hear There are only <x> bottles left in the fridge. This is not a matter of live and death, as one sees the amount of bottles left when taking one, anyway. But if we have the means to integrate this into Home Assistant, it should be reliable.

What’s also very confusing is that one would make sure to both

  • have at least 1 product of whatever is in stock left (because when it reaches 0, it will disappear from the sensor.grocy_stock sensor) and
  • always to double check when writing automations. ==> I naturally assumed that, when water is product_id 2, it will also be (...)[2](...) in the sensor. However, that is not the case. Let’s say some product is product_id 24, but all other products are out of stock… then it would be (...)[0](...), not (...)(23](...). When you know this, you can work with it. But it is counter intuitive and confusing.

Sorry, I hope this doesn’t come across like I just want to bash the project!! I love that there even is a grocy integration (when I tried integrating it myself years ago, I used HTTP calls). I just wanted to mention these things because I am trying to get more things done with grocy, and these things I mentioned made things a bit difficult. But perhaps the person who wrote it never wanted to actually display the amount of available stock in lovelace and that’s why they didn’t consider it… so I thought it wouldn’t hurt to just mention :slight_smile: The service calls were just another idea, because Home Assistant becomes more and more configurable via the webUI, and if every single item (regardless of the current stock amount) would be a sensor starting with sensor.grocy_stock_id_*, one could even find the desired product via dropdown menu instead of having to manually find the product_id via grocy API).

:raised_hands: :pray:

1 Like

I have said no to this request before, but I am willing to change my mind, since it’s obviously something several people want. Although since I don’t see that I myself want to use this, and I don’t have unlimited time on my hands, I will say that I will not implement this. I will however accept if someone else does this and makes a pr for it. It will have to be opt in (the sensors will be disabled by default) and it will have to be grouped in several devices etc. Here’s a feature request that I re-opened now.

This will also be accepted if someone makes no1 :slight_smile:

This would have to be implemented in the library first I think. I don’t know if it’s a function that’s available.

On to your current situation

No, the number in the brackets corresponds to the position in the list/array. list[2] is the item in the third position (it starts at 0).

The possible fix for this is to use a template like this, that loops over the items and find the one with correct id.

{% for product in state_attr('sensor.grocy_stock', 'products') -%}
{%- if product.id == 13 %}
{{product.available_amount}}
{% endif -%}
{%- endfor %}

The 13 should be changed to the correct id for your procuct in Grocy. The template will return nothing if the id is not present in the sensor, I don’t know how the template sensor handles that, you should be able to make it a 0 too I guess, with some more templating magic!

1 Like

Uh, that’s something that isn’t a very good idea, technical-wise. :slight_smile: Sorry, not meant mean or disrespectful, just as a discussion point. :slight_smile:

If I just take my stock, I’d have around 500 to 600 new sensors, that would be more than double all my other sensors at the moment… :open_mouth: :flushed: :astonished: One would have to boost his equipment to very expensive hardware…

I can see why you get there, but in my opinion it would be mixing things, that shouldn’t be mixed together.
Grocy is your household ERP - that’s good, and Groocy is good, because it does one thing: it controls and administers your household needs.
HomeAssistant is to manage your more or less technical approach to your home. And same goes here, it does what it does, and it does do it good, because it is designed for exactly that.

Groocy has a nice UI, and can be called directly via browser (same as HA). There is simply no technical need to handle these things in HA. If you really need to do stuff in your ERP than go to the Groocy webUI. If you want to turn on your lights, call HA to do so. Don’t get me wrong, as I said, I can see why you get there, people generally like to do everything in one place, but that is simply not necessary or advisable in most cases. Let the one software do what it does best, for all other things look at a software that is suitable for exactly that.

Let me give you an example: in most households the place to wash your hands is the bathroom. Normally there is soap, the (guest-) towels and so on. Sure you can wash your hands in the kitchen, but that’s not the ideal solution. Ask yourself, if you have important guests at home, where do you send them to wash their hands: the kitchen or the guest toilet? :wink:

With that being said, I prefer the approach that HA has always valid. Be the manager and not the worker. Translated to Groocy that would mean, HA displays the information and can step in to manage and maintain the application Groocy, but not what Groocy is made for - manage your household items.

Sorry to say, but I’d vote against such sensors, as I see them probelmatic (technical-wise) and wouldn’t want to have them in my installation either. :slight_smile:

The same goes for your other points: if you need to change something with your stock, go where it is handled, in this case Groocy. :slight_smile:

1 Like

If I just take my stock, I’d have around 500 to 600 new sensors

Damn! I did not consider this. I have < 20 stock products at the moment, so that is something one could work with. But I did really not consider that some people might have large stock palettes such as yourself.

There is simply no technical need to handle these things in HA.

I am not sure about this. See my example from above… There is a zigbee2mqtt multibutton on our fridge. You take a bottle of water, you press it, it subtracts amount: 1 from Fridge water (which is it’s own separate product, there is also Water bottles in general, but this way, we always know the amount of water in the fridge). Sure, you could also open grocy or barcodebuddy on your phone, scan the water bottle, and keep track that way. But imho this is too much work. Plus (I don’t know if that’s an issue of grocy itself, or my Android version), the grocy app crashes whenever I try doing this. I can use barcodebuddy (which requires me to verify my scans in the browser later), but when trying to scan anything via official grocy app, the app will crash and the product will not be consumed.

And the main advantage of connecting grocy and Home Assistant to me is something like “if there are only 2 bottles of water left in the fridge, send an alert via telegram asking to restock until the amount increased again” (which also works via that z2m button: one click subtracts bottle, another one adds 12 bottles - because there are always 12 water bottles in one crate and usually that is the amount we use when restocking).

I guess we could also do this separately (and perhaps should??): have the “fridge items” (or thise that need to be tracked and used to create notifications) outside of grocy, and instead use input_numbers directly in Home Assistant for this. Though I don’t know how reliable this is (for example, when updating Home Assistant… do the input_number values persist through this?).

I am currently trying to find a sensable solution for this. There is a wireless barcode scanner in the office (next to the kitchen), so we could always scan each and every item and transfer the read value via mqtt to node-red. Then there’d be too artificial barcodes that we print out that trigger consume or add. So if we want to add 12 bottles, scan the add items barcode, then scan 12 bottles (or rather the same bottle 12 times). Problem here is that you’d have to count the amount of scanned items. This is fine with 12 bottles. But let’s say you buy something in large quantities, for example, we sometimes buy 36 Clif Bars at once (because only one store in the area carries those and we don’t go there very often). If I scan 34 instead of 36, I won’t notice until they are supposedly out of stock, but there’s actually two of them left. And if I manually have to double-check everything (scan first, then manually count and compare), there’d be no point in scanning them in the first place. I could unpack my groceries in the office instead of the kitchen in the first place and do everything in the grocy webUI - which is possible, but imho way too much work.

Altogether, you are right about not having sensors in Home Assistant due to too large amounts of stock. Also, @teachingbirds stated that this will only implemented if there is a pr made by somebody else, and at least I myself cannot do this due to only having beginner skills in programming itself (and, besides appdaemon, wouldn’t know anything about integrating anything in Home Assistant at all).

My initial idea was that Home Assistant (and, to some extend, node-red) where the hub(s) to everthing in the household. Perhaps (I don’t know), I could use a webhook or command line script triggered by grocy on it’s own (without Home Assistant) when certain products are low in or out of stock. But that is something I never even looked into because I thought, if this one hub takes care of “everything” (as far as possible), it might as well route all the data and do the work of notifying etc.

I whipped up a meal plan card if anyone’s interested:

2 Likes

Hey guys!

I’m not able to add the integration… I’ve installed the Grocy addon from the supervisor. Changed the port to 9192. Restarted. Installed the Grocy from HACS. Restarted and when I try to add there is an error ‘Something went wrong’.

I’ve also deleted my cache. I use a duckdns (https://xxxxx.duckdns.org) and then the API from within the Grocy addon.

Any help or tips?

2 Likes

Hi!
I have used Grocy for some time now and i think it’s very useful, however since some time ago (more than a week) i got this problem that when i hit the track button I get this error message:

Failed to call service grocy/execute_chore. I/O must be done in the executor; Use `await hass.async_add_executor_job()` at custom_components/grocy/services.py, line 191: coordinator.api.execute_chore(chore_id, done_by, tracked_time)

I have reinstalled the Grocy integration and restarted but no success. So please I need some help to solve this :grinning:
Currently i run 2021.4.1 but it started already on 2021.3.x

This means the integration needs to be fixed or you’re running an old version that isn’t fixed.

1 Like

After updating HA to the newest version 2021.4.2 I get a similar error.
I can see tasks returned from Grocy to HA, but HA will not allow a task completion to be sent.

I have some medical issues in my family right now that takes up my time, so I’m not able to look at this right now. If anyone knows python and can try to help that would be much appreciated.

2 Likes