It would be great to pull in shopping lists etc… from the Bring! app which is one of the best shopping list apps for iOS/Android.
It appears to integrate with Google/Alexa already
It would be great to pull in shopping lists etc… from the Bring! app which is one of the best shopping list apps for iOS/Android.
It appears to integrate with Google/Alexa already
Looks very good. Is there any information on how this came about?
I am experimenting myself with node-red and some codes I found:
–> It’s a shame that Bring! has no open API.
This is my sensor
from homeassistant.helpers.entity import Entity
from requests import get
ICON = "mdi:cart"
ICONEMPTY = "mdi:cart-outline"
LIST_ID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the sensor platform."""
add_entities([BringSensor()])
class BringSensor(Entity):
"""Representation of a Sensor."""
def __init__(self):
"""Initialize the sensor."""
self._state = None
self._purchase = []
self._recently = []
@property
def name(self):
"""Return the name of the sensor."""
return 'Shopping List'
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def icon(self):
"""Return the icon to use in the frontend, if any."""
return ICON if len(self._purchase) > 0 else ICONEMPTY
@property
def device_state_attributes(self):
"""Return the state attributes."""
attrs = {}
attrs["Purchase"] = self._purchase
attrs["Recently"] = self._recently
return attrs
def getList(self, source=[], details=[], articles=[]):
items = []
for p in source:
found = False
for d in details:
if p["name"] == d["itemId"]:
found = True
break
item = {}
item["image"] = p["name"]
item["name"] = p["name"]
item["specification"] = p["specification"]
if found == True:
item["image"] = d["userIconItemId"]
item["key"] = item["image"]
if(item["name"] in articles):
item["name"] = articles[item["name"]]
else:
if(found == 0):
item["image"] = item["name"][0]
item["image"] = item["image"].lower().replace(
"é", "e").replace("ä", "ae").replace("-", "_").replace("ö", "oe")
# print("%s: %s => %s" % (item.key, item.name, item.specification))
if "+" in item["specification"]:
specs = item["specification"].split("+")
for spec in specs:
temp = dict(item.items())
temp["specification"] = spec.strip()
items.append(temp)
else:
items.append(item)
return items
def update(self):
self._items = []
self._recently = []
"""Fetch new state data for the sensor.
This is the only method that should fetch new data for Home Assistant.
"""
# get articles US
url = "https://web.getbring.com/locale/articles.en-US.json"
articles = get(url=url).json()
url = f"https://api.getbring.com/rest/bringlists/{LIST_ID}/details"
details = get(url=url).json()
url = f'https://api.getbring.com/rest/bringlists/{LIST_ID}'
data = get(url=url).json()
purchase = data["purchase"]
recently = data["recently"]
self._purchase = self.getList(purchase, details, articles)
self._recently = self.getList(recently, details, articles)
self._state = len(purchase)
and this is my custom card
const LitElement = Object.getPrototypeOf(
customElements.get("hui-view")
);
const html = LitElement.prototype.html;
class BringShoppingList extends LitElement {
static get properties() {
return {
hass: {},
config: {}
};
}
constructor() {
super();
this.config = {};
}
renderStyle() {
return html`
<style>
</style>
`
}
render() {
if (!this.config || !this.hass) {
return html``;
}
const stateObj = this.hass.states[this.config.entity];
return html`
${this.renderStyle()}
<ha-card .header="${this.config.name}">
<div class="card-content">
${stateObj.attributes.Purchase.map(item => this.getItemTemplate(item, this.config.purchaseColor))}
</div>
${this.config.showRecent ? html`
<div class="card-content">
${stateObj.attributes.Recently.map(item => this.getItemTemplate(item, this.config.recentlyColor))}
</div>
` : ""}
</ha-card>
`;
}
getItemTemplate(item, color) {
return html`
<paper-button
style="display: inline-block;
background-color: ${color};
color: #f4f4f4;
margin: 2px;
padding: 10px 5px;
height: ${this.config.itemHeight}px;
width: ${this.config.itemWidth}px;
cursor: pointer;
text-align: center;"
.key="${item.key}"
@click="${this.handleActionClick}"
>
<div style="width: auto; height: ${this.config.itemHeight / 2}px">
<img style="max-width: 100%;
max-height: 100%;"
src="https://web.getbring.com/assets/images/items/${item.image}.png">
</div>
<label style="display: block;
text-align: center;
color: #FFF;
font-size: 0.8em;
cursor: pointer;"
>${item.name}</label>
<label style="display: block;
text-align: center;
color: #FFF;
font-size: 0.8em;
cursor: pointer;"
>${item.specification || html` `}</label>
</paper-button>
`
}
handleActionClick(e) {
const theme = e.currentTarget.key;
this.hass.callService(
"bring",
"swap_item",
{
entityId: this.config.entity,
key: theme
}
);
}
getCardSize() {
return 9;
}
setConfig(config) {
if (!config.entity)
throw new Error('Please define an entity');
if (this.lastChild) this.removeChild(this.lastChild);
this.config.entity = config.entity;
this.config.name = config.name;
this.config.showRecent = config.show_recents == true ? true : false;
this.config.purchaseColor = '#ee524f';
this.config.recentlyColor = '#4faba2';
this.config.itemWidth = 90;
this.config.itemHeight = 63;
if (typeof config.purchase_color !== 'undefined' && config.purchase_color !== null)
this.config.purchaseColor = config.purchase_color;
if (typeof config.recently_color !== 'undefined' && config.recently_color !== null)
this.config.recentlyColor = config.recently_color;
if (typeof config.item_width !== 'undefined' && config.item_width !== null)
this.config.itemWidth = config.item_width;
if (typeof config.item_height !== 'undefined' && config.item_height !== null)
this.config.itemHeight = config.item_height;
}
}
customElements.define('bring-shopping-list-card', BringShoppingList);
console.info(
`%c BRING-SHOPPING-LIST \n%c Version 0.0.1 `,
"color: orange; font-weight: bold; background: black",
"color: white; font-weight: bold; background: dimgray"
);
I am new here in the forum, your contribution is exactly what I intend.
Can you tell me how you integrated the list? And where did you get the “Liste_id” from?
Where do I have to enter your codes exactly? Unfortunately it doesn’t work with sensors.
I’m not a developer myself but I’d like to explain what I’ve tried so far. It doesn’t work for me yet. Maybe it helps others and we get the solution from @dotKrad closer.
The first file is the bring.py as custom component. The second then saved as custom card: bring.js
I got the List-ID from the developer tools of Chrome. For this a picture:
If I set this one here I get a value back:
https://api.getbring.com/rest/bringlists/{LIST_ID}/details
I come from Germany so I had to adapt the following:
https://web.getbring.com/locale/articles.de-DE.json
(instead of en-US) --> works
With the YAML entry I started like a noob with :
sensor:
- platfrom: bring
It doesn’t work yet but I would like to thank @dotKrad for the files and the support.
dotKrad can you tell me how to integrate the sensor and the custom card? in configuration.ymal i only get error messages.
Hey guys, I uploaded the code I actually have for Bring integration
I’m not an expert, feel free to contribute
You need to add this to your configuration.yaml
bring_shopping_list:
lists:
- id: xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
name: Home
locale: de-DE
- id: xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
name: Work
sorry guys, I haven’t write the component documentation yet, but you need to copy the files in a bring_shopping_list folder under custom_components
Thanks, now it works
I am not able to change the status of a product.
Is there any way through the API or Lovelace UI?
Holy thread revivial Batman!
So, I have;
When I try to add a card via lovelace GUI I have no card…?
I should aslo note that I did not have the custom-lovelace folder but did have a community folder in www - funnily enough, the three in there (dual guage, spotify, calendar) are also missing from the GUI.
Can someone point me in the right direction…?
Sorry,
Dave the n00b.
Ignore me. I’m an idiot. Moved lovelace to yaml.
Hi … i would like to add the Bring list. Sorry for my noob question (i’m new in HA).
Could you may help me. I did the steps from the above post. Now i got:
Component Error: bring_shopping_list - Integration "bring shopping list" not found
Custom element doesn’t exist: bring-shopping-list-card.
Thx
Hi
after struggling some hours with the card integration the lists are now shown in my lovelace-ui but there is no click action and I don’t see the recently items. is this a known limitation or do I’ve configure something more?
BR Stefan
And additional for iobroker there is a node API: https://github.com/foxriver76/node-bring-api/blob/b91e35e6aa297c58c560e919d85192da3180e9b7/lib/bring.js maybe this helps to develop it further?
BR Stefan
Sorry guys, I had to stop the develop of this component, cause I’m really busy at the moment.
@stefankumli you can show the recent items in the card, setting show_recents: true
currently there are no click actions, just showing the items in the list
Hope can continue developing it as soon as possible
This is great work - please do keep it up. As original post, this is one of the most popular apps for shopping lists, so be awesome to have a slick integration in home assistant!