====== Send SMS via USB Modem ====== If you need send SMS using own GSM modem you can use [[Custom Protocols]] to instruct modem send messages. To send SMS you need send a few AT-commands to modem. Unfortunately, sometimes they are vendor-specific and we can't built in support all modems into WebHMI. So we publish custom protocol that will help you understand the idea and adopt it for your modem. Here is the sample protocol that will send message: function createDevices () addDevice({name = "SMS", shift = 0, base = 10, xtraFields = {1, 5}}); end function readRegister (reg, device, unitId) return "SMS"; end function writeRegister (reg, device, unitId, newValue) sendString("AT+CPIN=\"0000\"\r"); sendString("AT+CMGF=1\r"); sendString("AT+CSMP=17,167,0,0\r"); sendString("AT+CMGS=\"+" .. string.sub(reg.addr, 4) .. "\"\r"); sendString(newValue); sendString(string.char(26)); return true; end Protocol parameters: *Type: Serial Port *Address validation: ^(SMS[0-9]+)$ *Validation error message: Invalid phone number. Valid SMS addresses are SMSxxxxxxxxxx where xxxx is a phone number. Go to **Setup -> Registers -> Tools -> Custom Protocols** and add this protocol. After that you can create connection using this protocol. Some modems could answer on AT commands with huge delays. You might need specify extremely long timeouts for them in connection settings (3-6 seconds!) in you will see such behavior. Please note that modern modems usually have multiple UARTs (/dev/ttyUSB0, /dev/ttyUSB1, /dev/ttyUSB2, etc). Some of these UARTs can be used for data exchange only, another - for control modem during the established call. You have to find such control port manually (basically, try one by one) to find port that will react on AT-commands and use this post in this custom protocol. To send SMS to phone number 1234567890 you need to create a register with address SMS1234567890 with data type String. Once register was created you can send SMS to this phone it by writing text to this register. When WebHMI will get command to write new text to this register it will send needed AT command to modem and modem will send SMS to phone number specified in register address. If you will have troubles with sending SMS you can use this debug version of custom protocol. It will echo commands and modem replies into WebHMI communication log. This might help you debug the issue. function createDevices () addDevice({name = "SMS", shift = 0, base = 10, xtraFields = {1, 5}}); end function readRegister (reg, device, unitId) return "Ok"; -- Just a placeholder to allow type new values on Register's page, end function writeRegister (reg, device, unitId, newValue) local replyTmp = "" DEBUG("entered sms protocol for value "..newValue) --sendString("AT+CPIN=\"0000\"\r"); -- Some modems will require enter PIN code sendString("AT+CMGF=1\r"); -- Switch modem into text mode -- Get modem's reply replyTmp = ReadModemReply() if (replyTmp ~= "") then DEBUG("modem replied with "..replyTmp) end -- Get text mode parameters sendString("AT+CSMP=17,167,0,0\r"); -- Get modem's reply replyTmp = ReadModemReply() if (replyTmp ~= "") then DEBUG("modem replied with "..replyTmp) end -- Tell phone number to modem. We are using raw register address and cut phone number from it starting at char #4 sendString("AT+CMGS=\"+" .. string.sub(reg.addr, 4) .. "\"\r") -- Get modem's reply replyTmp = ReadModemReply() if (replyTmp ~= "") then DEBUG("modem replied with "..replyTmp) end -- Send message (newValue) and line end character (ASCII code #26) sendString(newValue..string.char(26)) -- Get modem's reply replyTmp = ReadModemReply() if (replyTmp ~= "") then DEBUG("modem replied with "..replyTmp) end return true; end function ReadModemReply() local CR = "\r" local one_char_tmp = "" local readStringTmp = "" repeat one_char_tmp = readString(1) if (one_char_tmp ~= false) then readStringTmp = readStringTmp..one_char_tmp else DEBUG("can't readString") return "" end until (one_char_tmp == CR) readString(1) -- read rest symbol return readStringTmp end