SerialModem
Simple interface for Serial Modems. Tested:
- Huawei E303 in serial mode
Installation
Add this line to your application's Gemfile:
gem 'SerialModem'
And then execute:
$ bundle
Or install it yourself as:
$ gem install SerialModem
Usage
Simple
If everything is connected and the modem is recognized (/dev/ttyUSB* is available), then you can simply do:
require 'serialmodem'
SerialModem::setup_modem
return unless SerialModem.attached?
SerialModem::ussd_send('*100#')
SerialModem::sms_send('+23599999999', 'Hello from SerialModem')
Ussd
Huawei-modems with Hilink don't support USSD, so you have to switch them to serial-mode. Older modems (pre-2015) are handled with HilinkModem, newer versions not yet. Once the modem is in serial-mode, you can send and receive USSD-codes. It is even possible to use USSD-menus.
Sending
Supposing the modem is setup, you can do
SerialModem::send_ussd('*100#')
Or, if you need a menu where each step needs an answer, you can do
SerialModem::send_ussd('*800#', '1', '2', '1234')
Now each command waits for the last command to be completed.
Receiving
The received codes are stored in an array of hashes, where each hash has three fields:
- time: a string of "%H:%M"
- code: the ussd-code as sent out by 'ussd_send'
- result
There is a maximum of SerialModem::serial_ussd_results_max messages stored.
SerialModem::send_ussd('*128#')
sleep 10
result = SerialModem.serial_ussd_results.first.result
Asynchronous receiving
You can also define a listener in SerialModem.serial_ussd_new
SMS
Similar to USSD, you can send and receive SMS. Due to some restrictions in Huawei-modems, there is a thread that checks for new SMSs every 20s. Normally modems should reply as soon as an SMS is received, but most of the Huawei-modems tested delete SMS automatically when in this mode. If you prefer nonethelss to rely on this mode, set SerialModem.serial_sms_autoscan to 0.
Sending
If everything is recognized, simply do:
SerialModem.sms_send('+23599999999', 'Hello from SerialModem')
And the message should be sent.
Receiving
All SMS are put in a hash of arrays with the key of the hash being the message-id and the elements of the array as follows:
0: sms-flag 1: number of sender 2: unknown field 3: date and time of SMS 4: the message
Asynchronous receiving
You can also use the SerialModem.serial_sms_new variable to set up an automatic callback whenever a new SMS is received:
def treat_sms(list, id)
p "Received SMS from #{list[id][1]}"
end
SerialModem.serial_sms_new.push(Proc.new { |list, id| treat_sms(list, id) })
# Wait for SMS
Special
Some care has been taken that the serial modem is recognized and can be functional again in case of error:
detach and re-attach in case of power-failure
It can happen that the modem is in use and is reattached because of errors in the power. In that case it is not attached anymore to '/dev/ttyUSB2', but to '/dev/ttyUSB3'. With some luck, the SerialModem.reload_option can help to make things OK again.