Showing posts with label SMS. Show all posts
Showing posts with label SMS. Show all posts

Monday, November 30, 2015

Esp8266 - Interactive SMS from the Web Page

UPDATE: Mon Nov 30 21:34:56 PST 2015
Added Links and Detail
Added RAW HTML listing

In the previous post I listed a code snippet that provides non-interactive SMS from the Esp8266. But sometime it is desirable to provide a simple interactive SMS interface for the Web User. An interactive SMS interface could be used to "page the SysAdmin" with the web user's supplied message.
Example Interactive Web SMS Interface
The interactive SMS interface is simple and requires only some HTML code to be inserted within a web page. Note: the previous post was a SMS method where user interaction was not needed nor desired.

Note: the Open SMS Gateway domain name that is used in the example is "textbelt.com", read their web page for details for Canadian and International use.

The following are excerpts from my ERB-EspWebServer.

Note: the RAW HTML code could be extracted from the example below and used with any Web Server.

The Setup:


// The Setup

    #define OPT_MONITOR_DEBUG_OUTPUT 1
   
    // ERB - Force format stings and string constants into FLASH Memory
    // I use E() as an Alias for F() so that DEBUG code can be inserted
    #define  E(x) F(x)
    // Used as an F() when being used as the first Element
    // of a Multi-Element Expression
    #define sE(x) String( F(x) )


// Defaults for Pager
    #define DEFAULT_PAGER_GATEWAY "textbelt.com"
    #define DEFAULT_PAGER_NUMBER  "202-555-1212"

    #define SYSTEM_ADMIN_PAGER_NUMBER DEFAULT_PAGER_NUMBER


Web Server Code Arduino Sketch Snippet:


    // Pager - User Interactive Web Interface
    sz += wprintln( E("\r\n<!-- Pager - User Interactive Web Interface -->") );
    sz += wprintln( E("<center>") );
    sz += wprintln( E("<hr width='75%' />") );

    sz += wprintln(sE("<form action="http://")
          + DEFAULT_PAGER_GATEWAY + E("/text method='POST' target='SMS_Report' >") );
       sz += wprintln( E("  <b>Page SysAdmin with </b>") );
       sz += wprintln(sE("  <input name='number' type='hidden' value='")
             + SYSTEM_ADMIN_PAGER_NUMBER + E("' />") );
       sz += wprintln( E("  <b>Message:</b>") );
       sz += wprintln(sE("  <input name='message' type='text' value='")
             + gDeviceName + E(": ' />") );
       sz += wprintln( E("  <input type='submit' value='GO' />") );
    sz += wprintln( E("</form>") );
    
    sz += wprintln( E("Or<br>") );
    
    sz += wprintln(sE("<form action="http://")
          + DEFAULT_PAGER_GATEWAY + E("/text method='POST' target='SMS_Report' >") );
       sz += wprintln( E("  <b>SMS Number:</b>") );
       sz += wprintln( E("  <input name='number' type='tel' />") );
       sz += wprintln( E("  <b>Message:</b>") );
       sz += wprintln(sE("  <input name='message' type='text' value='")
             + gDeviceName + E(": ' />") );
       sz += wprintln( E("  <input type='submit' value='GO' />") );
    sz += wprintln( E("</form>") );

    sz += wprintln( E("</center>") );


Note: I use my own custom "wprintln" function within the above example, modify as necessary.

For reference and to make things simple, I have extracted just the HTML from the above Sketch, as shown below.

HTML:


<!-- Pager - User Interactive Web Interface -->
<center>
<hr width='75%'>

<form method='POST' action='http://textbelt.com/text' target='SMS_Report' >
  <b>Page SysAdmin with </b>
  <input type='hidden' name='number' value='202-555-1212' />
  <b>Message:</b>
  <input type='text' name='message' value='Nod129: ' />
  <input type='submit' value='GO' />
</form>

Or<br>

<form method='POST' action='http://textbelt.com/text' target='SMS_Report' >
  <b>SMS Number:</b>
  <input type='tel' name='number' />
  <b>Message:</b>
  <input type='text' name='message' value='Nod129: ' />
  <input type='submit' value='GO' />
</form>

</center>


If you find this useful, leave a comment.

-- Home Page: https://WA0UWH.blogspot.com
 

Sunday, November 29, 2015

Esp8266 - with SMS

UPDATE: Sun Nov 29 22:14:04 PST 2015
Added details and Links


For my Esp8266 I wanted a easy way to send to my Cell Phone an SMS message.

For example: On a normal computers (Workstations and Raspberry PI) it is a simple mater of using "curl" to access an Open SMS Gateway (see previous post). I used this feature to report simple things like "reboot" and "backup finished" messages.

One such Open SMS Gateway is "textbelt.com", which is the one that I use. But, recently they were "black listed" by some of the Phone Carriers (my carrier) for abuse, apparently there was too much illegal traffic by the Gateway's users.

Textbelt has recently fixed the abuse and their Gateways is up and running again, or at least for my carrier.

For the Exp8266, I have created some functions that implements the "curl" protocol, (the heavy lifting), so now paging to my Cell Phone is a snap.

I am providing the functions here as just application snippets, hopefully you find them useful. I will put this in my ERB-EspWebServer GitHub (eventually).

The Setup:



// The Setup

    #define OPT_MONITOR_DEBUG_OUTPUT 1
   
    // ERB - Force format stings and string constants into FLASH Memory
    // USE WITH CAUTION !
    // I use E() as an Alias for F() so that DEBUG code can be inserted
    #define  E(x) F(x)
    // Used as an F() when being used as the first Element of a Multi-Element Expression
    #define sE(x) String( F(x) )

// Defaults for Pager
    #define DEFAULT_PAGE_GATEWAY "textbelt.com"
    #define DEFAULT_PAGE_PORT     80
    #define DEFAULT_PAGE_NUMBER  "202-555-1212"
    #define DEFAULT_PAGE_MESSAGE "Test"

    boolean gPageStnReady = false;



The Functions:



// Pager

// ###########################################################
//////////////////////////////////////////////////////////////
//
// Provides easy access to page via SMS Gateway
//
boolean
//ICACHE_FLASH_ATTR
page( String aMesgText = DEFAULT_PAGE_MESSAGE,
      String aNumber   = DEFAULT_PAGE_NUMBER,
      String aHost     = DEFAULT_PAGE_GATEWAY,
         int aPort     = DEFAULT_PAGE_PORT )
{
    
    digitalWrite ( gBluLED, ON );
    
        #if (OPT_MONITOR_DEBUG_OUTPUT) > 0
            Serial.println ( );
            Serial.println ( E("Starting Pager Client ...") );
        #endif
        
        String timeUTCBuf = "";
        
        String mesgTextHeader = String(gDeviceName)
            + E(": ")
            + String(gRev)
            + E(", ")
            + timeUTC(timeUTCBuf, gTimeZONE)
            + E(" - ");
    
        String mesg="number=" + aNumber
               + "&message=" + mesgTextHeader + aMesgText ;
    
        #if (OPT_MONITOR_DEBUG_OUTPUT) > 0
            Serial.println( sE("  Connecting to: ") + aHost );
        #endif
      
        // Use WiFiClient class to create TCP connections
        WiFiClient client;
        if (!client.connect(aHost.c_str(), aPort)) {
          #if (OPT_MONITOR_DEBUG_OUTPUT) > 0
              Serial.println("  Connection Failed");
          #endif
          return false;
        }
        
        #if (OPT_MONITOR_DEBUG_OUTPUT) > 0 
            Serial.println( sE("  MESG: ") + mesg );
        #endif
   
        // This will send the request to the server
        client.print( sE("POST /text/ HTTP/1.1\r\n")
                     + E("User-Agent: Esp8266/") + gRev + E("\r\n")
                     + E("Host: ") + aHost + E("\r\n")
                     + E("Accept: */*\r\n")
                     + E("Content-Length: ")
                     + String( mesg.length() ) + E("\r\n")
                     + E("Content-Type: application/x-www-form-urlencoded\r\n")
                     + E("\r\n")  // The Required Blank Line
                     + mesg + E("\r\n") );
    
        delay(10);

        // Wait for Client to Start Sending
        int i = 0;
        while( !client.available() ) {
          delay(10);
          if (i++ > 200) break;
        }
          
        // Read all the lines of the reply from server and print some to Serial
        boolean myStatus = false;
        while(client.available()){
          String line = client.readStringUntil('\n');
          if(line.indexOf("\"success\": true") >= 0) {
              myStatus = true;
          }
          #if (OPT_MONITOR_DEBUG_OUTPUT) > 0 
              if(line.indexOf("\"success\": ") >= 0 ||
                 line.indexOf("\"message\": ") >= 0
              ) Serial.println(line);
          #endif
        }
        
        client.flush();
        client.stop();
        #if (OPT_MONITOR_DEBUG_OUTPUT) > 0 
            Serial.println("  Connection Closed");
        #endif
         
    digitalWrite ( gBluLED, OFF );

    return myStatus;
  
}


// ###########################################################
//////////////////////////////////////////////////////////////
//
// Provides easy access to Pager via SMS Gateway
//
unsigned long gPageHoldOff = millis();
void
//ICACHE_FLASH_ATTR
pageOnStnReady() {
    
      if ( gPageHoldOff < millis() ) {
        
          gPageHoldOff = millis() + 1 * MINs;
        
          if ( gPageStnReady == false ) {
               gPageStnReady = page("Stn Ready");
          }
      }
  
    return;
  
}

// ###########################################################
// End


Let me know if you find this useful, leave a comment.

-- Home Page: https://WA0UWH.blogspot.com

Wednesday, November 25, 2015

Email sent from Raspberry PI

UPDATE:
Added details and Links

Sending Email from a Raspberry PI (or any typical Linux workstation) is NOT normally configured. But with the help of some optional commands it can be done with ease.

Also, see my previous post.


Some History

In the early days of Unix Workstations and Server, "sendmail" was typically configured by default, and therefore sending email was easy. In fact, it was "too easy", which allowed the bad guys to anomalously send SPAM. To combat SPAM most ISP's started requiring mail be "signed" (user name and password) by the originator, so it could be traced back to the point of origin.

Today

Often it is useful to send a simple status report, information, attachments, or a quick SMS messages from; a Linux Workstation, a small Raspberry PI, or a Beagle Bone.

Today "most" email must be signed, and because of that it has become more difficult to use email for sending mail even to oneself.

Note: There are a "few" Open Mail (SMTP) Gateways that can be used. But the gateways can not, and will not guarantee any kind of performance, or can not provide any reasonable expectations. These Open SMTP's  are often used by SPAMMER.

Google'ing "Raspberry PI email" will provide several solutions.

But, most (if not all), require you use/save your EmailAddress and EmailPasswd as clear open-text on the command line or within a configuration file. I do not like that idea. There has got to be a better way?

One of the suggested solutions is "sendEmail", unfortunately it has a (some what) "complex" command line interface, and as above it normally requires the user to type an email password as clear open-text on the command line.

Note the upper case "E" in the sendEmail name.

To simplify, I have created a "Wapper Script", that can be used similar to those used in the early days of UNIX.

Examples:

      $ date | mysendgmail some_user@gmail.com

or,

      $ mysendgmail some_user@gmail.com < textfile

or, SMS

      $ echo "Meet me for Lunch" | mysendgmail phonenumber@vtext.com

or, with an attachement

      $ echo "Here is my report" | mysendgmail some_user@yahoo.com -a myfile

or

      $ mysendgmail some_user@aol.com -s "My Status" -m I am driving, Do you want a ride.

Note: in the above example, @vtext.com is the Verizon SMS gateway, others could be used as necessary.

For the above examples, using my "Wapper Script", the users Gmail Password is prompted for, but does not display, see help text.

Also, see the included Help text for install instructions.

This Script makes my life easy, I hope you also find it useful. It is a little long for a blog post, but I wanted to provide it here before going to the trouble of setting up its own GitHub.

Note: some of the options of "sendEmail" have been used/perverted by this script to make the user interface easy and simple, which I find is a good compromise for functionality and usability.

Note: there is a BUG in the Raspberry PI implementation of "sendEmail",  Again, see the Help text.

If all else fails, "sendEmail" is a useful tool even when used by itself.

This following is mysendgmail script:



#! /bin/bash
# mysendgmail - Command line mail interface for Linux users,
# often on Raspberry Pi and other similar
# This script is a user friendly wrapper for "sendEmail"

# Because this script requires customization for each user,
# it should be save in each users $HONE/bin directory,
# as $HOME/bin/mysendgmail (or what ever name you like).


AUTHOR='Eldon R. Brown  - WA0UWH - 2015/11/22'
REV='1.02.30'

# Notes:
#   I think Google gmail allows 99 SMTP emails to be sent per day.
#   Note: an SMS sent to a Cell Phone has a 160 Character Limit.

progname=`basename $0`

# The Gmail Account, these must be customized per user
 from_user='userName@gmail.com'
 gmail_user='userName'

#This is for Google Gmail, others could be used
 SMTP='smtp.gmail.com:587'


# Setup for Bold, Highlight, and Normal output
 B=`tput bold` G=`tput setf 2` N=`tput sgr0` H=${B}${G}

Usage="

${B}${progname}-${REV}, by: ${AUTHOR}${N}

  ${H}Usage:${N}

        ${progname} [mode] [-t] user@domain.com [[-s|-u] subject] [sendEmail args] -m message . .
  . . | ${progname} [mode] [-t] user@domain.com [[-s|-u] subject] [sendEmail args]

        Where: [mode] =
               -n     = Dry Run
               -v     = Verbose
               -h     = This help message
              --h     = This help message, plus more Info
              --help  = sendEmail help message, also see the
                        man page, as: man sendEmail

"

Info="
  ${H}More Info:${N}

        To Install supporting functions:
        $ sudo aptitude install sendEmail perl
        $ sudo aptitude install libio-socket-ssl-perl libnet-ssleay-perl

        See some sendEmail Examples, at: http://goo.gl/6LqX8Q

        NOTE: There is a BUG in Raspberry PI's implementation
              of: /usr/bin/sendEmail REV=1.56
              Workaround:
                 replace 'SSLv3 TLSv1' with 'SSLv3' within /usr/bin/sendEmail

 NOTE: The Gmail Passwd can be saved (and somewhat hidden)
              in the current environment with:
              $ export GPW; read -s -p 'Gmail Passwd: ' GPW; echo
       And then later, it can be removed with:
              $ unset GPW

" 
 
# Main

 # Check first arg for Help Message, or Version Info
 case "${1}" in
 (-V)    echo -e "${progname}-${REV} by ${AUTHOR}"; exit;;
 (-h|"") echo -e "${Usage}" >&2; exit;;
 (--h)   echo -e "${Usage} ${Info}" >&2; exit;;
 (-help|--help) sendEmail --help >&2; exit;;
 esac
 
 # Check first arg for Dry Run or Verbose
 case "${1}" in
 (-n) DRYRUN='yes'; shift;;
 (-v) VERBOSE='yes'; shift;;
 esac

 # Check next arg for Dry Run or Verbose, again to avoid order conflict
 case "${1}" in
 (-n) DRYRUN='yes'; shift;;
 (-v) VERBOSE='yes'; shift;;
 esac

 # Prompt for Gmail Account Passwd, OR used the Environment Varrible $GPW
 gmail_passwd="${GPW}"
 if [ -z "${GPW}" ]
 then read -s -p "Gmail Password: " gmail_passwd </dev/tty; echo
 fi


# Parse Mail Address and Subject Args
 
 # Check if First arg is "-t", if so ignore, ignore it and
 # assume the next is email address
 case "${1}" in (-t) shift;; esac

 # Assume Next arg is the TO address
 to="${1}"; shift
 
 # Check if Next arg is "-s" or "-u", if so, ignore it and
 # assume the next is the Subject
 case "${1}" in (-u|-s) shift;; esac

 Default_Subject="Sent: `date '+%Y/%m/%d %H:%M:%S'`"
 # Assume Next arg is Subject
 sub="${1:-${Default_Subject}}"; shift

# Setup DEBUG modes

 # Check for DRYRUN mode, if so, Munge passwd for DRYRUN
 if [ "${DRYRUN}" = "yes" ]; then gmail_passwd='"*****"'; fi

 # Check for VERBOSE, For Debug
 if [ "${VERBOSE}" = "yes" ]; then MODE='set -xv'; fi

# Build the Command
 CMD="sendEmail -o tls=yes -s ${SMTP} \
  -xu ${gmail_user} -xp ${gmail_passwd} \
  -f ${from_user} -t ${to} -u ${sub} \
  $@" # Adds user supplied sendEmail options

# Finally,  Run Command
 case "${DRYRUN}" in
 (yes) echo $CMD;;  # For Debug
 (*) ${MODE}; $CMD | grep "`date '+%b %d'`";; # Report just the "basic" status
 esac

# End



-- Home Page: https://WA0UWH.blogspot.com

Wednesday, April 1, 2015

Sending SMS from the Raspberry PI

Yesterday my friend Larry - KB7KMO was in my Shop, we both have need for Status and/or Alarm Messaging from the Raspberry PI, a casual google searches did not provide much easy help. There is/was much information on how to do it with very long and complex configurations, but we wanted something simple.

After Larry left, and after several hours (actually more than a few) of research, I have found a free service that can be used to send a "SMS" messages from the Raspberry PI to a Cell Phone, using the "curl" command.

Obviously, An Internet connection is needed for the PI, and the "curl" command must be installed (if not already).



$ sudo apt-get install curl



The free SMS service is provided by "textbelt.com" (thanks, textbelt !).

There are limitations to the "textbelt.com" service; no more than 75 messages sent per day from a single IP Address, and no more than 3 messages per 3 minutes can be sent to a single Cell Phone number. For most typical use, this should not be a problem.

Note: the SMS messages received by the Cell Phone will be delivered from "txt@textbelt.com".

Usage: on the command line or shell script:



$ curl http://textbelt.com/text -d "number=AAAPPPNNNN" -d "message=This is a test message"



Where "AAAPPPNNNN" is the: Cell Phone Number, AreaCode, Prefix, and Number. Also, dashes ("-") can be used within the phone number, as: "number=202-555-1212"

Note: the words "number=" and "message=" must be used as shown.

For Canada and International use see: Web page.


- Have Fun with PI Messaging !


-- Home Page: https://WA0UWH.blogspot.com