Logic Machine Forum
LM phone call to phone number - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: LM phone call to phone number (/showthread.php?tid=4896)



LM phone call to phone number - AlexLV - 28.07.2023

Hi,

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

https://forum.logicmachine.net/showthread.php?tid=68&page=3&highlight=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-call-at-commands-to-set-up-voice-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


RE: LM phone call to phone number - admin - 08.08.2023

Try this (not tested):
Code:
function AT:call(number)
  self:send('ATD' .. number)
  os.sleep(8)
  self:send('ATH')
end



RE: LM phone call to phone number - AlexLV - 17.08.2023

(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


RE: LM phone call to phone number - admin - 17.08.2023

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')



RE: LM phone call to phone number - AlexLV - 19.08.2023

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


RE: LM phone call to phone number - Daniel - 21.08.2023

The message says it, If you want us to look drop full script not screenshot.


RE: LM phone call to phone number - AlexLV - 22.08.2023

(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


RE: LM phone call to phone number - Daniel - 23.08.2023

Drop this script to notepad++, select language LUA and it will highlight you which if belongs to which end.