Get value from Appdaemon app into custom_component

How can I send a variable derived from an Appdaemon app into a custom_component?

I want to do the following:

  1. Create a custom_component
  2. Use the users setting from config.yml and add them in the Appdaemon code (user_key and name_override should come from config.yaml of the custom_component)
  3. Send the variable that I got in Appdaemon back to my custom_component state. (ATTR_BALANCE should show in the custom_components state)

Appdaemon code:

import appdaemon.plugins.hass.hassapi as hass
import logging
import time

CONF_ID = "id"
CONF_ACCOUNT_KEY = "user_key" 
CONF_NAME_OVERRIDE = "name_override"

SENSOR_PREFIX = "Kadenabalance "

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
     
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', options=chrome_options)

driver.get("https://balance.chainweb.com/index.html")
time.sleep(5)
driver.find_element_by_id("account").send_keys (CONF_ACCOUNT_KEY)
driver.find_element_by_class_name("button").click()
time.sleep(5)
ATTR_BALANCE = driver.find_element_by_id("chain-0-balance-data").text

_LOGGER = logging.getLogger(__name__)
class KadenaBalance(hass.Hass):

  def initialize(self):
     self.log("KedenaBalance Is:")
     self.log(ATTR_BALANCE)

How can I run the following code at 7Am and 7PM of everyday?

import appdaemon.plugins.hass.hassapi as hass
import logging
import time
import datetime

CONF_ID = "id"
CONF_ACCOUNT_KEY = "user_key"
CONF_NAME_OVERRIDE = "name_override"

SENSOR_PREFIX = "Kadenabalance "

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
     
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', options=chrome_options)
driver.get("https://balance.chainweb.com/index.html")
time.sleep(5)
driver.find_element_by_id("account").send_keys (CONF_ACCOUNT_KEY)
driver.find_element_by_class_name("button").click()
time.sleep(5)
ATTR_BALANCE = driver.find_element_by_id("chain-0-balance-data").text

_LOGGER = logging.getLogger(__name__)

class KadenaBalance(hass.Hass):
  def initialize(self):
     self.log("KedenaBalance Is:")
     self.log(ATTR_BALANCE)
     self.call_service("state/set", entity_id="sensor.kda_balance", state=ATTR_BALANCE, attributes={"friendly_name" : "Kadena Balance"}, namespace="default")

I did the following but it doesn’t seem to run my code and update my variables state:

import appdaemon.plugins.hass.hassapi as hass
import logging
import time
import datetime
from datetime import timezone

CONF_ACCOUNT_KEY = "user_key"

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
     
class KadenaBalance(hass.Hass):
  def initialize(self):
     chrome_options = Options()
     chrome_options.add_argument('--headless')
     chrome_options.add_argument('--no-sandbox')
     chrome_options.add_argument('--disable-gpu')
     chrome_options.add_argument('--disable-dev-shm-usage')
     driver = webdriver.Chrome('chromedriver', options=chrome_options)
     driver.get("https://balance.chainweb.com/index.html")
     time.sleep(5)
     driver.find_element_by_id("account").send_keys (CONF_ACCOUNT_KEY)
     driver.find_element_by_class_name("button").click()
     time.sleep(5)
     ATTR_BALANCE = float(driver.find_element_by_id("chain-0-balance-data").text)
     my_formatter = "{0:.2f}"
     output = my_formatter.format(ATTR_BALANCE)
     self.log(output)
     self.call_service("state/set", entity_id="sensor.kda_balance", state=output, attributes={"friendly_name" : "Kadena Balance"}, namespace="default")
  def run_hourly(self, callback, start, **kwargs):
     name = self.name
     now = ha.get_now()
     if start == None:
       event = now + datetime.timedelta(hours=1)
     else:
       event = now
       event = event.replace(minute = start.minute, second = start.second)
       if event < now:
         event = event + datetime.timedelta(hours=1)    
     handle = self.run_every(callback, event, 60 * 60, **kwargs)
     return handle

Not sure if you were able to get this but it’s going to need a lot of work. I would move all of the scraping work into its own method and probably multiple methods for your case.

It is recommended against using time.sleep() in AppDaemon, it will tie up the thread, probably cause thread starvation and prevent other apps from running. If you need to wait some time before performing the next step, you’ll want to use the run_in() method or re-write the app as asynchronous, which isn’t recommended unless you’re experienced with AD.

You have run_hourly() but there is nothing within initialize() (or any other method besides the scheduler callback itself) calling the run_hourly() method and the signature for scheduler calls should be scheduled_callback(self, kwargs). Also, a scheduler callback wont return a handle but the scheduler method will, such as self.handle = self.run_hourly(self.scheduled_callback, 5)