Author Topic: New Plugin : External IP  (Read 381 times)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
New Plugin : External IP
« on: August 27, 2017, 12:56:28 pm »
Well after many years as a forum member, with no programming experience I've attempted a number of plugin in the past with little/no success - mostly due to my ideas being well beyond my capabilities :)

But one thing I thought I could do ( to help me learn)  was a simple plugin that will show me my external IP and - seeing as it can be changed by my ISP;  when used within either a scene, PLEG or in the start up with luup.variable_watch it could notify me that my external IP address has been changed.

Attached is my first working attempt, which I'm calling v0.1

Note - v0.1 just captures the IP, the is no scheduled refresh other than on Luup restart and has been tested against UI5 only at the moment.

V0.1 - Creates a device on the UI, which displays your external facing IP address.

Future ideas/updates (which I would appreciate any and all help/guidance on)

a) Set the initialize function to loop through every 30 mins to check if the IP has changed
b) Make text on the front show the entire IP address (currently it seems to cut it off no matter what I do)
c) Make the device icon visible (not sure why the URL in the JSON is not working)
d) Store a history of IP changes in a txt/HTML file on Vera for history
e) Add a variable where you can set the refresh e.g default would be 30, but you can set to anything

Spin off..

i) As the current plugin grabs text from a website, look to evolve it some other instances can be created to capture information from other places.


* FYI - Your external IP information is already available via Vera's own Set Up / Net & Wifi / Network Troubleshooting option .
« Last Edit: August 27, 2017, 02:58:56 pm by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
Re: New Plugin : External IP
« Reply #1 on: August 27, 2017, 01:20:48 pm »
Just to add ..

This plugin is very much "a learn as I go" project, so for something more polished - have a look at the very versatile SiteSensor plugin - http://forum.micasaverde.com/index.php/topic,50440.0.html as that  can do the same thing..
« Last Edit: August 27, 2017, 02:59:41 pm by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
Re: New Plugin : External IP
« Reply #2 on: September 04, 2017, 04:07:48 am »
Hi.

To do a) :

a) Set the initialize function to loop through every 30 mins to check if the External IP address has changed

Is the luup.call_timer the best way to go to do that.(http://wiki.micasaverde.com/index.php/Luup_Declarations#.3Ctimed.3E_.28callback.29)

Code: [Select]
function recheckIP()
    --
    -- An interval-based timer to callback the Implementation file's  'initialize' function every 30 mins.
    --
    luup.call_timer("initialize", 1, "30m", "", "")
end

And would I place this callback as a new function within the Implementation file, and then have the main starting 'initialise' function call it using 'recheckIP ()' before it finishes/ends? 
« Last Edit: September 04, 2017, 04:10:41 am by parkerc »

Offline akbooer

  • Master Member
  • *******
  • Posts: 5130
  • Karma: +221/-67
  • "Less is more"
Re: New Plugin : External IP
« Reply #3 on: September 04, 2017, 04:15:26 am »
Actually, a plugin's init() function has some rather special features which should only be called once, including calling luup.set_failure() and giving some return parameters.

So what's best is to call a subsidiary function with call_timer()
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
Re: New Plugin : External IP
« Reply #4 on: September 04, 2017, 04:37:08 am »
Ok, thanks that's good to know - although this plugin is pretty basic it's best to follow best practice .

So to do that, I'm going to need to break up the current code in the Implementation file, as that is currently acting as one function.

@akbooer does the following within the Implementation file determine the only function that is called first (on start up)

Code: [Select]
</functions>
<startup>initialize</startup>
</implementation>

Am I correct in saying that everything else within the Implementation file is still read upon being loaded by Vera, but does the above mean that only the named function above is called/run?

If so - for a call back to work - am I correct in saying that I have to make reference to the luup.call_timer pointing to a new sperate function within that 'initialize' function?


 
« Last Edit: September 04, 2017, 04:39:01 am by parkerc »

Offline akbooer

  • Master Member
  • *******
  • Posts: 5130
  • Karma: +221/-67
  • "Less is more"
Re: New Plugin : External IP
« Reply #5 on: September 04, 2017, 05:51:55 am »
My recommendations are these:

  • Put at little as possible into the I_xxx.xml file
  • Put all your code into an L_xxx.lua file
  • Use a proper development environment

The reason for this is that Lua code can't easily be syntax checked when embedded in XML and some characters have to be escaped.  It's an unholy mess.  The best development tool I've found is ZeroBrane Studio - it will catch all those syntax error before it becomes a problem.

A minimal I_xx.xml file is something like this:

Code: [Select]
<?xml version="1.0"?>
<implementation>
   <files>L_xxx.lua</files>
   <startup>init</startup>
</implementation>

...you won't need anything else until you start implementing action calls in your plugin.

A skeleton L_xxx.lua file is:

Code: [Select]
local VERSION = "update this with every edit"

function init (devNo)
  luup.variable_set ("yourServiceID","Version", Version, devNo)
 
  --  other stuff goes here

  luup.set_failure (0)
  return true, "OK", "your plugin name goes here"
end

If you're being fancy, then add some stuff to the D_xxx.json file to display the version number in the plugin's control tab.

For a periodic callback, that's not linked to a day of the week or a day of the month, you might as well use luup.call_delay() rather than a timer.  You'd call that first from the init code and it would reschedule itself on every callback.
« Last Edit: September 04, 2017, 06:17:18 am by akbooer »
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
Re: New Plugin : External IP
« Reply #6 on: September 06, 2017, 03:41:37 am »
Many thanks @akbooer

In your example Implementation file example, what exactly is 'init', i assumed the <startup> section was used to call a specific function - so is init interpretated differently ?

You mention calling the luup.call_delay from the init code ; so does that me the unit code is everything in the xxxxx.lua I would create ?

Does the xxxxx.lua file still get uploaded into the same place (via the same route) as the Device and Implementation xml files etc.?

Regarding ZeroBrane, as I work primarily on an iPad, i can't use that, so instead while limited I use Textastic for the lua coding/syntax checking.

Offline RichardTSchaefer

  • Master Member
  • *******
  • Posts: 9572
  • Karma: +729/-136
    • RTS Services Plugins
Re: New Plugin : External IP
« Reply #7 on: September 06, 2017, 09:40:08 am »
init is the name of the function to be called.


Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
Re: New Plugin : External IP
« Reply #8 on: September 06, 2017, 09:56:14 am »
Thanks @RTS

Ok good - and by just by calling the ' init ' function's name (which as a side point - I assume I can call the function anything)  - it will know that it's now in a separate lua file ?

Offline akbooer

  • Master Member
  • *******
  • Posts: 5130
  • Karma: +221/-67
  • "Less is more"
Re: New Plugin : External IP
« Reply #9 on: September 06, 2017, 01:16:11 pm »
Yes, you can call it anything, as long as it matches what's in the <startup> tag. 

It needs to be in a file referenced in the <files> tag.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2330
  • Karma: +32/-44
  • Life Moves Pretty Fast....
    • Node Central
Re: New Plugin : External IP
« Reply #10 on: September 22, 2017, 01:26:05 pm »
Thanks to suggestions from @BulldogLowell, I've updated some of the LUA code, plus i've also found a difference resource for the external IP address checking. (There's still a lot of log/print statements in the attached test code, more for my own benefit than anything else.) - @Akbooer's suggestions to address later on

Code: [Select]
function logToVera(mssg)
  luup.log("External IP Plugin Reported : "..mssg)
end

function getexternalip (lul_device)
local status, ip = luup.inet.wget("https://api.ipify.org/?format=txt")
local newIP = ip: match "%d+%.%d+%.%d+%.%d+"
local existingIP, lastUpdateTime = luup.variable_get("urn:nodecentral-com:serviceId:ExternalIP1","ExternalIP", lul_device)
local oldIP = luup.variable_get("urn:nodecentral-com:serviceId:ExternalIP1","OldIP", lul_device)
  local time = os.time()

  logToVera("External IP has changed, so update made")
 
  print("Your new IP is : '"..newIP.."'")
  logToVera("your new IP is : '"..newIP.."'")
print("Your existing IP is : '"..existingIP.."'")
logToVera("Your existing IP is : '"..existingIP.."'")
print("Your old IP is : '"..oldIP.."'")
logToVera("Your old IP was : '"..oldIP.."'")
  print("Last Updated : '"..lastUpdateTime.."'")
logToVera("Last Updated : '"..lastUpdateTime.."'")
  print("Time now is : '"..lastUpdateTime.."'")
logToVera("Time now is : '"..lastUpdateTime.."'")

    if (oldIP == nil) then
      luup.variable_set("urn:nodecentral-com:serviceId:ExternalIP1","OldIP", "0.0.0.0", lul_device)
      luup.variable_set("urn:micasaverde-com:serviceId:HaDevice1", "LastUpdate", lastUpdateTime, lul_device)
      logToVera("No previous IP is present so adding a temporary one")
print ("No previous IP is present so adding a temporary one")
elseif (newIP == existingIP) then
      logToVera("External IP has not changed, so nothing to do")
print("External IP has not changed, so nothing to do")
      luup.variable_set("urn:micasaverde-com:serviceId:HaDevice1", "LastUpdate", lastUpdateTime, lul_device)
      luup.call_delay ("getexternalip", 3600) -- Check if the IP address has changed ever hour
elseif (newIP ~= existingIP) then
logToVera("External IP has changed")
print("External IP has changed")
luup.variable_set("urn:nodecentral-com:serviceId:ExternalIP1","OldIP", oldIP, lul_device)
luup.variable_set("urn:nodecentral-com:serviceId:ExternalIP1","ExternalIP", newIP, lul_device)
luup.variable_set("urn:micasaverde-com:serviceId:HaDevice1", "LastUpdate", lastUpdateTime, lul_device)
print("External IP has changed, so update made")
logToVera("External IP has changed, so update made")
      luup.call_delay ("getexternalip", 3600) -- Check if the IP address has changed ever hour
--end
end
end

getexternalip(376)
« Last Edit: September 22, 2017, 01:32:50 pm by parkerc »