0

I have a Python script which retrieves the measured data from a smart plug so that I can visualize it on my Rasbperry Pi.

This command gets the data

send_hs_command("192.168.1.26", 9999, b'{"emeter":{"get_realtime":{}}}')

and this is the define

def send_hs_command(address, port, cmd):
    data = b""

    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        tcp_sock.connect((address, port))
        tcp_sock.send(encrypt(cmd))
        data = tcp_sock.recv(2048)
    except socket.error:        
        print(time.asctime( time.localtime(time.time()) ), "Socket closed.", file=sys.stderr)
    finally:
        tcp_sock.close()
    return data

My problem is that if I take the Smart Plug somewhere else, it will have a new IP-Address, which means I have to keep rewriting it on my Python script. This is not an option for me. What would be the simplest solution? Thanks

xoani
  • 107
  • 1
  • 1
  • 13
  • I guess you can get the IP addr by iface name, can't you? Maybe taking a look over this post https://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-of-eth0-in-python could help. You could even get the IP addr from the MAC addr using some net-sniffing python package like scapy. – danrodlor May 06 '19 at 10:40
  • 1
    @danlor - you are trying to solve a different problem than the one asked about. The asker needs to get the address of the smart plug, not the address of the pi. – Chris Stratton May 09 '19 at 21:47
  • @ChrisStratton, you're right, I misread the question. The iface-name method would give him the address of the pi in the given subnet, not the address of the smart plug. However, the MAC approach is still valid. – danrodlor May 10 '19 at 06:17

1 Answers1

0

I don't have a Pi to run this on.

If the IP address of the target(Smart Plug) is variable, can you not use a pre-determined host-name(located in '/etc/hostname') instead?

the socket library provides a few handy functions;

You can first use gethostbyaddr to get the host-name if you don't have the host-name information already. Then from that point onward you can use the known host-name and use create_connection to establish connections.

However, if you want to use something more dynamic; I'd suggest using the MAC address as the key. Please be advised that running scapy which perhaps depends on tcpdump on Raspberry Pi might be CPU exhaustive. Please take a look at the following snippet:

import socket
import time
import sys
from scapy.all import *


def send_hs_command(address, port, cmd):
    data = b""
    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        tcp_sock.connect((address, port))
        tcp_sock.send(encrypt(cmd))
        data = tcp_sock.recv(2048)
    except socket.error:
        print(time.asctime( time.localtime(time.time()) ), "Socket closed.", file=sys.stderr)
    finally:
        tcp_sock.close()
    print(data)
    return data


def get_ip_from_mac():
    # Match ARP requests
    packet_list = sniff(filter="arp", count=10) # increase number of arp counts
    for i in packet_list:
        # Show all ARP requests
        # print(i[Ether].src, "is broadcasting IP", i[ARP].psrc)
        if (i[ARP].hwsrc == '00:0c:29:b6:f4:be'): # target MAC address
            return (True, i[ARP].psrc)
    return (False, '')


def main():
    result = get_ip_from_mac()
    if result[0] == True:
        print("Succeeded to reach server")
        send_hs_command(result[1], 22, b'{"emeter":{"get_realtime":{}}}')
    else:
        # logic to retry or graciously fail
        print("Failed to reach server")


if __name__== "__main__":
    main()
iAmTryingOK
  • 216
  • 1
  • 10
  • Thanks a lot. I will test it and let you know. You are suggesting this cause the MAC address is always the same, right? – xoani May 06 '19 at 14:35
  • Yes, he is. If you're using Linux, you can set an udev rule to rename the iface based on the MAC of the device (or other parameters), thus you can get the IP addr by iface name as well, as I said. – danrodlor May 06 '19 at 19:00
  • Hi, I am getting this error `File "mactoip.py", line 5, in from scapy.all import * ImportError: No module named 'scapy'` – xoani May 10 '19 at 11:28
  • `pip install scapy` is your friend, also install `tcpdump` – iAmTryingOK May 11 '19 at 08:38