Monday, 13 February 2017

Finding the IP on a Pi using hostname

I was looking for a really easy method of finding the IP address on a Raspberry Pi.


I wanted a method I could use in a program to tell which bird box was returning data asynchronously.


And I was hoping to avoid having to hunt for the IP address string, buried somewhere in a block of text created by a command like ifconfig.


the requirement


My battery operated Picaxe-Pi bird box measures the battery voltage and overlays the status on the video stream. However, at this time of year the box activity is quite low. Typically a bird may stick its head in the box mid-morning. This triggers the system to start up and run, and if no further activity trips the box, it shuts down again.

I can remotely monitor the box with a program that pings a bunch of IP addresses. This gives an audible alarm when a box is on, and a visual display when the box is off (i.e. Picaxe is powered, but not the Pi).

So the problem is this; if I have been out for the day, I don't know the current state of the battery. This is not too much of a problem with the Pergola box because I can reach it, manually trigger the system, and then check the monitor display. But once the Maple tree box has been deployed, this won't be possible, because it will be 3m up a tree.

What I need is a display on my monitor to show the battery state for the last time that the box was on.

a solution


The Gambas programs in the monitor and each of the bird boxes can communicate via sockets. The initial idea was for the monitor to ask the box for the current battery level. In fact, as this data is all I want at the moment, I only have to create a client socket on the monitor and request a connection to the box, for the box to know it should send back battery data.

For example; the bird box provides a server socket, so the code just has to:-
  1. set a suitable (non-conflicting) local port (e.g. 12346 is not reserved or already in use on my Pi)
  2. run the socket .Listen(0) method
  3. respond when a _Connection() event occurs
  4. use the socket .Accept() method (which creates an outgoing port) and write the data to this port

The client (monitor) code just has to:-
  1. set Client socket IP and Port properties to suit bird box
  2. run the socket Connect() method
  3. respond to the sockets _Read() event

So far, so good. But the problem is that data returning from the box raises the _Read() event at the monitor some time after data was requested (i.e. its asynchronous). So I don't know which box this incoming data relates to.

The solution I'm using requires the returning data to include an ID so the monitor program knows which battery data goes with which box. The monitor program just uses a text file containing a list of IP addresses to try pinging. I can't just return the box hostname (e.g. Pi-28mm-int) because I have no way to resolve this to an IP address.

So I need code within the box software to find the local IP address. For similar situations in the past (e.g. BlissFlixx) I've used the Linux command:-

ifconfig

This involves executing "ifconfig > ifconfig.txt" via Gambas or Python and then searching the text file to find the IP address.

But now I've discovered that I can use the Linux command:-

hostname -I

...which returns all the local active IP addresses, e.g. if you have a wifi dongle and an ethernet cable connection to your Linux system, hostname -I will return both IP addresses. These will not be in a specific order, so you could not assume (say) that the first one listed was for ethernet and the second for wifi.

However, on each of my bird box systems there is only one active IP address (the wifi dongle), so using hostname is perfect for my requirements.

Dev box is just a Pi on the bench used for testing software


No comments:

Post a Comment