Skip to content

Latest commit

 

History

History
280 lines (212 loc) · 11.8 KB

MODIFYING.md

File metadata and controls

280 lines (212 loc) · 11.8 KB

Overview

The AppDaemon is meant to be integrated into your application. Once you get the AppDaemon running, modify it to look like a part of your project.

Changing the config page looks

The page "public_html/index.html" contains all the configuration pages. Feel free to add your company logo, and make the page branding closer to your own such as the colors, font face and so on.

The accompanying Config.js and Config.css file are also relevant.

Adding default config files

The AppDaemon tries to update the existing configuration files with information entered by the user, but it is not intelligent.

If your product needs default configurations, either supply

  • No configuration block, or
  • A fully defined configuration block

In particular, do not supply a partial configuration block as part of your default system given to customers. The AppDaemon will not properly deal with these.

For example, the following configuration block in /etc/dhcpcd.conf is acceptable:

interface wlan0
    static ip_address=192.168.1.31/24
    static routers=192.168.1.1
    static domain_name_servers=1.1.1.1 1.0.0.1

This is a fully fleshed block, and will be parsed correctly. If the user makes changes, those changes will be edited inline and saved.

Having no configuration block is acceptable - AppDaemon detects this and will add a complete block if needed.

The following configuration block in /etc/dhcpcd.conf is not acceptable:

interface wlan0
    static ip_address=192.168.1.31/24

Since only a partial block is supplied, AppDaemon will not properly process it during the "save and reboot" process.

The same caveat applies to /etc/wpa_cupplicant/wpa_supplicant.conf: supply either no file, or a file with complete connection credentials.

Disabling network interfaces

Lines in the file AppDaemon/etc/netenable can selectively enable/disable network interfaces as needed.

For example, if your product uses an external WiFi dongle and you want to disable the built-in WiFi, place the following in AppDaemon/etc/netenable:

wlan0:  disable

On system boot, the AppDaemon will execute "ifconfig $IF down" for all disabled interfaces listed in that file.


Adding lines to the "About" page

Lines in the file AppDaemon/etc/about will be automatically added to the end of the "About" page.

Place descriptive text about your application in that file, and the end user will see it on the "About" page during configuration.

To reformat the About page, edit the function "PopulateAboutPage()" in Config.js as needed.


Removing panels

To remove unneeded panels from the system, it is sufficient to comment out the TOC button. The "About" page will notice the missing button and omit the information from the removed page.

For example, to remove "File Sharing" entirely, change this:

<table id="TOCTable">
    <tr><td><img id="WB" class="NavButton" src="images/Wifi.png"    title="Wifi"        onclick=GotoPage("ScanningPage") /></td><td><h2>Wifi        </h2></td></tr>
    <tr><td><img id="SN" class="NavButton" src="images/SysName.png" title="System name" onclick=GotoPage("SysNamePage")  /></td><td><h2>System Name </h2></td></tr>
    <tr><td><img id="NB" class="NavButton" src="images/Network.png" title="Network"     onclick=GotoPage("NetworkPage")  /></td><td><h2>Networking  </h2></td></tr>
    <tr><td><img id="SB" class="NavButton" src="images/Sharing.png" title="Sharing"     onclick=GotoPage("SharingPage")  /></td><td><h2>Sharing     </h2></td></tr>
    <tr><td><img id="AB" class="NavButton" src="images/About.png"   title="About"       onclick=GotoPage("AboutPage")    /></td><td><h2>About       </h2></td></tr>
    <tr><td><h2>&nbsp;</h2></td></tr>
    <tr><td><img class="NavButton" src="images/Review.png"  title="Review and save" onclick=GotoPage("ReviewPage")   /></td><td><h2>Review and save </h2></td></tr>
    </table>

###to this:

<table id="TOCTable">
    <tr><td><img id="WB" class="NavButton" src="images/Wifi.png"    title="Wifi"        onclick=GotoPage("ScanningPage") /></td><td><h2>Wifi        </h2></td></tr>
    <tr><td><img id="SN" class="NavButton" src="images/SysName.png" title="System name" onclick=GotoPage("SysNamePage")  /></td><td><h2>System Name </h2></td></tr>
    <tr><td><img id="NB" class="NavButton" src="images/Network.png" title="Network"     onclick=GotoPage("NetworkPage")  /></td><td><h2>Networking  </h2></td></tr>
<!--    <tr><td><img id="SB" class="NavButton" src="images/Sharing.png" title="Sharing"     onclick=GotoPage("SharingPage")  /></td><td><h2>Sharing     </h2></td></tr>-->
    <tr><td><img id="AB" class="NavButton" src="images/About.png"   title="About"       onclick=GotoPage("AboutPage")    /></td><td><h2>About       </h2></td></tr>
    <tr><td><h2>&nbsp;</h2></td></tr>
    <tr><td><img class="NavButton" src="images/Review.png"  title="Review and save" onclick=GotoPage("ReviewPage")   /></td><td><h2>Review and save </h2></td></tr>
    </table>

Adding panels for your application

To add a new panel:

  • Add an entry (button/link) to the TOC
  • Add the new page with class="PageDiv"
  • Add an entry to the "GotoPage()" function in Config.js
  • Add code to populate your page
  • Add code to get data from the server

Example: Adding a new panel for an app named "GPIOServer":

In index.html, add a line to the TOC:


<table id="TOCTable">
    <tr><td><img id="WB" class="NavButton" src="images/Wifi.png"    title="Wifi"        onclick=GotoPage("ScanningPage") /></td><td><h2>Wifi        </h2></td></tr>
    <tr><td><img id="SN" class="NavButton" src="images/SysName.png" title="System name" onclick=GotoPage("SysNamePage")  /></td><td><h2>System Name </h2></td></tr>
    <tr><td><img id="NB" class="NavButton" src="images/Network.png" title="Network"     onclick=GotoPage("NetworkPage")  /></td><td><h2>Networking  </h2></td></tr>
    <tr><td><img id="AB" class="NavButton" src="images/GPIO.png"    title="GPIO"        onclick=GotoPage("GPIOPage")     /></td><td><h2>GPIOs</h2></td></tr>
    <tr><td><img id="AB" class="NavButton" src="images/About.png"   title="About"       onclick=GotoPage("AboutPage")    /></td><td><h2>About       </h2></td></tr>
    <tr><td><h2> </h2></td></tr>
    <tr><td><img class="NavButton" src="images/Review.png"  title="Review and save" onclick=GotoPage("ReviewPage")   /></td><td><h2>Review and save </h2></td></tr>
    </table>

In index.html, add the actual page:


<div id="GPIOPage" class="PageDiv">
    <table id="GPIOLines" summary="GPIO Configuration">
        <tr><td style="width: 10%"><h1>GPIO for: </h1></td><td><h1><span class="SysName"></span></h1></td></tr>
        </table>

    <table class="NavTable">
        <tr><td> </td></tr>
        <tr><td><img class="NavButton" src="images/Back.png" title="Back" onclick=GotoPage("TOCPage")    /></td><td><h2>Back</h2></td></tr>
        </table>

    </div>

In Config.js, add the page navigation:


        if( PageName == "TOCPage"      ) { PopulateTOCPage(); }
        if( PageName == "ScanningPage" ) { ConfigCommand("GetWifiList"); }
        if( PageName == "SSIDPage"     ) { PopulateSSIDPage(); }
        if( PageName == "SysNamePage"  ) { PopulateSysNamePage(); }
        if( PageName == "NetworkPage"  ) { PopulateNetworkPage(); }
        if( PageName == "SharingPage"  ) { PopulateSharingPage(); }
        if( PageName == "AboutPage"    ) { PopulateAboutPage(); }
        if( PageName == "ReviewPage"   ) { PopulateReviewPage(); }
        if( PageName == "EpilogPage"   ) { PopulateEpilogPage(); }
        if( PageName == "GPIOPage"     ) { ConfigCommand("GetGPIO"); }

In ConfigServer, add code to retrieve the information when it arrives:


    #
    # GetGPIOList - Return list of GPIO stuff
    #
    elsif( $Request->{Type} eq "GetGPIOList" ) {
        Message("ConfigServer: GetGPIOList()")
            if $Verbose;
        $Request->{Error} = "No error.";
        $Request->{State} = GetGPIOList();  #<-- You supply this function
        }

In Config.js, add code to populate the page:


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // PopulateGPIOPage - Populate the GPIO page as needed
    //
    function PopulateGPIOPage() {
        ... Your code goes here ...
        }

In Config.js, add code to receive the new data:


    if( ConfigData["Type"] == "GetGPIO" ) {
//                console.log(ConfigData);
        var GPIOList = ConfigData.State;

        PopulateGPIOPage(GPIOList);
        return;
        }

Built-in web page server

AppDarmon starts at system boot via command in /etc/rc.local. If you add the argument "WebDir=<some-directory>", the system will start a web server in that directory along with your application. Place an index.html in that directory and whatever support files you might need (index.css, index.js, favicon.ico), and these will be served on port 80 with your application.

This is a simple web server, based on the javascript html library, so it doesn't do sophisticated processing or security controls or .htaccess. If you need full website functionality, install and use Apache.

But if you just need a simple page or two for your application, you can use the built-in one supplied with the AppDaemon.

Here's how you might modify rc.local to make use of this feature:



ConfigGPIO=4;       # Config switch WPi07, Connector pin  7, GPIO (command) BCM 04
LEDGPIO=19;         # Config LED    WPi24, Connector pin 35, GPIO (command) BCM 19

Verbose="-v"        # AppDaemon gets very talky
#Verbose=           # AppDaemon shuts up

nohup /root/AppDaemon/bin/AppDaemon $Verbose --config-gpio=$ConfigGPIO --led-gpio=$LEDGPIO  \
                                             --user=pi /home/pi/SampleApp &

And with that example, here are the files the application would need:



/home/pi/GPIOServer/public_html: l
favicon.ico  GPIOServer.css  GPIOServer.js  images  index.html  success.txt

For reference, here's the full command line documentation for the AppDaemon:



##  USAGE
##
##      AppDaemon [-v] --SSID= --config-gpio= --led-gpio= --web-dir= --user= App1 [App2 ... ]
##
##      where:
##
##          --SSID=name             Name to show when in access point mode
##
##          --config-gpio=#         GPIO of button to enter config mode
##
##          --led-gpio=#            GPIO of LED (to blink when in AP mode)
##
##          --user=           User to run applications as (ie - "pi" for raspberry pi default user)
##
##          App[n]                  Applications to run and monitor
##
##          --web-dir=         Spark a web server in this directory, in addition to any apps
##
##          -verbose                Print out things as they happen
##          -v
##
##          If SSID is not given, will use the text in /etc/hostname. If this file is blank or
##            missing, will use the literal "RasPi"
##
##          If led-gpio is not given, will not attempt to blink anything when entering config mode.
##
##          If config-gpio is not given, will not enter config/ap mode.
##
##          If user is not given, will use "pi"