Page 8 of 14
Re: Find My iPhone implementation in LUA script
Posted: Friday 13 January 2017 12:28
by ropske
Hi,
sorry, i was indeed not really clear :p
i have indeed a print(position_text) so it shows up in my domoticz log
here i see a link that i can press and it opens a popup with visible location from google maps
but in in device with text sensor, i can see the string location, but it's not a link there, so i does not open a popup
thank you
Re: Find My iPhone implementation in LUA script
Posted: Friday 13 January 2017 14:01
by Nautilus
And you are updating the text sensor with exactly the same "position text"? The position changes correctly in the text sensor? Do you see the link text (beginning with "<a") or just the location. If not, are you sure you cannot click it?
Maybe some screenshots and code snippets would be in order to troubleshoot further...

Re: Find My iPhone implementation in LUA script
Posted: Friday 13 January 2017 19:32
by ropske
hmm, now it's suddenly working, seems i forgot to do a 'refresh' of the page lol
sorry to disturb

Re: Find My iPhone implementation in LUA script
Posted: Saturday 14 January 2017 21:35
by Calzor Suzay
I can't seem to get this working but have no visible errors...
The script is in place and no errors on system log for Domoticz, I know it's running as if I edit it to say blah somewhere then every minute it complains in the log about 'blah'
I created a hardware device called Freds iPhone, then two dummy devices off this a text one for "Position Fred" and a switch "iPhone Fred".
Code: Select all
-- Array of users to be checked
users = {
Fred = {username = "[email protected]" ; password = "fred" ; devicename = "Fred's iPhone"};
}
-- The latitude and longitude of your house (use Google Maps or similar to find this)
homelongitude = -121.886329
homelatitude = 37.338208
-- Radius (in km) which will be used to determine if a device is at home
radius = 1
The Device name in the script matches how it's presented in iCloud, it doesn't match the dummy hardware device in Domoticz as it seems you can't have ' in the name, maybe a bug in Domoticz?
The long/latitude are San Jose so it should trigger

The switch is permanently off, the text field just has hello world from when I created it.
What can I do to check it's running/working etc?
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 5:03
by ben53252642
Mine just stopped working with no changes to the script, is anyone else having issues?
Code: Select all
2017-01-15 14:54:01.970 Error: EventSystem: in iPhoneLocation: [string "-- Script to check the location of multiple i..."]:38: attempt to concatenate global 'stage2server' (a nil value)
Tried PHP-FindMyiPhone (
https://github.com/albeebe/PHP-FindMyiPhone) as well which I previously used for testing but getting:
Wondering if Apple have changed the API in some way?
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 7:36
by Egregius
The PHP implementation works fine here.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 15:21
by ben53252642
This is a more efficient version of the script which also solved the below error message RE stage2server that I was receiving:
Code: Select all
2017-01-15 14:54:01.970 Error: EventSystem: in iPhoneLocation: [string "-- Script to check the location of multiple i..."]:38: attempt to concatenate global 'stage2server' (a nil value)
New code:
Code: Select all
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 "/root/domoticz/scripts/lua/JSON.lua")()
-- Array of users to be checked
users = {
Ben = {username = "USERNAME" ; password = "PASSWORD" ; devicename = "Ben's iPhone"};
}
-- The latitude and longitude of your house (use Google Maps or similar to find this)
homelongitude = 1.23456789
homelatitude = 9.87654321
-- Radius (in km) which will be used to determine if a device is at home
radius = 0.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
getlocation = "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(getlocation)
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, ', Australia', '') .. ' (' .. (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
It's possible to get all the information needed from iCloud without the stage1 / stage2 servers in the original script. This curl command can get everything:
curl -s -X POST -L -u 'USERNAME: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/fmipservi ... initClient'
Simply change the two USERNAME and one PASSWORD fields to get all the data.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 16:31
by Calzor Suzay
Tried code above, again no errors but I'm seeing nothing written to me Switch or Text sensor.
I'm assuming you just need to match the "users = { Ben " bit from the script to your "iPhone Ben" and "Ben Position" devices?
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 16:47
by ben53252642
Yes it should just map to those devices in Domoticz,
You should see it updating in the status log tab:

- Screen Shot 2017-01-16 at 2.46.35 am.png (173.4 KiB) Viewed 3668 times
Remember the Position text string will only update if you go outside the set area.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 17:05
by Calzor Suzay
Nothing in my log

Can I try print(variable) in my script to see it's connecting properly to something and getting data?
BTW I set the long/latitude to no where near I live so it should trigger.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 17:10
by ben53252642
Try adding
print (getlocation) under getlocation, see what that shows.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 17:15
by ben53252642
This version also gets the iPhone battery level, which is really cool cause Domoticz can chart how long my iPhone lasts on battery power.
Just add a percentage sensor device called: iPhone Battery USER (in my case USER is Ben)

- Screen Shot 2017-01-16 at 6.31.49 am.png (23.93 KiB) Viewed 3598 times

- Screen Shot 2017-01-16 at 3.14.44 am.png (79.77 KiB) Viewed 3663 times
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 "/root/domoticz/scripts/lua/JSON.lua")()
-- Array of users to be checked
users = {
Ben = {username = "USERNAME" ; password = "PASSWORD" ; devicename = "Ben's iPhone"};
}
-- The latitude and longitude of your house (use Google Maps or similar to find this)
homelongitude = 1.23456789
homelatitude = 9.87654321
-- Radius (in km) which will be used to determine if a device is at home
radius = 0.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
getlocation = "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: d98c8ae0db3311e687b92890643032df' -H 'Accept-Language: en-us' -H 'Connection: keep-alive' https://fmipmobile.icloud.com/fmipservice/device/" .. credentials.username .."/initClient"
local handle = io.popen(getlocation)
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
bat = value.batteryLevel * 100 / 1
powerstateval = value.batteryStatus
table.insert(commandArray,{['UpdateDevice'] = otherdevices_idx['iPhone Battery ' .. user] .. '|0|' .. bat})
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, ', Australia', '') .. ' (' .. (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, ' .. bat .. '% battery remaining. PowerState: '.. powerstateval ..' ')
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
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 17:35
by Calzor Suzay
Ok with print (getlocation) I get.
Code: Select all
2017-01-15 16:33:00.105 LUA: curl -s -X POST -L -u '[email protected]:pass' -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/[email protected]/initClient
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 18:07
by ben53252642
Calzor Suzay wrote:Ok with print (getlocation) I get.
Code: Select all
2017-01-15 16:33:00.105 LUA: curl -s -X POST -L -u '[email protected]:pass' -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/[email protected]/initClient
Try print (result) above handle:close() but under getlocation
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 18:16
by Calzor Suzay
Well that gives me a whole bunch of stuff so looks like it's logging on ok
Code: Select all
2017-01-15 17:13:01.948 LUA: {"userInfo":{"firstName":"Fred","lastName":"Bloggs","membersInfo":null,"hasMembers":false},"serverContext":{"minCallbackIntervalInMS":5000,"enable2FAFamilyActions":false,"preferredLanguage":"en-gb","lastSessionExtensionTime":null,"enableMapStats":true,"callbackIntervalInMS":2000,"validRegion":true,"timezone":{"currentOffset":0,"previousTransition":1477789199999,"previousOffset":3600000,"tzCurrentName":"+00:00","tzName":"Europe/London"},"authToken":"AQAAAABYZAStk2LWr-potc~","maxCallbackIntervalInMS":60000,"classicUser":false,"isHSA":false,"trackInfoCacheDurationInSecs":86400,"imageBaseUrl":"https://statici.icloud.com","minTrackLocThresholdInMts":100,"maxLocatingTime":90000,"sessionLifespan":900000,"info":"Bh7nojqtLwCe6rDjgkpwtvlxJrjwoU8eu6iFQUgrSWh","prefsUpdateTime":1416502995675,"useAuthWidget":false,"clientId":"ZGV8xNDg0NTAwMzgxODc4","enable2FAFamilyRemove":false,"serverTimestamp":1484500381884,"macCount":0,"deviceLoadStatus":"200","maxDeviceLoadTime":60000,"prsId":616046716,"showSllNow":false,"cloudUser":true,"enable2FAErase":false},"alert":null,"userPreferences":{"touchPrefs":{}},"content":[{"msg":null,"canWipeAfterLock":true,"wipeInProgress":false,"lostModeEnabled":false,"activationLocked":true,"passcodeLength":6,"deviceStatus":"200","deviceColor":"3b3b3c-b4b5b9","features":{"MSG":true,"LOC":true,"LLC":false,"CLK":false,"TEU":true,"LMG":false,"SND":true,"CLT":false,"LKL":false,"SVP":false,"LST":true,"LKM":false,"WMG":true,"XRM":false,"PIN":false,"LCK":true,"REM":false,"CWP":false,"KEY":false,"KPD":false,"WIP":true},"lowPowerMode":false,"rawDeviceModel":"iPhone7,2","id":"pDHwh4/AuHYVNSUzmWV","remoteLock":null,"isLocating":true,"modelDisplayName":"iPhone","lostTimestamp":"","batteryLevel":0.55,"mesg":null,"locationEnabled":true,"lockedTimestamp":null,"locFoundEnabled":false,"snd":null,"fmlyShare":false,"lostDevice":null,"lostModeCapable":true,"wipedTimestamp":null,"deviceDisplayName":"iPhone 6","prsI
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 18:25
by ben53252642
It's probably not having a JSON.lua in the location that's specified in the path:
json = (loadfile "/root/domoticz/scripts/lua/JSON.lua")()
Read the first post, download the JSON.lua and specify the path to it.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 18:36
by Calzor Suzay
Mine is json = (loadfile "/home/osmc/domoticz/scripts/lua/JSON.lua")()
and it works as when I didn't have it I got loads or errors in the log appear, I downloaded the one mentioned in the link and then chown the script and JSON.lua file to OSMC:OSMC as that's the OS I run.
osmc@osmc:~/domoticz/scripts/lua$ ls -l
total 68
-rw-r--r-- 1 osmc osmc 55197 Jan 15 17:28 JSON.lua
-rw-r--r-- 1 osmc osmc 1870 Oct 19 15:11 script_device_demo.lua
-rw-r--r-- 1 osmc osmc 3535 Jan 15 17:33 script_time_checkphones.lua
-rw-r--r-- 1 osmc osmc 1932 Oct 19 15:11 script_time_demo.lua
I re downloaded to it to check.
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 18:42
by Calzor Suzay
Ok with this in the code
Code: Select all
output = json:decode(result)
for key,value in pairs(output.content) do
print ("Before If")
print (value.name)
print (credentials.devicename)
print (value.location.longitude)
print (value.location.latitude)
if value.name == credentials.devicename then
lon = value.location.longitude
lat = value.location.latitude
print (lon)
print ("after if")
I get
Code: Select all
2017-01-15 17:47:01.878 LUA: Before If
2017-01-15 17:47:01.878 LUA: Fred’s iPhone
2017-01-15 17:47:01.878 LUA: Fred's iPhone
2017-01-15 17:47:01.878 LUA: 0.25754617542079
2017-01-15 17:47:01.878 LUA: 50.837107226956
*Name & location tweaked
Edit just noticed the different apostrophe...

Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 19:01
by ben53252642
So is it working now? It's got to be something simple, your previous post showed an iPhone battery level (0.55 translates to 55%) so it's getting the data...
You sure you named the devices right? "iPhone Fred" etc...
Re: Find My iPhone implementation in LUA script
Posted: Sunday 15 January 2017 19:26
by Calzor Suzay
No I can't match the apostrophe it's using in the name of the phone.
It wants this which I copied pasted from the log ’
The only two I have are '` which don't match.
I thought I'd copy from the log into Putty directly but it translates it to a .
So then I thought I'd FTP the file off, edit in to Notepad++ which worked and Ftp'd back but then it changes it to "Freds ^ ^ s iPhone"
Do I have sort of language, keyboard mapping weirdness?