Skip to content

Thermostat

David Silvan edited this page Oct 27, 2016 · 7 revisions

Overview

In this lesson, we will be creating an app that reads temperature data from a server and displays the data in real-time to simulate a thermostat. We will allow the user to manually manipulate the data with the use of buttons as well.

Let's Get Started

User Interface Design

First, we set the AlignHorizontal property of the screen to be 'Center' so that everything will be centered (this step is optional).

Next, we insert a button, followed by a HorizontalArrangement (which can be found under the 'Layout' section of the 'Palette' panel). Then we'll add 2 more buttons inside of that horizontal arrangement. Finally, we'll add a FirebaseDB component (found under the 'Experimental' section of the 'Palette' panel) by dragging it into the screen.

Now we rename the buttons so that we won't get confused about their purpose later on. Rename Button1 to 'TempLabel', Button2 to 'DecreaseButton', and Button3 to 'IncreaseButton'. To rename the components, simply click on the component and then click the 'Rename' button.

Now it's time to configure the properties of the components so that the display is more user-friendly. The properties of each component can be found under the 'Properties' panel after clicking on a component. First we'll start by changing the Height and Width properties of the TempLabel button to both be 'Fill parent'. Then let's uncheck the Enabled box (this will be explained later), set the FontSize to 20, and check the FontBold box. Next we'll change the Text property of the TempLabel to say "Temperature".

For both the DecreaseButton and IncreaseButton, set the FontSize to 20, set the font to be bold, but leave the Enabled box checked. Change the Text property of the DecreaseButton to be "-" (minus sign) and the Text property of the IncreaseButton to be "+" (plus sign). Optionally, you can resize the HorizontalArrangement as well as the DecreaseButton and IncreaseButton. After doing all of this, your screen should look like this:

Next, we will set a background image for the TempLabel button. The reason that we do this is because App Inventor doesn't have good support for layering text over images. A workaround is to have a disabled button that has text and a background image. We already set the Text to be 'Temperature', so lets now set the background image. First we need to upload an image file into the App Inventor. To do this, click the "Upload File ..." button under the Media tab on the bottom right. Select an image file from your computer for the image file and click OK upload it. Now click on the TempLabel and click the Image property. From here, select the image file and click OK.

Finally, we need to setup the Firebase database so that we can send data to the server and sync data back from it. To do this, click on the FirebaseDB component and change the FirebaseURL property to be the URL of the Firebase database. For our lesson, the database URL will be: https://thermostat-1d90c.firebaseio.com/

Block Logic Editor

Now we will program the actual functions of the different components of the app (e.g., give the app functionality). Click the 'Blocks' button at the top right of the screen to switch to the Blocks editor. The first thing that we need to program is what the app will do when it is opened (in other words, do something when the Screen1 is initialized). Click on the Screen1 component under the Blocks panel and drag out the Screen1.Initialize block.

We will need a variable to hold the temperature data, so lets create one by dragging out the 'initialize global (name) to' block from the 'Variables' blocks and naming it 'temp'. Let's initialize it to 0 by dragging and dropping a number block from the 'Math' blocks and setting that number block to equal 0. What we want to do when the screen is initialized is retrieve the data from the server and set the 'temp' variable to equal that data. We can do this through the FirebaseDB blocks. Drag the Call FirebaseDB.GetValue block into the Screen1.Initialize block and then drag an empty text block into the tag field of the .GetValue block. Set the tag to be "temp" because that is the tag that we are using for our server. Then set the valueIfTagNotThere value to be 0 (using a math block, not a text block).

So now we need to handle what to do when the Firebase server gets the value on screen initialization. We do this by using a Firebase.GotValue block. Within this block we want to set the temp variable to equal the value passed by the GotValue, so drag a 'set global (name) to' block into the GotValue block and set the name of this inner block to be temp. Now hover over the 'value' parameter of the GotValue block and drag it into the 'set global temp to' block. We also want to set the TempLabel text to display this temp data, so drag out a 'set TempLabel.Text to' block under the 'set global temp to' block. Fill the space with the 'get global temp' block (optionally, you can use a 'join' block from the Text blocks to add a degree sign ("°") after the temperature data.

We also need to handle the case in which the data is changed on the server and update the temp variable and TempLabel accordingly. To do this, we use a Firebase.DataChanged block and do exactly what we did for the Firebase.GotValue block again (This is a good time to make use of the Duplicate feature, which can be used by right clicking on any block).

The last thing that we need to do is implement the functionality of the DecreaseButton and IncreaseButton. These buttons are used to change the data manually, but we want to send the updated data to the server (which will be synced back to the phones through the Firebase.DataChanged block). We'll start by dragging out a 'when DecreaseButton.Click' block and putting a 'call FirebaseDB.StoreValue' block within it. For the tag parameter of the StoreValue block, we'll use our "temp" tag (using a text block). For the valueToStore parameter, we need to use a "-" Math block to subtract 1 from the temp variable. Drag the 'get global temp' block into the first part of the minus block and a Math block of value 1 into the second part of the minus block.

For the IncreaseButton, we drag out the 'when IncreaseButton.Click' block and fill it exactly the same as the 'when DecreaseButton.Click', except using a "+" Math block instead of a "-" Math block.