├── README.md ├── comcast.py └── img ├── Card.PNG └── a.txt /README.md: -------------------------------------------------------------------------------- 1 | # Comcast_Data_Usage 2 | Python script designed to return Comcast internet usage data for us in [Home Assistant](https://www.home-assistant.io). Based on https://github.com/ntalekt/Cox_Data_Usage and https://github.com/lachesis/comcast 3 | 4 | ## Home Assistant Card Example 5 | 6 | ![Alt text](/img/Card.PNG?raw=true) 7 | 8 | ## Configuration 9 | 10 | Modify the `username` and `password` variables in `comcast.py` to match your Comcast main account. Update the `json_file` variable if required. 11 | 12 | Put `comcast.py` somewhere inside your Home Assistant configuration directory. 13 | 14 | ``` 15 | username = "USERNAME" 16 | password = "PASSWORD" 17 | json_file = "/home/homeassistant/.homeassistant/comcast/comcast_usage.json" 18 | ``` 19 | 20 | ## Automation 21 | 22 | ``` 23 | automation: 24 | - alias: Query Comcast Data Usage 25 | trigger: 26 | platform: time 27 | minutes: '/60' 28 | seconds: 00 29 | action: 30 | service: shell_command.query_comcast_data_usage 31 | ``` 32 | 33 | ## Shell Command Component 34 | 35 | ``` 36 | shell_command: 37 | query_comcast_data_usage: 'python /home/homeassistant/.homeassistant/comcast.py' 38 | ``` 39 | 40 | ## Sensor Component 41 | 42 | ``` 43 | - platform: command_line 44 | command: date +"%d" 45 | name: Day Of Current Month 46 | scan_interval: 3600 47 | 48 | - platform: command_line 49 | command: cal $(date +"%m %Y") | awk 'NF {DAYS = $NF}; END {print DAYS}' 50 | name: Days In Current Month 51 | scan_interval: 3600 52 | 53 | - platform: file 54 | name: Comcast Utilization 55 | file_path: /home/homeassistant/.homeassistant/comcast/comcast_usage.json 56 | value_template: > 57 | {% if value_json is defined %} 58 | {% if value_json.used | int == 0 and value_json.total | int == 0 %} 59 | stats unavailable 60 | {% else %} 61 | {{ value_json.used | int }} / {{ value_json.total | int }} GB ({{ ((value_json.used / value_json.total)*100) | round(1) }}%) 62 | {% endif %} 63 | {% else %} 64 | undefined 65 | {% endif %} 66 | 67 | - platform: file 68 | name: Comcast Avg GB Current 69 | file_path: /home/homeassistant/.homeassistant/comcast/comcast_usage.json 70 | value_template: > 71 | {% if value_json is defined %} 72 | {% if value_json.used | int == 0 and value_json.total | int == 0 %} 73 | stats unavailable 74 | {% else %} 75 | {{ ((value_json.used | int) / (states.sensor.day_of_current_month.state | int)) | round(1) }} GB per day 76 | {% endif %} 77 | {% endif %} 78 | 79 | - platform: file 80 | name: Comcast Avg GB Left 81 | file_path: /home/homeassistant/.homeassistant/comcast/comcast_usage.json 82 | value_template: > 83 | {% if value_json is defined %} 84 | {% if value_json.used | int == 0 and value_json.total | int == 0 %} 85 | stats unavailable 86 | {% else %} 87 | {{ (((value_json.total | int) - (value_json.used | int)) / ((states.sensor.days_in_current_month.state | int ) - (states.sensor.day_of_current_month.state | int))) | round(1) }} GB per day 88 | {% endif %} 89 | {% else %} 90 | undefined 91 | {% endif %} 92 | 93 | ``` 94 | 95 | ## Customize 96 | ``` 97 | sensor.comcast_utilization: 98 | icon: mdi:percent 99 | friendly_name: Utilization 100 | sensor.comcast_template: 101 | icon: mdi:calendar-clock 102 | friendly_name: Time Left 103 | sensor.comcast_avg_gb_current: 104 | icon: mdi:chart-line 105 | friendly_name: Current Daily Avg. 106 | sensor.comcast_avg_gb_left: 107 | icon: mdi:chart-line-stacked 108 | friendly_name: Remaining Daily Avg. 109 | ``` 110 | ## Required dependencies 111 | The only requirement for the Python script is the `requests` library. 112 | -------------------------------------------------------------------------------- /comcast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from __future__ import print_function 3 | 4 | import json 5 | import logging 6 | import os 7 | import re 8 | import requests 9 | import time 10 | 11 | username = 'USERNAME' 12 | password = 'PASSWORD' 13 | json_file = "/home/homeassistant/.homeassistant/comcast/comcast_usage.json" 14 | 15 | logger = logging.getLogger(__name__) 16 | logging.basicConfig(level=logging.DEBUG) 17 | logging.getLogger('requests').setLevel(logging.ERROR) 18 | 19 | session = requests.Session() 20 | 21 | logger.debug("Finding req_id for login...") 22 | res = session.get('https://customer.xfinity.com/oauth/force_connect/?continue=%23%2Fdevices') 23 | #res = session.get('https://login.comcast.net/login?r=comcast.net&s=oauth&continue=https%3A%2F%2Flogin.comcast.net%2Foauth%2Fauthorize%3Fclient_id%3Dmy-account-web%26redirect_uri%3Dhttps%253A%252F%252Fcustomer.xfinity.com%252Foauth%252Fcallback%26response_type%3Dcode%26state%3D%2523%252Fdevices%26response%3D1&client_id=my-account-web') 24 | assert res.status_code == 200 25 | m = re.search(r'', res.text) 26 | req_id = m.group(1) 27 | logger.debug("Found req_id = %r", req_id) 28 | 29 | data = { 30 | 'user': username, 31 | 'passwd': password, 32 | 'reqId': req_id, 33 | 'deviceAuthn': 'false', 34 | 's': 'oauth', 35 | 'forceAuthn': '1', 36 | 'r': 'comcast.net', 37 | 'ipAddrAuthn': 'false', 38 | 'continue': 'https://oauth.xfinity.com/oauth/authorize?client_id=my-account-web&prompt=login&redirect_uri=https%3A%2F%2Fcustomer.xfinity.com%2Foauth%2Fcallback&response_type=code&state=%23%2Fdevices&response=1', 39 | 'passive': 'false', 40 | 'client_id': 'my-account-web', 41 | 'lang': 'en', 42 | } 43 | 44 | logger.debug("Posting to login...") 45 | res = session.post('https://login.xfinity.com/login', data=data) 46 | assert res.status_code == 200 47 | 48 | logger.debug("Fetching internet usage AJAX...") 49 | res = session.get('https://customer.xfinity.com/apis/services/internet/usage') 50 | #logger.debug("Resp: %r", res.text) 51 | assert res.status_code == 200 52 | 53 | js = json.loads(res.text) 54 | 55 | out = { 56 | 'raw': js, 57 | 'used': js['usageMonths'][-1]['homeUsage'], 58 | 'total': js['usageMonths'][-1]['allowableUsage'], 59 | 'unit': js['usageMonths'][-1]['unitOfMeasure'], 60 | } 61 | print(json.dumps(out)) 62 | 63 | # Print JSON to file 64 | with open(json_file, 'w+') as outfile: 65 | json.dump(out, outfile, sort_keys=True) -------------------------------------------------------------------------------- /img/Card.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astromgren/Comcast_Data_Usage/42c42bedd60779dfe7fd9f24f1f752c9235a7050/img/Card.PNG -------------------------------------------------------------------------------- /img/a.txt: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------