I saw that there was an integration for surfacing your Mint Mobile plan information / balances in Home Assistant, so I decided to write a Python module for the RedPocket API and then fork the Mint Mobile integration to retrofit the module in.
GitHub: mbillow/ha-redpocket
Currently waiting for the PR to get merged to make it available in HACS.
Anything in the logs? If not, try reloading the extension from the Integrations page or restarting HA. If none of that works, Iâm happy to help debug further!
Appreciate the reply.
I restarted HA and reloaded the integration. Looking at the entities they all have a red circle exclamation point. I checked the logbook for a random one (did months remaining for one line) but no entries returned.
Reload the extension while watching the logs. The only thing that could cause all of the sensors to report unavailability is if the UpdateCoordinator is causing an exception. (code). I may need to publish a version with more logging if nothing useful is being printed out.
Once you finish that, you should see an additional item on the sidebar titles HACS. Click that, then âIntegrationsâ, then âExplore and Add Repositoriesâ in the bottom right, then search for and install the âRedPocketâ integration. Youâll need to restart, but after that you can go to Configuration > Integrations > âAdd Integrationâ > RedPocket Mobile > Login.
Awesome, got it installed! Shows my number on the sensors but theyâre all Unavailable.
Tried restarting the integration as well as Home Assistant.
Seeing the following in logs
Logger: custom_components.redpocket.sensor
Source: custom_components/redpocket/sensor.py:58
Integration: RedPocket Mobile (documentation, issues)
First occurred: 12:41:41 PM (1 occurrences)
Last logged: 12:41:41 PM
Unexpected error fetching redpocket line REDACTED sensor data: strptime() argument 1 must be str, not None
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 180, in _async_refresh
self.data = await self._async_update_data()
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 140, in _async_update_data
return await self.update_method()
File "/config/custom_components/redpocket/sensor.py", line 58, in async_update_data
return await hass.async_add_executor_job(line.get_details)
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 143, in get_details
return self._details_callback(self.account_hash)
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 259, in get_line_details
return RedPocketLineDetails.from_api(
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 79, in from_api
last_autorenew=str_to_date(
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 68, in str_to_date
return datetime.strptime(date_str, "%m/%d/%Y").date()
TypeError: strptime() argument 1 must be str, not None
Awesome, thanks so much for posting that! It looks like I wasnât properly handling the case where plans didnât have a last auto-renewal date. I fixed the issue in the underlying library and then published an update to the HA integration bumping the version. If you go into HACS, update the RedPocket module, then restart HA this should be resolved.
Thanks for the update. Took it, restarted and am getting this:
Logger: custom_components.redpocket.sensor
Source: custom_components/redpocket/sensor.py:58
Integration: RedPocket Mobile (documentation, issues)
First occurred: 3:18:52 PM (2 occurrences)
Last logged: 3:18:52 PM
Unexpected error fetching redpocket line REDACTED-CELL1 sensor data: time data '0000-00-00' does not match format '%Y-%m-%d'
Unexpected error fetching redpocket line REDACTED-CELL2 sensor data: time data '0000-00-00' does not match format '%Y-%m-%d'
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 71, in str_to_date
return datetime.strptime(date_str, "%m/%d/%Y").date()
File "/usr/local/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/local/lib/python3.8/_strptime.py", line 349, in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data '0000-00-00' does not match format '%m/%d/%Y'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 180, in _async_refresh
self.data = await self._async_update_data()
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 140, in _async_update_data
return await self.update_method()
File "/config/custom_components/redpocket/sensor.py", line 58, in async_update_data
return await hass.async_add_executor_job(line.get_details)
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 153, in get_details
return self._details_callback(self.account_hash)
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 269, in get_line_details
return RedPocketLineDetails.from_api(
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 85, in from_api
last_autorenew=str_to_date(
File "/usr/local/lib/python3.8/site-packages/redpocket/api.py", line 73, in str_to_date
return datetime.strptime(date_str, "%Y-%m-%d").date()
File "/usr/local/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/local/lib/python3.8/_strptime.py", line 349, in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data '0000-00-00' does not match format '%Y-%m-%d'
Woweeee my brain hurts. This API is whack. For @derikjlastAutoRenewDate is null and for you it is 0000-00-00⌠This has lead to some terrible sanitization logic being necessary:
def str_to_date(date_str: str) -> Optional[datetime.date]:
"""Two formats of date values... because why not?!"""
if not date_str:
# If the type is falsy, return None.
return
try:
# Most dates in the API are in this format...
return datetime.strptime(date_str, "%m/%d/%Y").date()
except ValueError:
# Please forgive me for this nested try-except block.
# This API is _whack_.
try:
# But some are in this format...
return datetime.strptime(date_str, "%Y-%m-%d").date()
except ValueError:
# And sometimes you get random crap like '0000-00-00'...
return
except TypeError:
# If the type is truthy, but can't be cast to a date, return None.
return
I released 2.3.1 just now. You may need to press the three dots, then âUpdate Informationâ for it to show up.
Nothing like consistency
Really do appreciate your work on this.
We are in business! MostlyâŚ
Messaging and Voice Remaining show Unavailable but not getting any logs.
I figure these keys wonât have any real value since they are Unlimited but if possible, seeing âUnlimitedâ would be preferred. Let me know if I can provide any further data on this.
Update: I just noticed that both data balances show the same value which is the value of the second line that shows on the Red Pocket site.
Oof, this one is my own mistake. I was trying to be lazy and define a function to update each line in the same loop as the UpdateCoordinator objects. Turns out the functions all end up with the same reference to the last line. Here is a simple example that I was initially expecting to print 1 than 2, but actually prints 2 then 2.
>>> funcs = []
>>> for number in [1, 2]:
... def say_number():
... print(number)
... funcs.append(say_number)
...
>>> funcs[0]()
2
>>> funcs[1]()
2
I defined the class outside the loop and used functools.partial to maintain the proper references:
>>> from functools import partial
>>> funcs = []
>>> for number in [1, 2]:
... def say_number(n: int):
... print(n)
... funcs.append(partial(say_number, number))
...
>>> funcs[0]()
1
>>> funcs[1]()
2
And sorry, I just visited the main github page and saw that your screenshot also shows Unavailable for the minutes/messages. I should have checked that before mentioning it as then I would have known it was expected.
That is likely the most âexpectedâ behavior. I was trying to be clever and be as HA-native as possible. I donât have any preference either way thought. Happy to review a PR if you want to change the behavior.
I have updated, and everything looks to be working aside from voice and messaging balance that are still unavailable. Maybe because theyâre âunlimitedâ? Donât need them for my purposes though.
Thanks for making this and the quick updates/replies!
Thanks Marc!
Hate to complain but I am seeing them as Unlimited Messages/Minutes. Could you make it just âUnlimitedâ?
While I am asking
My remaining months shows â1 Monthsâ. Accurate but shouldnât be plural.
Along that line, for things like âMonths leftâ and âDays remainingâ should they just be numeric values? I am very new to HA so maybe this is the norm but just wondering since we already know the units of measure, do we need them in the value?
I assume you are talking about the Entity Card. You can change this for yourself (I think) using the suffix config: Entities Card - Home Assistant
This is something I need to fix.
Units and state (value) are different parts of a sensor, the entity card just concatenates them automatically. There are more details in the link above, but the tl;dr here is that this is already how it works. For example, here is how I am using the values to display my plan: