[Custom Component] RedPocket Mobile Plan Sensors

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. :slight_smile:

GitHub: mbillow/ha-redpocket
Currently waiting for the PR to get merged to make it available in HACS.

Thank you for this! We have two numbers and it pulled in both of them but none of the entities have values. All of them show Unavailable.

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.

If you want an example of what the log lines should look like: Multiple lines · Issue #1 · mbillow/ha-redpocket · GitHub

Hi! I installed via HACS and restarted, but not sure where to go from here?

Thanks in advance!

You’ll need to finish the setup: https://hacs.xyz/docs/configuration/basic

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

Any ideas?

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.

Let me know how it goes!

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 @derikj lastAutoRenewDate 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 :slight_smile:
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

Feel free to pull the latest version (v2.3.2) and report back! :slight_smile: Here is the actual diff: Don't define the update function in the lines loop · mbillow/[email protected] · GitHub

Excellent work! They are showing correctly now.

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.

Thanks again for getting this going!

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!

@derikj @kramttocs I just published version 2.3.3 which changes the sensor behavior to report “Unlimited” instead of being unavailable. :slightly_smiling_face:

Thanks Marc!
Hate to complain but I am seeing them as Unlimited Messages/Minutes. Could you make it just “Unlimited”?

While I am asking :slight_smile:

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:


Something like this wouldn’t be possible is the units were apart of the state. Happy to help you understand this further if it still isn’t clear. :smiley: