This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

LM phone call to phone number
#1
Hi,

here is SMS message possibility describe, and latest CSQ (signal level was added):

https://forum.logicmachine.net/showthrea...hlight=CSQ

Can we somehow add ATD modem command (call to number) to modem library?

SMS/Telegram/E-mail is not always take attention when we are busy, but if we can initiate call to showed in script number and enter how many rings can be done - such way can be used for security or fire alarm notification.

Info found about AT commands:

https://m2msupport.net/m2msupport/voice-...oice-call/

I think to user.sms library we need to add something like this - very simple call to number command:

function call(number)
  cmd = string.format('ATD', number)
send(cmd)
  sleep(8)
send('ATH')
  end

but where and how do it correctly with line/answer check I still not experienced to do Sad

Error I have:

User library sms:472: attempt to call global 'send' (a nil value)
stack traceback:
User library sms:472: in function 'call'

Alex
Reply
#2
Try this (not tested):
Code:
function AT:call(number)
  self:send('ATD' .. number)
  os.sleep(8)
  self:send('ATH')
end
Reply
#3
(08.08.2023, 08:01)admin Wrote: Try this (not tested):
Code:
function AT:call(number)
  self:send('ATD' .. number)
  os.sleep(8)
  self:send('ATH')
end

Hi, this not working,

If I use in script calling this function:

require('user.sms')

call('3711234567')

I have error

Resident script:3: attempt to call global 'call' (a nil value)
stack traceback:

If I use

require('user.sms')

AT:call('3711234567')

Other error:

User library sms:319: attempt to index field 'port' (a nil value)
stack traceback:
User library sms:319: in function 'send'
User library sms:471: in function 'call'

So something needs to be corrected. If will be time, please look what I need correct in script.

BR, Alex
Reply
#4
It should be combined with the SMS script.

Change udphandler function in the resident script like this:
Code:
-- check local udp server for messages to send
udphandler = function(server)
  -- check for local sms to send
  local msg = server:receive()
  -- got no message
  if not msg then
    return
  end

  -- split into number and message
  local sep = msg:find(' ')
  if not sep then
    return
  end

  local num = msg:sub(1, sep - 1)
  local txt = msg:sub(sep + 1)

  if txt == 'CALL' then
    alert('calling: ' .. num)
    modem:call(num)
  else
    alert('sending sms: ' .. msg)
    modem:sendsms(num, txt)
  end
end

Then try this script (number should probably start with 00):
Code:
require('user.sms')
sendsms('003711234567', 'CALL')
Reply
#5
Hi,

it works, but at the end of number semicolon ;  should be added at least for my modem (in some descriptions is needed for ATD command in some not shown)

require('user.sms')
sendsms('003711234567;', 'CALL')

Alex

Forgot to add, that one more "end" should be added in udp handler function:

I have such error when tried to add provided script:

   

Is it possible to check where I need to add it?

Alex
Reply
#6
The message says it, If you want us to look drop full script not screenshot.
------------------------------
Ctrl+F5
Reply
#7
(21.08.2023, 07:36)Daniel Wrote: The message says it, If you want us to look drop full script not screenshot.

Hi, sorry. My script:

Code:
-- init
--
--
if not numbers then
  require('user.sms')
  require('json')
  require('socket')

  -- allowed numbers, SMS from other numbers will be ignored
  numbers = { '371xxxxxxx', '371xxxxxxx' }

  -- port number depends on modem model
  comport = 'ttyUSB0'
  doreset = false -- set to true if USB reset is required before starting any communication

  -- if SIM PIN is enabled, uncomment the line below and replace 0000 with SIM PIN
  -- pincode = '0000'

  -- command parser
  parser = function(cmd, sender)
    local find, pos, name, mode, offset, value, dvalue, obj, message

    cmd = cmd:trim()
    mode = cmd:sub(1, 1):upper()

    -- invalid request
    if mode ~= 'W' and mode ~= 'R' then
      return
    end

    cmd = cmd:sub(3):trim()

    -- parse object name/address
    find = cmd:sub(1, 1) == '"' and '"' or ' '
    offset = find == '"' and 1 or 0

    -- pad with space when in read mode
    if mode == 'R' and find == ' ' then
      cmd = cmd .. ' '
    end

    -- find object name
    pos = cmd:find(find, 1 + offset, true)

    -- name end not found, stop
    if not pos then
      return
    end

    -- get name part
    name = cmd:sub(1 + offset, pos - offset):trim()

    if mode == 'W' then
      value = cmd:sub(pos + offset):trim()

      if #value > 0 then
        -- try decoding value
        dvalue = json.pdecode(value)
        if dvalue ~= nil then
          value = dvalue
        end

        -- send to bus
        grp.write(name, value)
      end
    -- read request
    else
      obj = grp.find(name)

      -- object not known
      if not obj then
        return
      end

      -- send read request and wait for an update
      obj:read()
      os.sleep(1)

      -- read new value
      value = grp.getvalue(name)

      -- got no value
      if value == nil then
        return
      end

      -- add object name if specified
      if obj.name then
        name = string.format('%s (%s)', obj.name, obj.address)
      end

      message = string.format('Value of %s is %s', name, json.encode(value))
      modem:sendsms('+' .. sender, message)
    end
  end

  -- incoming sms handler
  readcsq = function()
    local res, err, reply = modem:send('AT+CSQ')
    local rssi

    if reply then
      rssi = reply:match('%+CSQ:%s+(%d+),(%d+)')
    end

    rssi = tonumber(rssi) or 0

    if 2 <= rssi and rssi <= 9 then
      quality = 'marginal'
    elseif 10 <= rssi and rssi <= 14 then
      quality = 'ok'
    elseif 15 <= rssi and rssi <= 19 then
      quality = 'good'
    elseif 20 <= rssi and rssi <= 30 then
      quality = 'excellent'
    else
      quality = 'unknown'
    end
    grp.write('0/0/40', quality)  -- Modem signal level write to group
  end

  csqtime = os.time()
  handler = function(sms)
    alert('incoming sms: [%s] %s', tostring(sms.sender), tostring(sms.data))

    -- sms from known number, call parser
    if table.contains(numbers, sms.sender) then
      parser(sms.data, sms.sender)
    end
  end

  -- check local udp server for messages to send
udphandler = function(server)
  -- check for local sms to send
  local msg = server:receive()
  -- got no message
  if not msg then
    return
  end

  -- split into number and message
  local sep = msg:find(' ')
  if not sep then
    return
  end

  local num = msg:sub(1, sep - 1)
  local txt = msg:sub(sep + 1)

  if txt == 'CALL' then
    alert('calling: ' .. num)
    modem:call(num)
  else
    alert('sending sms: ' .. msg)
    modem:sendsms(num, txt)
  end
    end
  end -- look like this place could be correct??-------------------------------------------------------------------------------

-- handle data from modem
if modem then
  if modem:run() then
    now = os.time()
    delta = math.abs(now - csqtime)

    if delta >= 15 then
      csqtime = now
      readcsq()
    end
    udphandler(server)
  else
    alert('SMS handler lost connection')
    modem:reinit()
  end
-- modem init
else
  alert('SMS handler init')
  -- open serial port
  modem = AT:init('/dev/' .. comport, doreset)

  -- init ok
  if modem then
    -- set sms handler
    modem:setsmshandler(handler)

    -- enable local echo
    modem:send('ATE1')
   
    -- send pin if set
    if pincode then
      modem:send('AT+CPIN=' .. pincode)
      modem:read()
    end

    -- phase 2+
    modem:send('AT+CSMS=1')
    -- set to pdu mode
    modem:send('AT+CMGF=0')
    -- enable sms notifications
    modem:send('AT+CNMI=1,1,0,0,1')
    -- fixup encoding
    modem:send('AT+CSCS="GSM"')
    --modem:send('AT+CSCS="UCS2"') --not working
    -- modem:send('ATD+371xxxxxxx;')
   -- sleep(8)
   -- modem:send('ATH')
   
    --modem:send('AT+CSQ')
    --modem:read()
    -- delete all saved messages
    modem:send('AT+CMGD=1')
    sleep(0.2)
     modem:send('AT+CMGD=2')
    sleep(0.2)
     modem:send('AT+CMGD=3')
    sleep(0.2)
     modem:send('AT+CMGD=4')
    sleep(0.2)
     modem:send('AT+CMGD=5')
    sleep(0.2)
     modem:send('AT+CMGD=6')
    sleep(0.2)
     modem:send('AT+CMGD=7')
    sleep(0.2)
     modem:send('AT+CMGD=8')
    sleep(0.2)
     modem:send('AT+CMGD=9')
    sleep(0.2)
     modem:send('AT+CMGD=10')
    sleep(0.2)
     modem:send('AT+CMGD=11')
    sleep(0.2)
     modem:send('AT+CMGD=12')
    sleep(0.2)
     modem:send('AT+CMGD=13')
    sleep(0.2)
     modem:send('AT+CMGD=14')
    sleep(0.2)
     modem:send('AT+CMGD=15')
    sleep(0.2)
     modem:send('AT+CMGD=16')
    sleep(0.2)
     modem:send('AT+CMGD=17')
    sleep(0.2)
     modem:send('AT+CMGD=18')
    sleep(0.2)
     modem:send('AT+CMGD=19')
    sleep(0.2)
     modem:send('AT+CMGD=20')
    -- local udp server for sending sms
    server = socket.udp()
    server:setsockname('127.0.0.1', 12535)
    server:settimeout(0.1)

    alert('SMS handler started')
  -- init failed
  else
    alert('SMS USB init failed')
  end
end
BR, Alex
Reply
#8
Drop this script to notepad++, select language LUA and it will highlight you which if belongs to which end.
------------------------------
Ctrl+F5
Reply


Forum Jump: