MKANET

Roblox Custom Integration bug

Sep 9th, 2023
1,398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.89 KB | None | 0 0
  1. """Sensor for roblox account status."""
  2. from datetime import timedelta
  3. import logging
  4. import requests
  5.  
  6. from time import mktime
  7.  
  8. import voluptuous as vol
  9.  
  10. from homeassistant.components.sensor import PLATFORM_SCHEMA
  11. from homeassistant.const import CONF_API_KEY
  12. from homeassistant.core import callback
  13. import homeassistant.helpers.config_validation as cv
  14. from homeassistant.helpers.entity import Entity
  15. from homeassistant.helpers.event import track_time_interval
  16. from homeassistant.util.dt import utc_from_timestamp
  17.  
  18. _LOGGER = logging.getLogger(__name__)
  19.  
  20. CONF_ACCOUNTS = "accounts"
  21.  
  22. ICON = "mdi:robot-outline"
  23.  
  24. roblox_cookie = ""
  25.  
  26. PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
  27.     {
  28.         vol.Required(CONF_API_KEY): cv.string,
  29.         vol.Required(CONF_ACCOUNTS, default=[]): vol.All(cv.ensure_list, [cv.string]),
  30.     }
  31. )
  32.  
  33.  
  34. BASE_INTERVAL = timedelta(minutes=.25)
  35.  
  36.  
  37. def setup_platform(hass, config, add_entities, discovery_info=None):
  38.     """Set up the roblox platform."""
  39.  
  40.     roblox_cookie = config.get(CONF_API_KEY)
  41.     # Initialize robloxmods app list before creating sensors
  42.     # to benefit from internal caching of the list.
  43.  
  44.     entities = [
  45.         robloxSensor(account, roblox_cookie) for account in config.get(CONF_ACCOUNTS)
  46.     ]
  47.     if not entities:
  48.         return
  49.     add_entities(entities, True)
  50.  
  51.     # Only one sensor update once every 60 seconds to avoid
  52.     # flooding roblox and getting disconnected.
  53.     entity_next = 0
  54.  
  55.     @callback
  56.     def do_update(time):
  57.         nonlocal entity_next
  58.         entities[entity_next].async_schedule_update_ha_state(True)
  59.         entity_next = (entity_next + 1) % len(entities)
  60.  
  61.     track_time_interval(hass, do_update, BASE_INTERVAL)
  62.  
  63.  
  64. class robloxSensor(Entity):
  65.     """A class for the roblox account."""
  66.  
  67.     def __init__(self, account, robloxod):
  68.         """Initialize the sensor."""
  69.         self._robloxod = robloxod
  70.         self._account = account
  71.         self._profile = None
  72.         self._game = None
  73.         self._game_id = None
  74.         self._extra_game_info = None
  75.         self._state = None
  76.         self._name = None
  77.         self._avatar = None
  78.         self._last_online = None
  79.         self._level = None
  80.         self._owned_games = None
  81.         self._gameurl = None
  82.         self._game_image_header = None
  83.         self._game_image_main = None
  84.         self._placeId = None
  85.         self._universeId = None
  86.        
  87.     @property
  88.     def name(self):
  89.         """Return the name of the sensor."""
  90.         return self._name
  91.  
  92.     @property
  93.     def entity_id(self):
  94.         """Return the entity ID."""
  95.         return f"sensor.roblox_{self._account}"
  96.  
  97.     @property
  98.     def state(self):
  99.         """Return the state of the sensor."""
  100.         return self._state
  101.  
  102.     @property
  103.     def should_poll(self):
  104.         """Turn off polling, will do ourselves."""
  105.         return False
  106.  
  107.     def update(self):
  108.         """Update device state."""
  109.         try:
  110.             r = requests.get("https://www.roblox.com/profile?userId=" + self._account)
  111.             data = r.json()
  112.             self._name = data["Username"]
  113.             #self._avatar = data["AvatarUri"]
  114.            
  115.             # Get Headshot
  116.             headers = {
  117.                 'accept': 'application/json',
  118.             }
  119.  
  120.             params = {
  121.                 'userIds': self._account,
  122.                 'size': '48x48',
  123.                 'format': 'Png',
  124.                 'isCircular': 'false',
  125.             }
  126.  
  127.             response = requests.get('https://thumbnails.roblox.com/v1/users/avatar-headshot', params=params, headers=headers)
  128.             self._avatar = response.json().get('data')[0].get('imageUrl')
  129.            
  130.             # Get Presence
  131.             cookies_dict = {".ROBLOSECURITY": self._robloxod}
  132.             headers = {
  133.                 "accept": "application/json",
  134.                 "Content-Type": "application/json",
  135.             }
  136.  
  137.             json_data = {
  138.                 "userIds": [
  139.                     self._account,
  140.                 ],
  141.             }
  142.             response = requests.post(
  143.                 "https://presence.roblox.com/v1/presence/users",
  144.                 headers=headers,
  145.                 json=json_data,
  146.                 cookies=cookies_dict,
  147.             )
  148.             data = response.json()
  149.             userPresence = data.get("userPresences")[0]
  150.             self._game_id = userPresence.get("gameId")
  151.            
  152.             self._last_online = userPresence.get("lastOnline")
  153.             self._placeId = userPresence.get("placeId")
  154.             self._game = userPresence.get("lastLocation")
  155.             self._universeId = userPresence.get("universeId")
  156.            
  157.             isOnline = int(userPresence.get("userPresenceType")) > 0
  158.             if isOnline:
  159.                 self._state = "online"    
  160.             else:
  161.                 self._state = "offline"
  162.                 self._game = "offline"
  163.            
  164.             if self._universeId is not None:
  165.                 r = requests.get('https://thumbnails.roblox.com/v1/games/multiget/thumbnails?universeIds=' + str(self._universeId) + '&countPerUniverse=1&defaults=true&size=768x432&format=Png&isCircular=false')
  166.                 data = r.json()
  167.                 self._game_image_header = data['data'][0]['thumbnails'][0]['imageUrl']
  168.                 self._game_image_main = data['data'][0]['thumbnails'][0]['imageUrl']
  169.                 # self._gameurl = 'https://www.roblox.com/games/' + str(placeId)
  170.         except:
  171.             self._game = None
  172.             self._game_id = None
  173.             self._state = None
  174.             self._name = None
  175.             self._avatar = None
  176.             self._last_online = None
  177.             self._level = None
  178.             self._game_image_header = None
  179.             self._game_image_main = None
  180.             self._gameurl = None
  181.             self._placeId = None
  182.             self._universeId = None
  183.  
  184.     @property
  185.     def extra_state_attributes(self):
  186.         """Return the state attributes."""
  187.         attr = {}
  188.         if self._game is not None:
  189.             attr["game"] = self._game
  190.         if self._game_id is not None:
  191.             attr["game_id"] = self._game_id
  192.             attr["place_id"] = self._placeId
  193.             # game_url = f"{roblox_API_URL}{self._game_id}/"
  194.             attr["game_image_header"] = self._game_image_header
  195.             attr["game_image_main"] = self._game_image_main
  196.         else:
  197.             attr["game_image_header"] = "https://hassio.mka.net/local/images/blankdot.png"
  198.             attr["game_image_main"] = "https://hassio.mka.net/local/images/blankdot.png"
  199.  
  200.         if self._last_online is not None:
  201.             attr["last_online"] = self._last_online
  202.  
  203.         return attr
  204.  
  205.     @property
  206.     def entity_picture(self):
  207.         """Avatar of the account."""
  208.         return self._avatar
  209.  
  210.     @property
  211.     def icon(self):
  212.         """Return the icon to use in the frontend."""
  213.         return ICON
  214.  
Advertisement
Add Comment
Please, Sign In to add comment