Page 9 of 14

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 19:32
by ben53252642
Ahh I had the same issue with mine:

"Ben's iPhone"

in my case changing the single quotes to " allowed it to accept the single ' in my name.

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 19:54
by Calzor Suzay
I don't think it's that there's " " around either side

I think It's the fact I physically can't get a ’ into my Raspberry Pi.
I've just tried changing locale's UTF8, en_GB.ISO-8859-15 to no effect.

I could recall the iPhones and change there name but it's bugging me now :)

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 19:57
by ben53252642
SSH into the Pi and use nano?

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 19:59
by ben53252642
Actually you know you can just use the script editor in Domoticz right?

Mine is setup like this:
Screen Shot 2017-01-16 at 5.58.36 am.png
Screen Shot 2017-01-16 at 5.58.36 am.png (70.32 KiB) Viewed 4505 times
You don't actually have to put the script in the lua scripts folder of Domoticz, it can run from the web interface scripts UI just fine.

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 20:22
by Calzor Suzay
I was using nano via SSH and no I didn't know you could edit LUA scripts on the webpage gui.
/long breath, AHHHHHHHhhhhhh! , and smile :)
It seems to be working now as expected, thanks for your help.

I've deleted the old .lua script from the folder and rebooted but it does still seem to be running it as I'm seeing all the print commands I added still appear... How do I remove it?

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 20:54
by Calzor Suzay
Think I've sorted extra script now as well :)

Re: Find My iPhone implementation in LUA script

Posted: Sunday 15 January 2017 21:41
by Calzor Suzay
And battery details logging as well, awesome :)

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 18 January 2017 5:30
by blindlight
ben53252642 wrote:This version also gets the iPhone battery level, which is really cool cause Domoticz can chart how long my iPhone lasts on battery power. :D

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

Screen Shot 2017-01-16 at 3.14.44 am.png

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
getlocation works, but my battery level is still 0.0.
maybe some region problem. i'm in Shanghai.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 08 February 2017 17:25
by aleguid
are a new user, I followed the instructions but in the end the result is null. I have no errors in the logs and the dummy created are unchanged. you have any idea?

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

  -- Array of users to be checked
  users = {
            Alessio = {username = "mailmyaccount" ; password = "passwordmyaccount" ; devicename = "iPhone Alessio"};
                      }
  -- The latitude and longitude of your house (use Google Maps or similar to find this)
  homelongitude = 11.868779
  homelatitude = 43.566226
  -- Radius (in km) which will be used to determine if a device is at home
  radius = 0.1

  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, ', Italia', '') .. ' (' .. (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
thx

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 21 February 2017 23:04
by dvangulik
Hi guys, I am using Ben's implementation of the LUA script and it is working great. Thanks for that it would not have worked for me without your guidance. What leads me to my question. In my log it prints the power status; not charging or charging. I would like to use this data for some automation. Can you please help me to either create a virtual switch (charging; on, not charging: off) or a way to use the printed information in events? Thanks in advance for your support, it will be much appreciated.

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 28 February 2017 13:01
by cattoo
Now I got this error, don't know why. Anyone?

Code: Select all

Error: EventSystem: in Check_iphone: [string "-- Script to check the location of multiple i..."]:10: attempt to call a nil value

Re: Find My iPhone implementation in LUA script

Posted: Tuesday 28 February 2017 23:07
by rjblake
I used this for a while and while it worked mostly, there were times where it didn't update battery, or returned battery as 0%. No idea why, perhaps it was picking up other devices (e.g. iMac) for some reason, or perhaps Apple didn't feel like responding everytime.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 9:03
by Nautilus
cattoo wrote:Now I got this error, don't know why. Anyone?

Code: Select all

Error: EventSystem: in Check_iphone: [string "-- Script to check the location of multiple i..."]:10: attempt to call a nil value
It would help to know what is line 10 in your script :) The error could e.g. relate to a variable that is not given any value ( = nil).
rjblake wrote:I used this for a while and while it worked mostly, there were times where it didn't update battery, or returned battery as 0%. No idea why, perhaps it was picking up other devices (e.g. iMac) for some reason, or perhaps Apple didn't feel like responding everytime.
I've noticed that the battery level is quite often empty or 0%. I've chosen to ignore these in the script. As a presence detection method (that is based on the location of iPhone), this has been the most reliable so far. All geofence apps, pinging / arp scanning etc. have more or less failed or have been unreliable...:)

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 9:12
by Nautilus
dvangulik wrote:Hi guys, I am using Ben's implementation of the LUA script and it is working great. Thanks for that it would not have worked for me without your guidance. What leads me to my question. In my log it prints the power status; not charging or charging. I would like to use this data for some automation. Can you please help me to either create a virtual switch (charging; on, not charging: off) or a way to use the printed information in events? Thanks in advance for your support, it will be much appreciated.
In the script, you need a new variable (similar to lon / lat / batterystatus )and then store the charging status to it, the json output tells you how you need to define it, comapre to e.g. batterystatus:

Code: Select all

powerstateval = value.batteryStatus
(hint: look vor value and batteryStatus in the json output)

Then just create a virtual on / off switch and check it's current status and update it whether it is different than it is supposed to be :)

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 9:32
by cattoo
Nautilus wrote:
cattoo wrote:Now I got this error, don't know why. Anyone?

Code: Select all

Error: EventSystem: in Check_iphone: [string "-- Script to check the location of multiple i..."]:10: attempt to call a nil value
It would help to know what is line 10 in your script :) The error could e.g. relate to a variable that is not given any value ( = nil).
rjblake wrote:I used this for a while and while it worked mostly, there were times where it didn't update battery, or returned battery as 0%. No idea why, perhaps it was picking up other devices (e.g. iMac) for some reason, or perhaps Apple didn't feel like responding everytime.
I've noticed that the battery level is quite often empty or 0%. I've chosen to ignore these in the script. As a presence detection method (that is based on the location of iPhone), this has been the most reliable so far. All geofence apps, pinging / arp scanning etc. have more or less failed or have been unreliable...:)
It was the JSON script placement thats was wrong. But now I have a other issue
Error: EventSystem: in Check_iphone: [string "-- Script to check the location of multiple i..."]:38: bad argument #1 to 'pairs' (table expected, got nil)
Line 38 is the "for key" part

Code: Select all

output = json:decode(result)
    for key,value in pairs(output.content) do
      if value.name == credentials.devicename then

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 9:52
by Nautilus
I would add some print statements to see if you are getting the expected responses from the curl fetches. Check previous page in this thread and what ben... suggests :) Now it seems you are not getting the expected response. You can also try the curl from command line to make sure it works. One reason could be exotic iPhone name or password that contain some lua magic characters.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 12:43
by cattoo
Well I added this print (result) above handle:close() but under getlocation
and got my user info, token, current timezone and stuff like that. So it seems that I get logged in.
But when when ill add print (getlocation)
I get

Code: Select all

 LUA: 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: DELETED' -H 'Accept-Language: en-us' -H 'Connection: keep-alive' 'https://fmipmobile.icloud.com/fmipservice/device/USERNAME/initClient'
why is it like this?

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 13:37
by Nautilus
cattoo wrote:Well I added this print (result) above handle:close() but under getlocation
and got my user info, token, current timezone and stuff like that. So it seems that I get logged in.
But when when ill add print (getlocation)
I get

Code: Select all

 LUA: 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: DELETED' -H 'Accept-Language: en-us' -H 'Connection: keep-alive' 'https://fmipmobile.icloud.com/fmipservice/device/USERNAME/initClient'
why is it like this?
That is just printing just the curl command. It is used in the next line (io.popen). Then the interesting stuff after this is json decoding which I guess is not working as expected. The result of "output = json:decode(result)" is something faulty. How did you define the json file location, are you sure you have it there? Is it spelled correctly in your script?

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 14:18
by cattoo
The file is located here
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")(
And I've checked and the JSON file is there.

Re: Find My iPhone implementation in LUA script

Posted: Wednesday 01 March 2017 14:33
by rjblake
Nautilus wrote:...
I've noticed that the battery level is quite often empty or 0%. I've chosen to ignore these in the script. As a presence detection method (that is based on the location of iPhone), this has been the most reliable so far. All geofence apps, pinging / arp scanning etc. have more or less failed or have been unreliable...:)
Indeed - I do really like the functionality being able to log location and for the rest worked well. Wish my code was half as useful or tidy. Battery drain seemed a bit high if polled too often. I am experimenting with an app 'Locative' that I have found works really well too and only needs config on the phone. Also trying to work out how to exploit my Tado app and perhaps just use that, as it does its job just fine for the Thermostat