Purple Air AQI Solution found but can't get it to work

It’s been enough years since I ran this that the best I can do is say ‘used to work for me’ and suggest you try to look at previous examples folks have posted here. Unfortunately the forum software WF uses is BEYOND AWFUL in terms of search capabilities so it might be a bit of work.

Worst case take Pete’s example - install that, see that work, and build up step by step.

I think I duplicated your issue.

I pulled out my SD card with wfpiconsole on it and updated the console version to the current version to retest.

The test:

  • I set the PurpleAir panel as panel1 (primary) it works just fine…
  • and when I click on the button bottom-left to go to the Secondary PanelOne it works…
  • BUT…when I click again on the button bottom-left to go ‘back’ to the custom panel it throws that same error you are experiencing…

@peter can you take a look at this code please and chime in here ?

#-----------------------------
# user/customPanels.py
#------------------------------
from kivy.uix.relativelayout import RelativeLayout
from panels.template         import panelTemplate
from kivy.properties         import Clock
from kivy.properties         import StringProperty

import requests
import json

#-----------------------------------
# do all the grabbing the data here
#-----------------------------------
class ExamplePanel(panelTemplate):

    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.updateData()
        Clock.schedule_interval(self.updateData,59)

    def updateData(self, *args):

        data = self.get_data()

        # set the kivy panel element text
        self.ids.example_label.text = data

    def get_data(self):

        try:
            # API endpoint URL for a PurpleAir AQI sensor
            url = "http://192.168.2.33/json"
            return str(response['current_temp_f'])
        except:
            return "n/a"


#---------------------------------------
# user/customPanels.kv
#---------------------------------------

<ExamplePanel>:
    PanelBackground:
        _panelTitle: 'PurpleAir AQI'
    Label:
        id: example_label
        text: ''
        pos_hint: {'x': 0, 'y': 0}
        size_hint: (1, 1)
        font_name: 'fonts/Inter-Bold.ttf'
        font_size: dp(100*app.scaleFactor)
        color: utils.rgba('#ff0404ff')
        valign: 'center'
        halign: 'center'
        markup: 1
<ExampleButton>:
    PanelButton:
        text: 'Example'
        on_release: app.CurrentConditions.switchPanel(self)

To save you the research, I based mine on Custom panel to display tide information - #12 by robert.jochim if not others. Unfortunately it’s been enough years that I don’t remember which other threads I might have used as references.

(from the logfile)
WARNING: running xinput against an Xwayland server. See the xinput man page for details.
WARNING: running xinput against an Xwayland server. See the xinput man page for details.
WARNING: running xinput against an Xwayland server. See the xinput man page for details.
[INFO   ] [Base        ] Start application main loop
[WARNING] [request_api ] 2026-09-01 18:32:39 - last_6h call failed
[INFO   ] [Base        ] Leaving application in progress...
Traceback (most recent call last):
  File "/home/pi/wfpiconsole/main.py", line 621, in <module>
    wfpiconsole_app.run()
    ~~~~~~~~~~~~~~~~~~~^^
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/app.py", line 956, in run
    runTouchApp()
    ~~~~~~~~~~~^^
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/base.py", line 574, in runTouchApp
    EventLoop.mainloop()
    ~~~~~~~~~~~~~~~~~~^^
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/base.py", line 339, in mainloop
    self.idle()
    ~~~~~~~~~^^
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/base.py", line 383, in idle
    self.dispatch_input()
    ~~~~~~~~~~~~~~~~~~~^^
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/base.py", line 334, in dispatch_input
    post_dispatch_input(*pop(0))
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/base.py", line 302, in post_dispatch_input
    wid.dispatch('on_touch_up', me)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/uix/behaviors/button.py", line 179, in on_touch_up
    self.dispatch('on_release')
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "kivy/_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
  File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
  File "kivy/_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
  File "/home/pi/wfpiconsole/venv/lib/python3.13/site-packages/kivy/lang/builder.py", line 60, in custom_callback
    exec(__kvlang__.co_value, idmap)
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pi/wfpiconsole/user/customPanels.kv", line 23, in <module>
    on_release: app.CurrentConditions.switchPanel(self)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pi/wfpiconsole/main.py", line 605, in switchPanel
    self.ids[button_data[1]].add_widget(eval(new_panel + 'Panel')(mode))
                                        ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
TypeError: ExamplePanel.__init__() takes 1 positional argument but 2 were given
[INFO   ] [UDP         ] 2026-09-01 18:32:51 - Closing socket
[INFO   ] [UDP         ] 2026-09-01 18:32:51 - Socket closed

And from the .ini file…

[PrimaryPanels]
PanelOne = Example
PanelTwo = Temperature
PanelThree = WindSpeed
PanelFour = SunriseSunset
PanelFive = Rainfall
PanelSix = Barometer

[SecondaryPanels]
PanelOne = Sager
PanelTwo = Forecast
PanelThree =
PanelFour = MoonPhase
PanelFive =
PanelSix = Lightning

I appreciate your digging that out. I’ll give it a try asap.

I think a small change needs to be made to the init method in the .py file.

It should be:

def __init__(self, mode=None, **kwargs):
    super().__init__(mode, **kwargs)

rather than:

def __init__(self,**kwargs):
    super().__init__(**kwargs)

Thanks @peter - I revisited the example mine was based on and lined mine up accordingly.

Edit - this worked…

def __init__(self,mode=None,**kwargs):
        super().__init__(mode,**kwargs)

@propgrinder try the above. No other changes in what I posted yesterday.

That’s really funny. I read your reply backwards. Fortunately I wound up with what you told me to do. Must find more coffee…

Success! Thank you Peter and vinceskahan for all your assistance.