AppDaemon - how to do OO

Hi,

I’m using AppDaemon for quite some time and happy about it… I use some Object Oriented programming in it and it works perfectly.

Since my file is now getting quite large, I’d like to split it into multiple files, one per class. But, once I start to do:

from test import Test

where Test is a simple class, it works fine the first time. However, if I do any changes to Test, my main app does not see it. Even if I delete the file from __pycache__, reload the main app, AppDaemon refuses to see my changes.

Any idea on how to fix that?

P.s.: I know I can split up apps in AppDaemon but I’m not a big fan of all the config files you then need. My current config file is simple and to the point, like this (some complex examples):

room_automation:
  module: room_automation
  class: RoomAutomation
  rooms:
    badkamer:
      switch_to_light:
        - badkamer_licht -> badkamer_licht_1
      velux: badkamer_velux
      window_sunshade: 
        cover: badkamer_zonwering
        orientation: wall_1
      climate: 
        thermostat: thermostaat_badkamer
        preheat_temperature: 22
        schedule:
          '06:00:00': 22
          '07:30:00': 16
          '19:30:00': 22
          '21:30:00': 16
      media_player: media_player.badkamer
    waskot:
      switch_to_light:
        - waskot_licht -> waskot_licht_1,waskot_licht_2
      velux: waskot_velux
      media_player: media_player.den
    slaapkamer_1:
      switch_to_light: 
        - slaapkamer_1_licht_1
        - slaapkamer_1_licht_2
      velux: slaapkamer_1_velux
      window_sunshade: 
        cover: slaapkamer_1_zonwering
        orientation: wall_1
      antimuggen:
        from: '20:15:00'
        to: '06:30:00'
    slaapkamer_2:
      switch_to_light: 
        - slaapkamer_2_licht_1
        - slaapkamer_2_licht_2
      velux: slaapkamer_2_velux
      antimuggen:
        from: '21:30:00'
        to: '06:31:00'

Each item below a room is an actual class which has it’s own state, …

Not really sure if this is whatbyou need but what about AppDaemons get_app() method to create a refernec to another app?

You can add the imported file as a global_module, and add it to the apps global dependencies. So when the imported file changes, AD sees it, and will reload the app automatically for you, so it picks up the changes.

Regards

2 Likes

@Odianosen25 that was the solution… you are a hero!!

Now I can do proper OO in my AppDaemon python modules. Thanks!

That’s true but then the app is managed by AppDaemon and a singleton. I want to create multiple instances of certain classes, so this doesn’t work.

2 Likes

Ah I understand, seems like I misunderstood :slightly_smiling_face:

In order to get global_modules to properly reload apps you need some extra config. Your YAML should look like this:

global_modules:
  - some_module

some_app:
  global_dependencies:
    - some_module
  module: whatever
  class: WhateverApp

Alternatively, if you’re using the AD 4 beta, you can do this:

global_modules:
  - some_module

some_app:
  module: whatever
  class: WhateverApp

And then in the code for some_app:

import some_module

class WhateverApp:
  def initialize(self):
    self.depends_on_module(some_module)

This allows you to leave the dependency portion out of the YAML and still get the reloads happening correctly.

3 Likes

I’m bumping this topic because it’s the only one that is close to my issue.

I’d also like to do OO programming and split my code among different classes. But I don’t want to use the get_app feature as it creates singletons and I need to have my dependency maintain their proper state/variables (aka transient dependencies)

Therefore, I need to split my code in the pythonic way with import. In my dependencies, I would like to get access to the HASS plugin, in order to call methods such as get_state. How could I do that? The only way I think of would be to inject the current AD app in the constructor of my dependency (self), but it looks ugly as a circular dependency. :frowning:

Thanks in advance !