Tuesday, April 29, 2014

Standing Meeting 4/28/14

With our goals for Scholar's Day out of the way and some new goals in mind, we met about where to proceed from our current state. We met and discussed some changes that we would like to make to the user interface and the framework. The main tasks are as follows:

Update the user's light control page - It got the job done but in the long run, we didn't like having the user select check-boxes and then click save to make any changes to the lights. Our goal is to change the interface so each light has an on and an off button. There will also be a way to identify whether the light is on or off based on which button (on or off) is highlighted or depressed. Users can simply click "On" and their update will automatically be sent to the database without them having to click and then save repeatedly. We figure this can be done through JavaScript.

Implement Schedule - We didn't worry about this leading up to Scholar's Day because our presentation time was limited anyway and it gave us time to work on other things but now, we would like to implement at least a basic schedule framework. Users will be able to schedule lights to turn on or off and the lights will carry out this action at the specified time.

Our last thing which will be a combination of front-end and back-end is:
Add button to turn on/off all lights within a room - This is not mandatory to the functionality of the project but we could see that clients would likely want this feature especially if they have a lot of lights in every room. This way, they can click one button rather than having to click all of them to turn off all lights. The On/Off button for the room will work just like the individual lights but it will be in a different place an will likely look different.

With this planned out, our meeting adjourned ready to improve the world! One satisfied customer at a time!

Pi-Side Script

As of right now, we are hosting our database on a central server.  Each PI needs to be able to connect to that database to check if it needs to turn on or off any of its lights.  We ran into some troubles writing the Python script that would accomplish this.

The script was not very long, and was laid out in the following manner.
  1. Establish a connection with the database.
  2. Query the database to check what state of the lights should be.
  3. Check the current state of the lights.
  4. Make any changes to the state of the lights if necessary.
  5. Repeat.
We had no problems except for steps number 3 and 4.  We were using a subprocess call to run a bash command that read in the current state of all our lights.  All we needed was a 1 or 0 to know if the lights was on of off, respectively.  After some time spent troubleshooting, we discovered that all the lights were always being read as off.

As it turns out, the subprocess call() function only returns if the call was successful or not.  Basically in layman's terms our Python script was telling bash to do something, then turning around and giving us a thumbs up that bash successfully did it.  We wanted to know the result of the command, not just that it was being done.

Well, the information we wanted from the command was being sent to stdout.  So how do we get that information into a variable in our script so we can make use of it?  File redirection.

What felt maybe a little dirty, and still looks a little strange perhaps, turned out to work pretty well.  We redirected stdout to a file in our current directory.  Then we had python jump into the file and read what was written there.  Finally, we had the information we needed!  That took care of most of our problems.

There was still a minor problem afterwords with step number 5.  In our script we are essentially running a while( true ) loop, and constantly checking the database/current-state and making changes if necessary with a few if statements.  The problem we ran into was because in Python you don't create your own data types.  You just say var = <whatever>.  Well, the information we were reading from our file was either a 0 or a 1.  A simple int.  Because it was coming from a file however, Python made it into a string.  In our if statements when we compared our string information to an int, we would get the wrong response.  It was a simple fix, simply casting the string to an int, but a problem that took a little bit of time to locate and really showed our inexperience with Python.

Monday, April 28, 2014

Twitter Bootstrap

To keep our website looking professional, we needed to change the list of lights in a given house to look more modern. We were sure that we wanted to use Twitter Bootstrap for this, but we weren't sure the best component to use. I perused the documentation for a while, and attempted to use stacked nav tabs to accomplish the effect. Alas, my attempt was in vain. The day seemed bleak and the sky dark. I handed in my resignation and Zach decided to take up the cause. It wasn't long before Zach found the "list-group" and "list-group-item" class. This seemed to work perfectly for our project, and made our website look much more professional. Here is the example of what our light view looks like now and the code that produced it.

{% if house_list %}
  <form action="{% url 'management:submitChange' %}" method="post" >
  {% csrf_token %}
  {% for house in house_list %}
    <!-- <h3> {{ house.description }} </h3> -->
    <ul class ="list-group">
    {% for room in house.get_rooms %}
          <li class="list-group-item"><h3 style="margin-top: 0px">{{ room.description }}:
                    {{ room.getNumberOfLights }} lights</h3></li>
      <ul class="list-group">
            {% for light in room.get_lights %}

          <li class="list-group-item">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" 
name="light" value="{{light.id}}"
                        {% if light.is_on %} checked {% endif %}>
                        {{ light.description }}</li>

        {% endfor %}
      </ul>
    {% endfor %}
    </ul>
  {% endfor %}
  <div class="form-actions">
    <button type="submit" class="btn btn-primary"> Save</button>
    <button class="btn" type="button" value="Cancel">Cancel</a>
    <!-- <input type="submit" value="Save"/><input type="button" value="Cancel"/> -->
  </div>
    </form> 
{% else %}
  <p>No lights are installed.</p>
{% endif %}

In the future, we hope to get rid of the check boxes in favor of buttons, which will require altering the method currently in place for communicating changes to the database.