Some guidance???

Hello fellow Linoders!

Some background:

I use my Linode for primarily hosting numerous websites and providing VPN's for friends overseas.

Semi recently I was toying around, and used an Arduino to control my detached garage door. It uses relays for the open close functionality, and a combination of limit switches and magnetic switches for the feedback of the door positions.

I currently use a raspberry PI on my home network that is reachable from the outside via https which can talk to the Arduino over Ethernet. I put together a small PHP script that allows me to check the status of the door, as well as operate it. This was about the extent of my php scripting.

My Linode runs a bash script ever 5 minutes that checks the door status, if the door is open, it write a value to a text file. If on the next check it is still open (checks the text file), if will send me a text letting me know that I left the door open.

Where I need some help:

I have wanted to clean all of this up for a while, but really don’t know the best way to do it as I really am not much of a programmer. Ideally, I want to start to use a database to track the number of minutes the garage door is open so I don’t get a text if it is open for 2 scans of the script, which could be 5 minutes and 1 second.

I was also thinking it would be handy to have a way (via url) that could "set an alarm" (bit in db) where if it detects an open door it would text immediately instead of waiting. I would also want to be able to disable the alarm the same way. Maybe something like http://www.whatever.com/garage/arm or something like that.

Is it easy to integrate a bash script with mysql?

I don't think that anything here is too hard, but I just want to do it in the most efficient way possible.

Any advice or questions? This is more for my own learning than anything else.

3 Replies

Essentially, you want a certain action occurs if the garage door has changed state. It sounds like your Arduino is set up as an I/O register of sorts, where you can read its current position, or write a new position. Since I should be working on Embedded System Design homework and am instead procrastinating, here's a state machine.

~~![](<URL url=)http://drop.hoopycat.com/garage_state_machine.jpg" />

I think the Arduino is actually the easier place to put the state machine, because otherwise you have to deal with all the orchestrations required to maintain less than 8 bits of state in a stateless HTTP-based system. When STATUS changes, have it send a signal to the RPi that causes it to e-mail you or whatever. I'd also set up a mechanism on the Arduino to query STATUS, as well as set or clear the ARMED flag… a RESET is probably also a good idea (when this happens, go straight back to START).

Note: I haven't tested this code, nor have I written a state machine in C before. God help you.

typedef enum {ST_IDLE, ST_OPEN, ST_WAIT, ST_ALARMING} state_t;
typedef enum {ALLCLEAR, PANIC, DUMBADOLLARSIGNDOLLARSIGN} status_t;
typedef enum {false = 0, true} bool;   // good god, what a barbaric language

state_t currentState = ST_IDLE;
status_t currentDoorStatus = ALLCLEAR;

const unsigned long OPEN_WAIT = 5 * 60 * 1000;  // milliseconds to wait when the barn door is open
unsigned long open_millis = 0;  // millis() when door is detected open

bool armed = false;  // set this to true if you want to PANIC

// prototypes for implementation-specific stuff
void sendNotification(status_t alarmStatus);
bool isGarageDoorOpen();

// setStatus: calls sendNotification when newStatus is different than currentDoorStatus
void setStatus(status_t newStatus)
{
  if (newStatus != currentDoorStatus)
  {
    // the status has changed; send a text message or e-mail or whatever
    sendNotification(newStatus);
    currentDoorStatus = newStatus;
  }

  return;
}

// loop: this is the code that loops over and over and over again
void loop()
{
  switch (currentState)
  {
    case ST_IDLE:
      if (true == isTheGarageDoorOpen())
      {
        // garage door is open; proceed to open state
        currentState = ST_OPEN;
      }
      else
      {
        // garage door is closed; all clear, stay in idle state
        setStatus(ALLCLEAR);
        currentState = ST_IDLE;
      }
    break;

    case ST_OPEN:
      if (true == armed)
      {
        // alarm is armed, freak all the way out, proceed to alarming state
        setStatus(PANIC);
        currentState = ST_ALARMING;
      }
      else
      {
        // alarm is not armed, record current time, proceed to wait state
        open_millis = millis();  // record the current time
        currentState = ST_WAIT;
      }
    break;

    case ST_WAIT:
      if (OPEN_WAIT < (millis() - open_millis))
      {
        if (true == isTheGarageDoorOpen())
        {
          // door has been open more than OPEN_WAIT milliseconds, update status and proceed to alarming state
          setStatus(DUMBADOLLARSIGNDOLLARSIGN);
          currentState = ST_ALARMING;
        }
        else
        {
          // miracles of miracles; the damn thing is now closed.  back to idle state
          currentState = ST_IDLE;
        }
      }
      else
      {
        // continue waiting...
        currentState = ST_WAIT;
      }
    break;

    case ST_ALARMING:
      if (false == isTheGarageDoorOpen())
      {
        // garage door has closed, return to idle state
        currentState = ST_IDLE;
      }
      else
      {
        // we're still freaking out over here
        currentState = ST_ALARMING;
      }
    break;
  }
}

Edit: So apparently I hallucinated the bool type; I tend to do that. Have another enum.~~

HaD (Hack a Day) has a forum for stuff just like this (i.e. projects that need advice and/or help) and they specialize in the Hardware side of things (and the Software required to make the hardware work).

http://hackaday.com/

Ill check em out. Thanks!

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct