The wine-cellar
implementation allows you to integrate your Cellar Tracker data into Home Assistant.
- Sensor entity (per account) provides total bottle count.
- Action provides detailed inventory.
- Actions provide summaries of inventory.
- Action immediately refreshes inventory from Cellar Tracker.
This is an unofficial integration of Cellar Tracker for Home Assistant. The developer and the contributors are not in any way affiliated with CellarTracker! LLC.
"CellarTracker!" is a trademark of CellarTracker! LLC
- Cellar Tracker account - https://cellartracker.com
- Flex Table Card - Available in HACS or https://github.com/custom-cards/flex-table-card/
- Install manually by copying the
custom_components/wine_cellar
folder into<config_dir>/custom_components
. - Restart Home Assistant.
- In the Home Assistant UI, navigate to
Settings
thenDevices & services
. In theIntegrations
tab, click on theADD INTEGRATION
button at the bottom right and selectWine Cellar
. Fill out the options and save.- Member Name - Your cellartracker.com Member Name (NOT your Email Address).
- Password - Your cellartracker.com password.
A single sensor entity is provided for each linked CellarTracker account. This could be useful for a quick view of your total bottle count as well as a launch point to more detailed information, as shown here:
This Tile Card provides the total bottle count, a link to a view with more information called wine-inventory
, and an icon_tap_action
to immediately refresh Home Assistant from the CellarTracker database.
- type: tile
entity: sensor.<yourmembername>_wine_inventory
name: Wine Inventory
tap_action:
action: navigate
navigation_path: wine-inventory
icon_tap_action:
action: call-service
service: wine_cellar.refresh_inventory
target:
entity_id: sensor.<yourmembername>_wine_inventory
More detailed views of the inventory are best presented with the flex-table-card. The flex-table-card
shows data in a tabular form, which works well for a wine database.
Consider this list of wines as shown in a flex-table-card
:
The card definition for the above view demonstrates some advanced features of the card which can be used to mimic CellarTracker's display of icons. Notice the use of the action
option to populate the table using the wine_cellar.get_inventory
action.
type: custom:flex-table-card
action: wine_cellar.get_inventory
entities:
include: sensor.<yourmembername>_wine_inventory
clickable: true
sort_by:
- ConsumeBy
- Vintage
columns:
- name: ""
data: inventory
align: center
modify: |-
function getColor(wineColor) {
let color="red";
switch(wineColor) {
case "Red":
color="DarkRed"
break;
case "White":
color="Khaki"
break;
case "Rosé":
color="LightPink"
break;
default:
color="White";
break;
}
return color;
} function getIcon(wineType) {
let icon="mdi:glass-wine";
switch(wineType) {
case "Dry":
icon="mdi:glass-wine"
break;
case "Sweet/Dessert":
icon="mdi:glass-tulip"
break;
case "Sparkling":
icon="mdi:glass-flute"
break;
default:
icon="mdi:glass-wine"
break;
}
return icon;
} '<ha-icon icon=' + getIcon(x.Category) + ' style=color:' +
getColor(x.Color) + ';></ha-icon>'
- name: Barcode
data: inventory.Barcode
hidden: true
- name: Vintage
data: inventory.Vintage
modify: if(parseInt(x) == 1001) {"N.V."} else{parseInt(x)}
- name: Wine
data: inventory.Wine
- name: ConsumeBy
data: inventory
modify: |-
((parseInt(x.BeginConsume) || 9999) +
(parseInt(x.EndConsume) || 9999)) / 2
hidden: true
- name: Category
data: inventory
modify: x.Category + " " + x.Color
- name: Consume
data: inventory
modify: |-
let result =
x.BeginConsume == "" && x.EndConsume == ""
? "None"
: x.BeginConsume + "-" + x.EndConsume;
parseInt(x.BeginConsume) > new Date().getFullYear()
? '<div class="too-early">' + result + '</div>'
: parseInt(x.EndConsume) < new Date().getFullYear()
?'<div class="too-late">' + result + '</div>'
: result
- name: Bin
data: inventory.Bin
- name: Price
data: inventory.Price
modify: if (x == 0 ) {"N/A"} else {"$" + parseFloat(x).toFixed(0)}
- name: Store
data: inventory.StoreName
css:
tr:has(> td div.too-early): color:dimgray !important;
tr:has(> td div.too-late): color:red !important;
A group of actions is available to summarize the inventory by various fields. They are:
- wine_cellar.get_countries
- wine_cellar.get_locations
- wine_cellar.get_producers
- wine_cellar.get_types
- wine_cellar.get_varietals
- wine_cellar.get_vintages
Each action returns a list that includes the following attributes:
- group title
- count
- value_total
- value_avg
- percent
You can preview the data that will be provided to the flex-table-card
for each action by using the Developer tools
Actions
tab.
For example, the following action call...
action: wine_cellar.get_countries
target:
entity_id: sensor.<yourmembername>_wine_inventory
data: {}
...produces a result like:
sensor.<yourmembername>_wine_inventory:
countries:
- Country: Australia
count: 1
value_total: 25
value_avg: 25
percent: 2
- Country: France
count: 2
value_total: 72
value_avg: 36
percent: 5
- Country: Italy
count: 1
value_total: 29
value_avg: 29
percent: 2
...
The keys that are returned with each action are as follows:
Action | Top level | Group title |
---|---|---|
get_countries |
countries | Country |
get_locations |
locations | Location |
get_producers |
producers | Producer |
get_types |
types | Type |
get_varietals |
varietals | Varietal |
get_vintages |
vintages | Vintage |
This is the card for the summary by Country shown in the following examples:
type: custom:flex-table-card
title: Bottles per Country
action: wine_cellar.get_countries
entities:
include: sensor.<yourmembername>_wine_inventory
sort_by: Country-
columns:
- name: Country
data: countries.Country
- name: Percentage
data: countries.percent
align: right
- name: Total Cost
data: countries.value_total
align: right
prefix: $
- name: Average Price
data: countries.value_avg
align: right
prefix: $
- name: Bottles
data: countries.count
align: right
When using the other Summary Actions, you will need to change some of the name
and data
values, as well as any title
, sort_by
, modify
,
or other relevant values. That is, every occurrence of Country
and countries
in the above example would need to be substituted using the table above.
Here are examples of each action:
Feel free to contribute by opening a PR or issue on this project.