Find My iPhone implementation in LUA script

Moderator: leecollings

Post Reply
BluesBro
Posts: 54
Joined: Tuesday 13 August 2013 19:55
Target OS: -
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by BluesBro »

Is there a way to make the script send this info instead:

json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=<iframe%20width="365"%20height="300"%20frameborder="0"%20style="border:0"%20src="https://www.google.com/maps/embed/v1/pl ... n></iframe>

Should pop up like the attached image if possible...
Attachments
2016-12-16 13_33_56-Domoticz.png
2016-12-16 13_33_56-Domoticz.png (81.73 KiB) Viewed 3854 times
Nautilus
Posts: 722
Joined: Friday 02 October 2015 12:12
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Finland
Contact:

Re: Find My iPhone implementation in LUA script

Post by Nautilus »

BluesBro wrote:Is there a way to make the script send this info instead:

json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=<iframe%20width="365"%20height="300"%20frameborder="0"%20style="border:0"%20src="https://www.google.com/maps/embed/v1/pl ... n></iframe>

Should pop up like the attached image if possible...
Yes, check my post on previous page: http://www.domoticz.com/forum/viewtopic ... 00#p107716

As I describe, having some weird issues with it while a family member was travelling, I'm now using just:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(address, ' ','+')..'/@'..lat..','..lon..'">'..string.gsub(address, ', Finland', '')..'</a><br>('..drivedistance..' / '..drivetime..')'
which gives the person's position as address which is a clickable link that opens in a new tab (or google maps app if browsing with phone). The drivedistance / drivetime variable I parse from google maps api to see the actual distance (not just the "direct line" distance) and the expected drivetime...
BluesBro
Posts: 54
Joined: Tuesday 13 August 2013 19:55
Target OS: -
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by BluesBro »

Nautilus wrote:
BluesBro wrote:Is there a way to make the script send this info instead:

json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=<iframe%20width="365"%20height="300"%20frameborder="0"%20style="border:0"%20src="https://www.google.com/maps/embed/v1/pl ... n></iframe>

Should pop up like the attached image if possible...
Yes, check my post on previous page: http://www.domoticz.com/forum/viewtopic ... 00#p107716

As I describe, having some weird issues with it while a family member was travelling, I'm now using just:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(address, ' ','+')..'/@'..lat..','..lon..'">'..string.gsub(address, ', Finland', '')..'</a><br>('..drivedistance..' / '..drivetime..')'
which gives the person's position as address which is a clickable link that opens in a new tab (or google maps app if browsing with phone). The drivedistance / drivetime variable I parse from google maps api to see the actual distance (not just the "direct line" distance) and the expected drivetime...
I get this error when using your code:
lua: script_time_checkphones.lua:52: bad argument #1 to 'gsub' (string expected, got function)
stack traceback:
[C]: in function 'gsub'
script_time_checkphones.lua:52: in main chunk
[C]: ?
Nautilus
Posts: 722
Joined: Friday 02 October 2015 12:12
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Finland
Contact:

Re: Find My iPhone implementation in LUA script

Post by Nautilus »

BluesBro wrote:
Nautilus wrote:
BluesBro wrote:Is there a way to make the script send this info instead:

json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=<iframe%20width="365"%20height="300"%20frameborder="0"%20style="border:0"%20src="https://www.google.com/maps/embed/v1/pl ... n></iframe>

Should pop up like the attached image if possible...
Yes, check my post on previous page: http://www.domoticz.com/forum/viewtopic ... 00#p107716

As I describe, having some weird issues with it while a family member was travelling, I'm now using just:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(address, ' ','+')..'/@'..lat..','..lon..'">'..string.gsub(address, ', Finland', '')..'</a><br>('..drivedistance..' / '..drivetime..')'
which gives the person's position as address which is a clickable link that opens in a new tab (or google maps app if browsing with phone). The drivedistance / drivetime variable I parse from google maps api to see the actual distance (not just the "direct line" distance) and the expected drivetime...
I get this error when using your code:
lua: script_time_checkphones.lua:52: bad argument #1 to 'gsub' (string expected, got function)
stack traceback:
[C]: in function 'gsub'
script_time_checkphones.lua:52: in main chunk
[C]: ?
I assume you are not parsing the drive time or distance, did you remove those? Do you get an error from:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(address, ' ','+')..'/@'..lat..','..lon..'">'..address..'</a>'
I've modified the original so much that I'm not exactly sure what needs to be changed in order to get this to work. The point is anyhow that just change the "position_text = ..." to your liking and "anything" is possible...:)

Edit: I checked the first post and yes, now "address" is a function and "position" the result. So you need to have something like:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(position, ' ','+')..'/@'..lat..','..lon..'">'..position..'</a>'
BluesBro
Posts: 54
Joined: Tuesday 13 August 2013 19:55
Target OS: -
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by BluesBro »

Thank you! It's working now :-)
pinda
Posts: 2
Joined: Monday 19 December 2016 10:09
Target OS: NAS (Synology & others)
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by pinda »

edit: omg i switched the dummy switch and text name.....got it working now.

I'm doing this with almost zero script knowledge. So just followed the manual and tried some googling :)
Getting the following errors in domoticz on my synology nas. So any help would be welcome ;)

2016-12-19 10:05:01.658 Error: EventSystem: in check_iphone: [string "-- Script to check the location of multiple i..."]:51: bad argument #1 to 'match' (string expected, got nil)

2016-12-19 10:10:01.945 Error: EventSystem: in check_iphone: [string "-- Script to check the location of multiple i..."]:51: bad argument #1 to 'match' (string expected, got nil)

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 = 5
local m = os.date('%M')
if (m % interval == 0) then

  json = (loadfile "XXXX PATH/JSON.lua")()

  -- Array of users to be checked
  users = {
            Tom = {username = '[email protected]' ; password = 'XXXXXXXXXXX' ; devicename = 'XXXXXXXXX'};
          }
  -- The latitude and longitude of your house (use Google Maps or similar to find this)
  homelongitude = XXXXXXXXXX
  homelatitude = XXXXXXXXXX
  -- Radius (in km) which will be used to determine if a device is at home
  radius = 5

  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

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

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

    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_distance_str = string.match(otherdevices['Position ' .. user], '%(.*%)') or '(1000 km)'
        prev_distance = tonumber(string.sub(prev_distance_str, 2,-5))
        -- update text device, but only if postion has changed more than defined in "radius" to reduce log size
        if math.abs(prev_distance - distance) > radius then  
          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

end

return commandArray 
fiscvs
Posts: 6
Joined: Wednesday 16 November 2016 7:08
Target OS: -
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by fiscvs »

i got it to work but in prowl i get a notification that i came home every 5 minutes. What can i do to change that? I only want it to give me 1 notification when someone gets home. And when someone left, but not every 5 minutes! I know i am home ;)
ben53252642
Posts: 543
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Find My iPhone implementation in LUA script

Post by ben53252642 »

mvzut, change this in your first post. It allows for names like:

Ben's iPhone

devicename = "Ben's iPhone"};

Specifically swap the '' for double "" around the device name.
Unless otherwise stated, all my code is released under GPL 3 license: https://www.gnu.org/licenses/gpl-3.0.en.html
mvzut
Posts: 443
Joined: Thursday 12 November 2015 10:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Find My iPhone implementation in LUA script

Post by mvzut »

fiscvs wrote:i got it to work but in prowl i get a notification that i came home every 5 minutes. What can i do to change that? I only want it to give me 1 notification when someone gets home. And when someone left, but not every 5 minutes! I know i am home ;)
Hmmm... that's strange. It should only change the value of the virtual switches to "On" if it was off, using the following statements:

Code: Select all

if otherdevices['iPhone ' .. user] == 'Off' then
   commandArray['iPhone ' .. user] = 'On'
End
What do you see in the logs, does it report successive "On"s every 5 minutes?
Raspberry Pi 4 - RFXtrx433 - CC2531 Zigbee - Opentherm Gateway - P1 smart meter - Netatmo - Philips Hue - ELV Max! - ESP8266 DIY water meter - 6 x Sonos - 4 x IP cameras - Wall mounted tablet + Dashticz - Google Home integration - MANY switches/sensors
mvzut
Posts: 443
Joined: Thursday 12 November 2015 10:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: The Netherlands
Contact:

Re: Find My iPhone implementation in LUA script

Post by mvzut »

ben53252642 wrote:mvzut, change this in your first post. It allows for names like:

Ben's iPhone

devicename = "Ben's iPhone"};

Specifically swap the '' for double "" around the device name.
Good suggestion, I updated the original post.
Raspberry Pi 4 - RFXtrx433 - CC2531 Zigbee - Opentherm Gateway - P1 smart meter - Netatmo - Philips Hue - ELV Max! - ESP8266 DIY water meter - 6 x Sonos - 4 x IP cameras - Wall mounted tablet + Dashticz - Google Home integration - MANY switches/sensors
fiscvs
Posts: 6
Joined: Wednesday 16 November 2016 7:08
Target OS: -
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by fiscvs »

It seems the dummy switch doesnt toggle?

2017-01-10 12:50:02.175 LUA: Adress, Postcode, Netherlands
2017-01-10 12:50:03.665 EventSystem: Script event triggered: script_time_checkphones.lua

But the switch is not flipped. If i do it manually then the notification stops..

What have i forgotten?
blindlight
Posts: 4
Joined: Wednesday 11 January 2017 16:00
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by blindlight »

Great script!!
I've got it working.....for almost 48h
but i get an error this morning.

Code: Select all

Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_checkphones.lua: /home/pi/domoticz/scripts/lua/script_time_checkphones.lua:40: attempt to concatenate global 'stage2server' (a nil value)


so i put print(result) right before stage2server = string.match(.....) to see what stage1command gets. here's what log shows:

Code: Select all

LUA: HTTP/1.1 200 OK 
Server: AppleHttpServer/3b804a0 
Date: Wed, 11 Jan 2017 15:23:02 GMT 
Content-Type: application/json;charset=UTF-8 
Transfer-Encoding: chunked 
Connection: keep-alive 
X-Responding-Instance: fmipservice:10200801:st11p02me-fmipservice008:8001:16H103:2cc8f06 
X-Responding-Server: st11p02me-fmipservice008_001 
X-Responding-Partition: p02 
Vary: Accept-Encoding 
Strict-Transport-Security: max-age=31536000; includeSubDomains 
Set-Cookie: NSC_q02-gnjqtfswjdf=ffffffff12a4c85645525d5f4f58455e445a4a422971;path=/;secure;httponly 
via: icloudedge:hk03p01ic-zteu010412:7402:16G41:Hong Kong 
X-Apple-Request-UUID: a82b2ad2-6903-4d6c-91ca-80e675c434c0 
access-control-expose-headers: X-Apple-Request-UUID 
access-control-expose-headers: Via 
i see there's no "X-Apple-MMe-Host" in the result. maybe that's the reason stage2server is a nil.
so why suddenly it doesn't work? can anyone show me a correct response of stage1command?(maybe statue 200 is not ok?)
thx a lot!
User avatar
Egregius
Posts: 2582
Joined: Thursday 09 April 2015 12:19
Target OS: Linux
Domoticz version: v2024.7
Location: Beitem, BE
Contact:

Re: Find My iPhone implementation in LUA script

Post by Egregius »

I think Apple changed something yesterday or today.
There are also replies about not functioning anymore on the PHP implementation on Github.
Nautilus
Posts: 722
Joined: Friday 02 October 2015 12:12
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Finland
Contact:

Re: Find My iPhone implementation in LUA script

Post by Nautilus »

If someone has access to Vera plugins there seems to be a fix available already:
http://forum.micasaverde.com/index.php/ ... #msg306362
http://forum.micasaverde.com/index.php/ ... 7.885.html

Was not able to find a source for those anywhere, though, so I guess you need to have Vera to be able to download and use (them and hopefully see what they contain?)...
redina
Posts: 2
Joined: Wednesday 29 April 2015 19:01
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by redina »

They seemed to simplified it. They use the same dns-name for all. So no need to call twice.

Remove stage1Command (to find server) and call the generic server directly: fmipmobile.icloud.com

Snippet:

Code: Select all

for user,credentials in pairs(users) do
    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://fmipmobile.icloud.com/fmipservice/device/" .. credentials.username .."/initClient"
    local handle = io.popen(stage2command)
    local result = handle:read("*a")
    handle:close()
MarceldeJongNL
Posts: 43
Joined: Tuesday 03 May 2016 10:07
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.5108
Location: Barendrecht
Contact:

Re: Find My iPhone implementation in LUA script

Post by MarceldeJongNL »

Yes!

Changed

Code: Select all

stage2server = string.match(result, "X%-Apple%-MMe%-Host%:%s(.*%.icloud%.com)")
 
Into

Code: Select all

stage2server = "fmipmobile.icloud.com"


And it works again!
Hardware: Raspberry Pi 2B | RFXCOM RFXtrx433E v1 | Synology DS213+ | KaKu Clones | Conrad RSL switches | KAKu Doorbell Clone | USB Webcam | ICY Thermostat | Resol DL2 | Imatic Relay Board | Eminent 6230 | Eminent 6220 | iMatic 16 ports Relay Board
Nautilus
Posts: 722
Joined: Friday 02 October 2015 12:12
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Finland
Contact:

Re: Find My iPhone implementation in LUA script

Post by Nautilus »

redina wrote:They seemed to simplified it. They use the same dns-name for all. So no need to call twice.

Remove stage1Command (to find server) and call the generic server directly: fmipmobile.icloud.com
Thanks! :)

Out of curiosity - is the Vera source (for plugins at least) available somewhere or did you find this out from somewhere else?
redina
Posts: 2
Joined: Wednesday 29 April 2015 19:01
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Find My iPhone implementation in LUA script

Post by redina »

I just tested and saw that it's returning the data in the first call.
ropske
Posts: 483
Joined: Tuesday 12 August 2014 5:37
Target OS: Raspberry Pi / ODroid
Domoticz version: V3_8394
Location: Rumbeke,Belgium
Contact:

Re: Find My iPhone implementation in LUA script

Post by ropske »

Nautilus wrote:
BluesBro wrote:
Nautilus wrote:
Yes, check my post on previous page: http://www.domoticz.com/forum/viewtopic ... 00#p107716

As I describe, having some weird issues with it while a family member was travelling, I'm now using just:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(address, ' ','+')..'/@'..lat..','..lon..'">'..string.gsub(address, ', Finland', '')..'</a><br>('..drivedistance..' / '..drivetime..')'
which gives the person's position as address which is a clickable link that opens in a new tab (or google maps app if browsing with phone). The drivedistance / drivetime variable I parse from google maps api to see the actual distance (not just the "direct line" distance) and the expected drivetime...
I get this error when using your code:
lua: script_time_checkphones.lua:52: bad argument #1 to 'gsub' (string expected, got function)
stack traceback:
[C]: in function 'gsub'
script_time_checkphones.lua:52: in main chunk
[C]: ?
I assume you are not parsing the drive time or distance, did you remove those? Do you get an error from:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(address, ' ','+')..'/@'..lat..','..lon..'">'..address..'</a>'
I've modified the original so much that I'm not exactly sure what needs to be changed in order to get this to work. The point is anyhow that just change the "position_text = ..." to your liking and "anything" is possible...:)

Edit: I checked the first post and yes, now "address" is a function and "position" the result. So you need to have something like:

Code: Select all

position_text = '<a style="color:black" target="blank" href="https://www.google.com/maps/place/'..string.gsub(position, ' ','+')..'/@'..lat..','..lon..'">'..position..'</a>'

Hi Nautilus,

thanks for this script!
One question: is the link made where you can see your devices?
Because there i cannot click anythone that opens this 'map'

In my domoticz log i get a link and i can click it.

Am i doing something wrong?
Thanks :D
Nautilus
Posts: 722
Joined: Friday 02 October 2015 12:12
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Finland
Contact:

Re: Find My iPhone implementation in LUA script

Post by Nautilus »

ropske wrote:
Hi Nautilus,

thanks for this script!
One question: is the link made where you can see your devices?
Because there i cannot click anythone that opens this 'map'

In my domoticz log i get a link and i can click it.

Am i doing something wrong?
Thanks :D
Hi,

not sure if I quite understand the question :) What do you mean with Domoticz log? There are two things updated with the script, the On/Off switch which only gives the status whether the phone is at home or not (i.e. no links there) and then the "text sensor" that shows the current position as text. And this text you can format into a clickable link as well as discussed earlier in this thread.

Maybe you have some debug setting on that writes the text sensor value to log as well, but the sensor itself (once you create it) is found on the Utility tab (add as favorite to see it on the Dashboard)...
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests