Page 2 of 14

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 13 September 2016 21:06
by Egregius
Add some prints to the script and watch the logfile.

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 13 September 2016 21:57
by joto
Hi again
my bad guys, I'm running on Windows and that's probably why it doesn't work... :(

Never used lua or curl before so it will probably take a while for me to find the OS-dependent parts.
Problems is a good way to learn new things :D

Find My iPhone implementation in LUA script

Posted: Tuesday 13 September 2016 22:47
by mvzut
joto wrote:Hi again
my bad guys, I'm running on Windows and that's probably why it doesn't work... :(

Never used lua or curl before so it will probably take a while for me to find the OS-dependent parts.
Problems is a good way to learn new things :D
That explains a lot Image.
Not sure if there are alternatives to curl that are standard present on Windows systems. But you could probably simply install a curl version for Windows: https://curl.haxx.se/download.html
I haven't tested it, so no guarantees Image

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 13 September 2016 22:55
by Egregius
Do you know you can (ab)use the same service to sent text messages to ios? They even make sound when the phone is in do not disturb mode or silent.

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 13 September 2016 23:36
by G3rard
mvzut wrote:
Egregius wrote:Could it be that you need to manually update the text sensor once it a text like "Westlaan 401-407, 8800 Roeselare (6.7 km)"?
I guess you could be right! At first, I didn't have the check that it was only updated when the difference with the previous position was large enough. I get the previous distance from the contents of the text field, so when that doesn't contain "(x.x km)" it will never be updated. I have added a line in the script

Code: Select all

if prev_distance == nil then prev_distance = 1000 end
See original post where it needs to be placed. Can you let me know if this helps?
Thanks for this script!

I had to change the line

Code: Select all

prev_dist = tonumber(string.sub(string.match(otherdevices['Position ' .. user], '%(.*%)'), 2,-5))
to

Code: Select all

prev_dist = tonumber(string.sub(string.match(otherdevices_svalues['Position ' .. user], '%(.*%)'), 2,-5))
to get this working.

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 13 September 2016 23:37
by G3rard
Egregius wrote:Do you know you can (ab)use the same service to sent text messages to ios? They even make sound when the phone is in do not disturb mode or silent.
Nice, do you have some more information available on this?

Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 0:16
by mvzut
G3rard wrote:
mvzut wrote:
Egregius wrote:Could it be that you need to manually update the text sensor once it a text like "Westlaan 401-407, 8800 Roeselare (6.7 km)"?
I guess you could be right! At first, I didn't have the check that it was only updated when the difference with the previous position was large enough. I get the previous distance from the contents of the text field, so when that doesn't contain "(x.x km)" it will never be updated. I have added a line in the script

Code: Select all

if prev_distance == nil then prev_distance = 1000 end
See original post where it needs to be placed. Can you let me know if this helps?
Thanks for this script!

I had to change the line

Code: Select all

prev_dist = tonumber(string.sub(string.match(otherdevices['Position ' .. user], '%(.*%)'), 2,-5))
to

Code: Select all

prev_dist = tonumber(string.sub(string.match(otherdevices_svalues['Position ' .. user], '%(.*%)'), 2,-5))
to get this working.
Strange, here it (also) works without using svalues. Makes you wonder how two Domoticz systems can behave so differently? Are you perhaps on a stable (older) version?

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 7:32
by Egregius
G3rard wrote:
Egregius wrote:Do you know you can (ab)use the same service to sent text messages to ios? They even make sound when the phone is in do not disturb mode or silent.
Nice, do you have some more information available on this?
Only in PHP :lol:
It's included in my pass2php script (http://egregius.be/tag/domoticz/ and https://github.com/Egregius/PHP-Custom- ... r-Domoticz)
Once operational it's enough to have a line like this:

Code: Select all

ios('test message with high priority');
 
Then the message is sent as if it would be sent from the findmyiphone service, because of that it always makes sound. Ideal for those really important messages like movement in the living room while you're sleeping and the phone is on do not disturb mode. Mine is always in that mode during the night.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 8:08
by cattoo
Well i still have the issue as my post said :(

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 8:19
by Egregius
Place the json.lua file in one of the folders where it's searching. If the folder doesn't exist just make it.

ex
/usr/local/lib/lua/5.2/

sudo mkdir /usr/local/lib/lua
sudo mkdir /usr/local/lib/lua/5.2
sudo cp /home/pi/domoticz/scripts/lua/json.lua /usr/local/lib/lua/5.2

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 8:28
by cattoo
Well its not the JSON file thats the issue. Check this post and see the rest of the posts :D
http://www.domoticz.com/forum/viewtopic ... 318#p96326

Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 8:52
by mvzut
cattoo wrote:Well its not the JSON file thats the issue. Check this post and see the rest of the posts :D
http://www.domoticz.com/forum/viewtopic ... 318#p96326
I think I see what the problem is. I was looking at the wrong line all the time, line 56 in your script seems to be the line with the UpdateDevice command, right? In that line there is a space missing after 'iPhone'. I had that typo for a brief moment in my original post, but corrected it as soon as I saw it. Apparently you copied the code before that. Let me know if it works now! If so, please remove the "position_text = position" if you want distance info in your text devices.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 9:30
by cattoo
mvzut wrote:
cattoo wrote:Well its not the JSON file thats the issue. Check this post and see the rest of the posts :D
http://www.domoticz.com/forum/viewtopic ... 318#p96326
I think I see what the problem is. I was looking at the wrong line all the time, line 56 in your script seems to be the line with the UpdateDevice command, right? In that line there is a space missing after 'iPhone'. I had that typo for a brief moment in my original post, but corrected it as soon as I saw it. Apparently you copied the code before that. Let me know if it works now! If so, please remove the "position_text = position" if you want distance info in your text devices.
Well, i copied the script again and got new errors

Code: Select all

Error: EventSystem: in Iphone: [string "-- Script to check the location of multiple i..."]:75: 'end' expected (to close 'if' at line 8) near
Its getting closer....

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 9:35
by mcmikev
I still have some strange behavior.

The script seems to be running fine. I have added some print('debug') lines to see where the scripts stops or fininshes.
It looks like te whole scripts is being run but nothing is changed (switches or text swtich).

What could be the issue for that?

This is de "debug" for the script.

Code: Select all

2016-09-14 09:17:00.304 LUA: User check
2016-09-14 09:17:00.305 LUA: end User check
2016-09-14 09:17:00.305 LUA: funct adres
2016-09-14 09:17:00.305 LUA: end funct adres
2016-09-14 09:17:00.305 LUA: start stage1command
2016-09-14 09:17:01.255 LUA: end stage1command
2016-09-14 09:17:01.262 LUA: start stage2command
2016-09-14 09:17:01.847 LUA: end stage2command
2016-09-14 09:17:01.847 LUA: start json decode
2016-09-14 09:17:02.809 LUA: end stage1command
2016-09-14 09:17:02.809 LUA: start stage2command
2016-09-14 09:17:03.395 LUA: end stage2command
2016-09-14 09:17:03.396 LUA: start json decode
2016-09-14 09:17:03.414 LUA: end json decode
This is my script (with editted usernames and location for privacy) and the debug print lines.

Code: Select all

-- Script to check the location of multiple iPhones every X minutes,
-- test if they are "home" and represent this using virtual switches

commandArray = {}
-- polling interval in minutes (1-59), setting this too low may drain the phones' batteries
interval = 1
local m = os.date('%M')
if (m % interval == 0) then

  json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
print('User check') 
  -- Array of users to be checked
  users = {
            Mike = {username = 'me' ; password = 'me' ; devicename = 'iPhone Mike'};
            Cez  = {username = 'her' ; password = 'her' ; devicename = 'iPhone Cez'}
           -- Person3  = {username = '[email protected]' ; password = 'password3' ; devicename = 'iPhone Person3'}
          }
print('end User check') 
 -- The latitude and longitude of your house (use Google Maps or similar to find this)
  homelongitude = 14.938646 
  homelatitude = 50.504517
  -- Radius (in km) which will be used to determine if a device is at home
  radius = 0.5
print('funct adres')
  function address(longitude, latitude)
    command = "curl -s https://maps.googleapis.com/maps/api/geocode/json?latlng=" .. latitude .. "," .. longitude .. "&sensor=false"
    local handle = io.popen(command)
    local result = handle:read("*a")
    handle:close()
    output = json:decode(result)
    return output.results[1].formatted_address
  end
print('end funct adres')
print('start stage1command')
  for user,credentials in pairs(users) do
    stage1command = "curl -s -X POST -D - -o /dev/null -L -u '" .. credentials.username .. ":" .. credentials.password .. "' -H 'Content-Type: application/json; charset=utf-8' -H 'X-Apple-Find-Api-Ver: 2.0' -H 'X-Apple-Authscheme: UserIdGuest' -H 'X-Apple-Realm-Support: 1.0' -H 'User-agent: Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)' -H 'X-Client-Name: iPad' -H 'X-Client-UUID: 0cf3dc501ff812adb0b202baed4f37274b210853' -H 'Accept-Language: en-us' -H 'Connection: keep-alive' https://fmipmobile.icloud.com/fmipservice/device/" .. credentials.username .."/initClient"
    local handle = io.popen(stage1command)
    local result = handle:read("*a")
    handle:close()
print('end stage1command')

print('start stage2command')
    stage2server = string.match(result, "X%-Apple%-MMe%-Host%:%s(.*%.icloud%.com)")
    stage2command = "curl -s -X POST -L -u '" .. credentials.username .. ":" .. credentials.password .. "' -H 'Content-Type: application/json; charset=utf-8' -H 'X-Apple-Find-Api-Ver: 2.0' -H 'X-Apple-Authscheme: UserIdGuest' -H 'X-Apple-Realm-Support: 1.0' -H 'User-agent: Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)' -H 'X-Client-Name: iPad' -H 'X-Client-UUID: 0cf3dc501ff812adb0b202baed4f37274b210853' -H 'Accept-Language: en-us' -H 'Connection: keep-alive' https://" .. stage2server .. "/fmipservice/device/" .. credentials.username .."/initClient"
    local handle = io.popen(stage2command)
    local result = handle:read("*a")
    handle:close()
print('end stage2command')
print('start json decode')
    output = json:decode(result)
    for key,value in pairs(output.content) do
      if value.name == credentials.devicename then
        lon = value.location.longitude
        lat = value.location.latitude
        distance = math.sqrt(((lon - homelongitude) * 111.320 * math.cos(math.rad(lat)))^2 + ((lat - homelatitude) * 110.547)^2)  -- approximation
        position = address(lon,lat)
        position_text = string.gsub(position, ', Netherlands', '') .. ' (' .. (math.floor(distance*10+0.5)/10) .. ' km)'
        prev_dist = tonumber(string.sub(string.match(otherdevices['Position ' .. user], '%(.*%)'), 2,-5))
        if prev_distance == nil then prev_distance = 1000 end
        if math.abs(prev_dist - distance) > radius then   -- only update text device if postion has changed more than defined in "radius" to reduce log size 
          table.insert(commandArray,{['UpdateDevice'] = otherdevices_idx['Position ' .. user] .. '|0|' .. position_text})
        end
        --print('iPhone ' .. user .. ': ' .. math.floor(distance*100+0.5)/100 .. ' km from home')
        if distance < radius  then
          if otherdevices['iPhone ' .. user] == 'Off' then
            commandArray['iPhone ' .. user] = 'On'
            table.insert(commandArray, {['SendNotification'] = 'Presence update#' .. user .. ' came home'})
          end
        else
          if otherdevices['iPhone ' .. user] == 'On' then
            commandArray['iPhone ' .. user] = 'Off'
            table.insert(commandArray, {['SendNotification'] = 'Presence update#' .. user .. ' left home'})
          end
        end
      end
    end
  end
print('end json decode')

end

return commandArray
Hope someone can tell me what is going wrong. No errors are being given.

Thanks.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 9:43
by Egregius
You don't have any print in the if value.name == credentials.devicename block. I would one there.
Also remove the -- before the print ('iPhone... line.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 10:05
by mcmikev
I have added some more print lines none of these are shown in the log

Maybe some extra information : I run on RPI2B with domoticz image.

Code: Select all

print('start json decode')
    output = json:decode(result)
    for key,value in pairs(output.content) do
      if value.name == credentials.devicename then
        lon = value.location.longitude
        lat = value.location.latitude
        distance = math.sqrt(((lon - homelongitude) * 111.320 * math.cos(math.rad(lat)))^2 + ((lat - homelatitude) * 110.547)^2)  -- approximation
        print(distance)
	position = address(lon,lat)
        print(lon)
        print(lat)
        position_text = string.gsub(position, ', Netherlands', '') .. ' (' .. (math.floor(distance*10+0.5)/10) .. ' km)'
        prev_dist = tonumber(string.sub(string.match(otherdevices['Position ' .. user], '%(.*%)'), 2,-5))
        if prev_distance == nil then prev_distance = 1000 end
        if math.abs(prev_dist - distance) > radius then   -- only update text device if postion has changed more than defined in "radius" to reduce log size 
          table.insert(commandArray,{['UpdateDevice'] = otherdevices_idx['Position ' .. user] .. '|0|' .. position_text})
        end
        print('iPhone ' .. user .. ': ' .. math.floor(distance*100+0.5)/100 .. ' km from home')
        if distance < radius  then
          if otherdevices['iPhone ' .. user] == 'Off' then
            commandArray['iPhone ' .. user] = 'On'
            table.insert(commandArray, {['SendNotification'] = 'Presence update#' .. user .. ' came home'})
          end

Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 10:31
by mvzut
cattoo wrote:
mvzut wrote:
cattoo wrote:Well its not the JSON file thats the issue. Check this post and see the rest of the posts :D
http://www.domoticz.com/forum/viewtopic ... 318#p96326
I think I see what the problem is. I was looking at the wrong line all the time, line 56 in your script seems to be the line with the UpdateDevice command, right? In that line there is a space missing after 'iPhone'. I had that typo for a brief moment in my original post, but corrected it as soon as I saw it. Apparently you copied the code before that. Let me know if it works now! If so, please remove the "position_text = position" if you want distance info in your text devices.
Well, i copied the script again and got new errors

Code: Select all

Error: EventSystem: in Iphone: [string "-- Script to check the location of multiple i..."]:75: 'end' expected (to close 'if' at line 8) near
Its getting closer....
Ok, sorry, missed an "end" in line 54, see updated original post again.

The problem is that I have been editing it based on feedback from this forum and my own improvement ideas, but without testing. I do test things in my own version of the script, but that's already different again since I keep on trying and adding stuff. Classic case of bad version control. I don't have a lot of experience in programming, now learning these things the hard way Image. Sorry for the inconvenience!

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 12:07
by mvzut
mcmikev wrote:I have added some more print lines none of these are shown in the log

Maybe some extra information : I run on RPI2B with domoticz image.

Code: Select all

print('start json decode')
    output = json:decode(result)
    for key,value in pairs(output.content) do
      if value.name == credentials.devicename then
        lon = value.location.longitude
        lat = value.location.latitude
        distance = math.sqrt(((lon - homelongitude) * 111.320 * math.cos(math.rad(lat)))^2 + ((lat - homelatitude) * 110.547)^2)  -- approximation
        print(distance)
	position = address(lon,lat)
        print(lon)
        print(lat)
        position_text = string.gsub(position, ', Netherlands', '') .. ' (' .. (math.floor(distance*10+0.5)/10) .. ' km)'
        prev_dist = tonumber(string.sub(string.match(otherdevices['Position ' .. user], '%(.*%)'), 2,-5))
        if prev_distance == nil then prev_distance = 1000 end
        if math.abs(prev_dist - distance) > radius then   -- only update text device if postion has changed more than defined in "radius" to reduce log size 
          table.insert(commandArray,{['UpdateDevice'] = otherdevices_idx['Position ' .. user] .. '|0|' .. position_text})
        end
        print('iPhone ' .. user .. ': ' .. math.floor(distance*100+0.5)/100 .. ' km from home')
        if distance < radius  then
          if otherdevices['iPhone ' .. user] == 'Off' then
            commandArray['iPhone ' .. user] = 'On'
            table.insert(commandArray, {['SendNotification'] = 'Presence update#' .. user .. ' came home'})
          end
From your debugging output I conclude that getting the info from Apple using curl and json-decoding works fine. But if the "print(lon)" and "print(lat)" do not show up in the log, that must mean that the "if value.name == credentials.devicename" is never true. Are you sure you typed the name of your iPhone correctly in the "users" array? Are there any special characters in it maybe? You could adda a print(result) after "local result = handle:read("*a")". That should print a very long string in the log with all your device info. Try to look for your device name in it. Does it show up, and how is it exactly spelled?

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 12:17
by mcmikev
Just discovered that It is not the switch name but device name of the iphone :shock: :shock:

Changed that and now I get more :-)
But get error from line 53

2016-09-14 12:16:19.411 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_checkphones.lua: /home/pi/domoticz/scripts/lua/script_time_checkphones.lua:53: bad argument #1 to 'sub' (string expected, got nil)

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 14 September 2016 13:22
by cattoo
Got error on row 54 aswell

Code: Select all

Error: EventSystem: in Check_iphone: [string "-- Script to check the location of multiple i..."]:54: bad argument #1 to 'match' (string expected, got nil)