Bottom line, I wrote a custom component back in July 2018 and all worked as expected. My next Home Assistant software update was December 2018.
The error is:
Log Details (ERROR)
Fri Jan 18 2019 07:58:34 GMT-0600 (Central Standard Time)
Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/discovery.py", line 151, in async_load_platform
assert hass_config, 'You need to pass in the real hass config'
AssertionError: You need to pass in the real hass config
I will post some relevant details later, but first, let me set some context via a story. I did a custom component, I called “Almond_Plus”, that supported a switch and covers back in July of 2018. I have not had time to mess with Home Assistant in awhile. Knowing that things are changing fast (user login, Lovelace UI, entities naming, …), I did not want to far behind and then have to make a big jump. Too late. When I did update, the switches and covers from my custom components quit showing up. At that time I assumed I needed to make some changes to my code. I did not have time to mess with it and still don’t. But I did take a closer look at the log this morning. I have what I call a virtual switches. They are named “paul_on_way_home_switch” and “testswitch”. I can ask Google to trun on “my way home”, and the virtual switch is turned on and the correct automation ran. Under the current entities both “paul_on_way_home” and it’s debugging counterpart “testswitch” show up. I was following my debugging information from almond_plus that writes to the log.
Now for the details. I will attempt to present them in what I see as more relevant to “I don’t know if you need this but here it is”.
Here is a snippet of the log focused on the virtual switches mixed in with the Almond_plus debug statements …
2019-01-18 07:58:32 DEBUG (SyncWorker_9) [custom_components.almond_plus] Loading switch platform
2019-01-18 07:58:32 DEBUG (SyncWorker_9) [custom_components.almond_plus] Loading cover platform
2019-01-18 07:58:34 DEBUG (SyncWorker_9) [custom_components.almond_plus] switch list 1: ['switch.paul_on_way_home_switch', 'switch.testswitch']
2019-01-18 07:58:34 DEBUG (SyncWorker_9) [custom_components.almond_plus] switch list 2: None
2019-01-18 07:58:34 DEBUG (SyncWorker_9) [custom_components.almond_plus] cover list 1: []
2019-01-18 07:58:34 DEBUG (SyncWorker_9) [custom_components.almond_plus] cover list 2: None
2019-01-18 07:58:34 DEBUG (SyncWorker_9) [custom_components.almond_plus] Setup ended with True
2019-01-18 07:58:34 INFO (MainThread) [homeassistant.setup] Setup of domain almond_plus took 4.5 seconds.
Here is the almond_plus.py set up code.
def setup(hass, config):
"""Set up the Almond+ component."""
return_status = False
try:
global myhass_data
myhass_data = {}
myhass_data["config"] = config[DOMAIN]
connect_url = config[DOMAIN][CONF_URL]
myhass_data["almondplus_api"] = AlmondPlus(connect_url, almond_plus_call_back)
myhass_data["almondplus_switch_entities"] = None
myhass_data["almondplus_cover_entities"] = None
hass.data[DATA_ALMONDPLUS] = myhass_data
hass.data[DATA_ALMONDPLUS]["almondplus_api"].start()
time.sleep(2)
_LOGGER.debug("Test Almond+ setup: "+str(hass.data[DATA_ALMONDPLUS]["almondplus_api"].get_device_list()))
_LOGGER.debug("Loading switch platform")
load_platform(hass, 'switch', DOMAIN, discovered=None, hass_config=None)
_LOGGER.debug("Loading cover platform")
load_platform(hass, 'cover', DOMAIN, discovered=None, hass_config=None)
time.sleep(2)
switches = sorted(hass.states.async_entity_ids('switch'))
_LOGGER.debug("switch list 1: "+str(switches))
tmp_switches = myhass_data["almondplus_switch_entities"]
_LOGGER.debug("switch list 2: "+str(tmp_switches))
covers = sorted(hass.states.async_entity_ids('cover'))
_LOGGER.debug("cover list 1: "+str(covers))
tmp_covers = myhass_data["almondplus_cover_entities"]
_LOGGER.debug("cover list 2: "+str(tmp_covers))
return_status = True
except Exception as e:
_LOGGER.error("Error\n"
+"**************************\n"
+ str(e) + "\n"
+ traceback.format_exc()
+ "**************************")
_LOGGER.debug("Setup ended with "+str(return_status))
return return_status
Looking at the code, I expect “Switch list 1:” to be the list of current switches. Then “Switch list 2:” should show the switches that were read created in the platform for the switches.
Here is the code for that.
def setup_platform(hass, config, add_devices, discovery_info=None):
global my_almond_plus
return_value = False
try:
_LOGGER.debug("Started - find me 2")
my_almond_plus = hass.data[DATA_ALMONDPLUS]["almondplus_api"]
switches = []
_LOGGER.debug("looking for devices (switch)")
for almond_key, almond_entity in my_almond_plus.get_device_list().items():
if almond_entity.value_type == "1":
tmp = AlmondPlusSwitch(almond_entity)
_LOGGER.debug("Device -"+tmp.id+", "+tmp.device_id+", "+tmp.state+", "+tmp.name)
switches.append(tmp)
#switches.append(AlmondPlusSwitch(almond_entity))
if len(switches) > 0:
add_devices(switches)
hass.data[DATA_ALMONDPLUS]["almondplus_switch_entities"] = switches
return_value = True
except Exception as e:
_LOGGER.error("Error\n"
+ "**************************\n"
+ str(e) + "\n"
+ traceback.format_exc()
+ "**************************")
_LOGGER.debug("Setup ended with " + str(return_value))
return return_value
One other note, the AlmondPlusSwitch class code is …
class AlmondPlusSwitch(SwitchDevice):
"""Representation of an Almond+ switch."""
def __init__(self, device):
self._id = None
self._device_id = None
self._name = None
self._state = None
"""Attributes"""
self.friendly_device_type = None
self.type = None
self.location = None
self.last_active_epoch = None
self.model = None
self.value_name = None
self.value_value = None
self.value_type = None
self._update_properties(device)
def _update_properties(self, device):
self._id = device.id
self._device_id = device.device_id
self._name = DOMAIN+"_"+device.name + '_' + device.id + '_' + device.device_id
self._state = ''
self.set_state(device.value_value)
"""Attributes"""
self.friendly_device_type = device.friendly_device_type
self.type = device.type
self.location = device.location
self.last_active_epoch = device.last_active_epoch
self.model = device.model
self.value_name = device.value_name
self.value_value = device.value_value
self.value_type = device.value_type
@property
def name(self):
"""Get the name of the pin."""
return self._name
@property
def id(self):
"""Get the name of the pin."""
return self._id
@property
def device_id(self):
"""Get the name of the pin."""
return self._device_id
@property
def is_on(self):
"""Return true if pin is high/on."""
_LOGGER.debug("is_on "+self.name+"-"+self._state)
return self._state == "on"
@property
def should_poll(self):
return False
def turn_on(self, **kwargs):
_LOGGER.debug("Turn on")
my_almond_plus.set_device(self.id, self.device_id, "true")
def turn_off(self, **kwargs):
_LOGGER.debug("Turn off")
self._state = 'off'
my_almond_plus.set_device(self.id, self.device_id, "false")
@property
def device_state_attributes(self):
"""Return the optional state attributes."""
data = {}
data["id"] = self._id
data["device_id"] = self._device_id
data["friendly_device_type"] = self.friendly_device_type
data["type"] = self.type
data["location"] = self.location
data["last_active_epoch"] = self.last_active_epoch
data["last_active_datetime"] = datetime.datetime.fromtimestamp(int(self.last_active_epoch))
data["model"] = self.model
data["value_name"] = self.value_name
data["value_value"] = self.value_value
data["value_type"] = self.value_type
return data
def update(self, device):
_LOGGER.debug("Switch Update -"+self._id+"-"+self.device_id+"-")
self._update_properties(device)
self.schedule_update_ha_state()
def set_state(self, value_value):
_LOGGER.debug("Setting State -"+value_value+"-"+value_value.lower()+"-")
if value_value.lower() == "true":
self._state = 'on'
#self.turn_on()
_LOGGER.debug("Setting on "+self._state)
elif value_value.lower() == "false":
self._state = 'off'
#self.turn_off()
_LOGGER.debug("Setting off "+self._state)
else:
self._state = 'unknown'
_LOGGER.debug("Setting unknown " + self._state)
_LOGGER.debug("Setting State Finish "+self._state)
This next part of the log I am showing is kind of long. It is the payload that makes it look complicated. The 30,000-foot view of it is that a message is sent and the Almond+ responded.
2019-01-18 07:58:31 DEBUG (SyncWorker_9) [custom_components.almond_plus] sending {"MobileInternalIndex":"239d7b4e-1b29-11e9-82a5-080027c659bb","CommandType":"DeviceList"}
2019-01-18 07:58:31 DEBUG (SyncWorker_9) [custom_components.almond_plus] Sent
2019-01-18 07:58:31 DEBUG (SyncWorker_9) [custom_components.almond_plus] After send
2019-01-18 07:58:31 DEBUG (Thread-3) [custom_components.almond_plus] {"MobileInternalIndex":"239d7b4e-1b29-11e9-82a5-080027c659bb","CommandType":"DeviceList","Devices" : {"2":{"Data":{"ID":"2","Name":"Under Cabinet MultiSwitch","FriendlyDeviceType":"BinarySwitch","Type":"43","Location":"Under Cabinet","LastActiveEpoch":"1547819073","Model":"Unknown: type=2017,","Version":"4","Manufacturer":"YALE"},"DeviceValues":{"1":{"Name":"SWITCH_BINARY1","Value":"true","Type":"1"},"2":{"Name":"SWITCH_BINARY2","Value":"false","Type":"1"}}},"4":{"Data":{"ID":"4","Name":"GarageDoorOpener Two Car","FriendlyDeviceType":"GarageDoorOpener","Type":"53","Location":"Default","LastActiveEpoch":"1547819063","Model":"Unknown: type=4744,","Version":"0","Manufacturer":"Linear"},"DeviceValues":{"1":{"Name":"BARRIER OPERATOR","Value":"0","Type":"44"}}},"5":{"Data":{"ID":"5","Name":"Garage Lights Inside/Outside","FriendlyDeviceType":"BinarySwitch","Type":"43","Location":"Default","LastActiveEpoch":"1547813298","Model":"Unknown: type=2017,","Version":"4","Manufacturer":"YALE"},"DeviceValues":{"1":{"Name":"SWITCH_BINARY1","Value":"false","Type":"1"},"2":{"Name":"SWITCH_BINARY2","Value":"false","Type":"1"}}},"6":{"Data":{"ID":"6","Name":"Vaulted Ceiling/Porch Light","FriendlyDeviceType":"BinarySwitch","Type":"43","Location":"Default","LastActiveEpoch":"1546315987","Model":"Unknown: type=2017,","Version":"4","Manufacturer":"YALE"},"DeviceValues":{"1":{"Name":"SWITCH_BINARY1","Value":"false","Type":"1"},"2":{"Name":"SWITCH_BINARY2","Value":"false","Type":"1"}}},"7":{"Data":{"ID":"7","Name":"Almond Click Purp","FriendlyDeviceType":"SecurifiButton","Type":"61","Location":"Default","LastActiveEpoch":"1547819073","Model":"ZB2-BU01 ","Version":"0","Manufacturer":"Securifi L"},"DeviceValues":{"1":{"Name":"PRESS","Value":"3","Type":"91"},"2":{"Name":"LOW BATTERY","Value":"false","Type":"12"},"3":{"Name":"TAMPER","Value":"false","Type":"9"}}},"8":{"Data":{"ID":"8","Name":"Outside outlet Entryway","FriendlyDeviceType":"BinarySwitch","Type":"1","Location":"Default","LastActiveEpoch":"1547816950","Model":"Unknown: type=2017,","Version":"4","Manufacturer":"YALE"},"DeviceValues":{"1":{"Name":"SWITCH BINARY","Value":"false","Type":"1"}}},"9":{"Data":{"ID":"9","Name":"Power Strip 1","FriendlyDeviceType":"BinarySwitch","Type":"1","Location":"Default","LastActiveEpoch":"1546349943","Model":"ZFM-80","Version":"4","Manufacturer":"Remotec"},"DeviceValues":{"1":{"Name":"SWITCH BINARY","Value":"false","Type":"1"}}},"10":{"Data":{"ID":"10","Name":"yellow click","FriendlyDeviceType":"SecurifiButton","Type":"61","Location":"Default","LastActiveEpoch":"1542916780","Model":"ZB2-BU01 ","Version":"0","Manufacturer":"Securifi L"},"DeviceValues":{"1":{"Name":"PRESS","Value":"0","Type":"91"},"2":{"Name":"LOW BATTERY","Value":"false","Type":"12"},"3":{"Name":"TAMPER","Value":"false","Type":"9"}}},"11":{"Data":{"ID":"11","Name":"GarageDoorOpener One Car","FriendlyDeviceType":"GarageDoorOpener","Type":"53","Location":"Default","LastActiveEpoch":"1547819864","Model":"Unknown: type=4744,","Version":"0","Manufacturer":"Linear"},"DeviceValues":{"1":{"Name":"BARRIER OPERATOR","Value":"0","Type":"44"}}}}}
2019-01-18 07:58:31 DEBUG (Thread-3) [custom_components.almond_plus] load send rec: 239d7b4e-1b29-11e9-82a5-080027c659bb-{"MobileInternalIndex": "239d7b4e-1b29-11e9-82a5-080027c659bb", "CommandType": "DeviceList", "Devices": {"2": {"Data": {"ID": "2", "Name": "Under Cabinet MultiSwitch", "FriendlyDeviceType": "BinarySwitch", "Type": "43", "Location": "Under Cabinet", "LastActiveEpoch": "1547819073", "Model": "Unknown: type=2017,", "Version": "4", "Manufacturer": "YALE"}, "DeviceValues": {"1": {"Name": "SWITCH_BINARY1", "Value": "true", "Type": "1"}, "2": {"Name": "SWITCH_BINARY2", "Value": "false", "Type": "1"}}}, "4": {"Data": {"ID": "4", "Name": "GarageDoorOpener Two Car", "FriendlyDeviceType": "GarageDoorOpener", "Type": "53", "Location": "Default", "LastActiveEpoch": "1547819063", "Model": "Unknown: type=4744,", "Version": "0", "Manufacturer": "Linear"}, "DeviceValues": {"1": {"Name": "BARRIER OPERATOR", "Value": "0", "Type": "44"}}}, "5": {"Data": {"ID": "5", "Name": "Garage Lights Inside/Outside", "FriendlyDeviceType": "BinarySwitch", "Type": "43", "Location": "Default", "LastActiveEpoch": "1547813298", "Model": "Unknown: type=2017,", "Version": "4", "Manufacturer": "YALE"}, "DeviceValues": {"1": {"Name": "SWITCH_BINARY1", "Value": "false", "Type": "1"}, "2": {"Name": "SWITCH_BINARY2", "Value": "false", "Type": "1"}}}, "6": {"Data": {"ID": "6", "Name": "Vaulted Ceiling/Porch Light", "FriendlyDeviceType": "BinarySwitch", "Type": "43", "Location": "Default", "LastActiveEpoch": "1546315987", "Model": "Unknown: type=2017,", "Version": "4", "Manufacturer": "YALE"}, "DeviceValues": {"1": {"Name": "SWITCH_BINARY1", "Value": "false", "Type": "1"}, "2": {"Name": "SWITCH_BINARY2", "Value": "false", "Type": "1"}}}, "7": {"Data": {"ID": "7", "Name": "Almond Click Purp", "FriendlyDeviceType": "SecurifiButton", "Type": "61", "Location": "Default", "LastActiveEpoch": "1547819073", "Model": "ZB2-BU01 ", "Version": "0", "Manufacturer": "Securifi L"}, "DeviceValues": {"1": {"Name": "PRESS", "Value": "3", "Type": "91"}, "2": {"Name": "LOW BATTERY", "Value": "false", "Type": "12"}, "3": {"Name": "TAMPER", "Value": "false", "Type": "9"}}}, "8": {"Data": {"ID": "8", "Name": "Outside outlet Entryway", "FriendlyDeviceType": "BinarySwitch", "Type": "1", "Location": "Default", "LastActiveEpoch": "1547816950", "Model": "Unknown: type=2017,", "Version": "4", "Manufacturer": "YALE"}, "DeviceValues": {"1": {"Name": "SWITCH BINARY", "Value": "false", "Type": "1"}}}, "9": {"Data": {"ID": "9", "Name": "Power Strip 1", "FriendlyDeviceType": "BinarySwitch", "Type": "1", "Location": "Default", "LastActiveEpoch": "1546349943", "Model": "ZFM-80", "Version": "4", "Manufacturer": "Remotec"}, "DeviceValues": {"1": {"Name": "SWITCH BINARY", "Value": "false", "Type": "1"}}}, "10": {"Data": {"ID": "10", "Name": "yellow click", "FriendlyDeviceType": "SecurifiButton", "Type": "61", "Location": "Default", "LastActiveEpoch": "1542916780", "Model": "ZB2-BU01 ", "Version": "0", "Manufacturer": "Securifi L"}, "DeviceValues": {"1": {"Name": "PRESS", "Value": "0", "Type": "91"}, "2": {"Name": "LOW BATTERY", "Value": "false", "Type": "12"}, "3": {"Name": "TAMPER", "Value": "false", "Type": "9"}}}, "11": {"Data": {"ID": "11", "Name": "GarageDoorOpener One Car", "FriendlyDeviceType": "GarageDoorOpener", "Type": "53", "Location": "Default", "LastActiveEpoch": "1547819864", "Model": "Unknown: type=4744,", "Version": "0", "Manufacturer": "Linear"}, "DeviceValues": {"1": {"Name": "BARRIER OPERATOR", "Value": "0", "Type": "44"}}}}}
2019-01-18 07:58:31 DEBUG (Thread-3) [custom_components.almond_plus] receive ended
My guess is from the error I am not setting up the hass object with the new security the right way, but looking at the current dev docs, it looks like the way it is passed has not changed. I am hoping someone can point me in the right way.