class SmsSerial

Attributes

t[R]

Public Class Methods

new(dev='/dev/ttyUSB0', callback: nil, debug: false) click to toggle source
# File lib/sms_serial.rb, line 19
def initialize(dev='/dev/ttyUSB0', callback: nil, debug: false)

  @debug = debug
  @sp = SerialPort.new dev, 115200    
  puts 'running ' + "SmsSerial".highlight 

  @t = Thread.new {

    Thread.current[:v] = []

    loop do

      message = @sp.read
      if message.length > 0
  
        callback.call(message) if callback and @debug
  
        if message =~ /^\+CMTI:/ then
          callback.call(message.lines[2]) if callback
        else

          Thread.current[:v] ||= []
          Thread.current[:v]  << message 

        end
      end
  
      sleep 0.3
  
    end
  }
  
end

Public Instance Methods

count() click to toggle source

count the number of SMS messages

# File lib/sms_serial.rb, line 55
def count()

  puts 'inside count'.info if @debug

  cmd 'CPMS?' do |r|
    puts 'r: ' + r.inspect if @debug
    total = r.lines[2].split(',')[1].to_i
    puts ('message count: ' + total.to_s).debug if @debug

    total
  end
  
end
del(idx)
Alias for: delete
delete(idx) click to toggle source
# File lib/sms_serial.rb, line 69
def delete(idx)
  
  return delete_all() if idx.to_sym == :all

  cmd 'CMD' do |r|
    total = r.lines[2].split(',')[1].to_i
    puts ('message count: ' + total.to_s).debug if @debug

    total
  end

end
Also aliased as: del
delete_all() click to toggle source
# File lib/sms_serial.rb, line 84
def delete_all()

  # format: [index, delflag]
  # delflag 1 means delete all read messages
  cmd 'CMGD=1,1'

end
list_all() click to toggle source
# File lib/sms_serial.rb, line 92
def list_all()

  n = count()
  sleep 0.3

  @sp.write %Q(AT+CMGL="ALL"\r\n)
  n.times.map {r = read_buffer; parse_msg(r)}

  flush_output() if n < 1

end
read(idx=1) click to toggle source

read an SMS message

# File lib/sms_serial.rb, line 106
def read(idx=1)

  cmd('CMGR=' + idx.to_s) do |r| 
    begin
      parse_msg r 
    rescue SmsSerialError => e
      puts 'Invalid message no.'.warning
      nil
    end
  end

end

Private Instance Methods

cmd(s) { |r| ... } click to toggle source

e.g. cmd 'cmgr=1'

# File lib/sms_serial.rb, line 123
def cmd(s)

  puts ('inside cmd s: ' + s.inspect).debug if @debug
  r2 = @sp.write "AT+%s\r\n" % [s]
  puts 'r2: ' + r2.inspect if @debug
  puts '@t[:v] ' + @t[:v].inspect if @debug
  
  r = read_buffer

  block_given? ? yield(r) : r
end
flush_output() click to toggle source
# File lib/sms_serial.rb, line 135
def flush_output()
  r = read_buffer
  []
end
parse_msg(r) click to toggle source
# File lib/sms_serial.rb, line 153
def parse_msg(r)

  puts ('parse_msg r: ' + r.inspect).debug if @debug
  return if r.empty?
  heading = r.lines[2][/\+CMG[RL]: (?:[^,]+,)?(.*)/,1]
  puts ('heading: ' + heading.inspect).debug if @debug

  raise SmsSerialError, "Message not found" unless heading

  sender, sent = CSV.parse(heading).first.values_at(0,2)
  {sender: sender, sent: Time.parse(sent), body: r.lines[4].rstrip}

end
read_buffer() click to toggle source
# File lib/sms_serial.rb, line 140
def read_buffer()
  
  sleep 2 if @debug

  puts 'inside read_buffer @t[:v]: ' + @t[:v].inspect if @debug
  r = ''
  @t[:v].any? ? (r += @t[:v].shift until @t[:v].empty?).to_s : r = ''
  
  puts 'read_buffer r: ' + r.inspect if @debug
  r
  
end