Check if clients are online with ips stored in json [SOLVED] - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Check if clients are online with ips stored in json [SOLVED] (/thread-37552.html) |
Check if clients are online with ips stored in json [SOLVED] - AlphaInc - Jun-24-2022 Hello everybody, I have a script which should do something (to make an example, I let it create a folder). Therefore I defined a function which does just that: def folder(): path = os.getcwd() newPath = path+"/tmp" os.mkdir(newPath)But I only want my function to be executed when at least one of my clients are online. The ip addresses are defined in a json file: [ { "Name": "Client 1", "ip": "192.168.1.2" }, { "Name": "Client 2", "ip": "192.168.1.3" } ]Now I want to define a new function which checks all ip addresses. The question I have is, how do I get the ips from my json and ping them one after another to check if at least one of them is online and if they are execute my folder-function? This is all I have so far: def ipCheck(): f = open('clients.json') data = json.load(f) for i in data: print(i) f.close() RE: Check if clients are online with ips stored in json - ibreeden - Jun-26-2022 Hi @AlphaInc , I understand you have two problems:
You dit almost right reading the JSON file, but you missed a detail. Look at the file: it starts with "[" so it is a list. There is one comma, so the list contains two items. The items start with "{" so they are dictionaries. You want the IP-address, and you see these addresses have key "ip". So to extract these adresses you should do someting like: import json with open("clients.json") as f: data = json.load(f) for i in data: print(i["ip"])Now for the ping(). You could use pythonping, but if I understand the manual right, you need to be superuser to run a script using pythonping. I consider this to be bad practice. So you need to use the default ping on your computer. On Windows you should execute one ping with "ping /n 1 192.168.1.2". On Linux-like systems you need to use "-c" (count) instead of "/n". So you could define a function like this: from subprocess import call, DEVNULL import platform def ping(host_or_ip: str) -> bool : """ping() executes: on windows: ping /n 1 host_or_ip on Linux or Mac: ping -c 1 host_or_ip Meaning: execute one ping to host_or_ip. Returns True if host_or_ip responded, else False. """ if platform.system().lower() == "windows": countoption = "/n" else: countoption = "-c" return not call(["ping", countoption, "1", host_or_ip], stdout=DEVNULL, stderr=DEVNULL)Please show us how you use these building blocks to create your program. Let us know if you run into troubles. RE: Check if clients are online with ips stored in json - snippsat - Jun-26-2022 icmplib is cool✨ We had a Thread about this before ping program in Python. So to write a example on how it can be done,this also works as an unprivileged user. import asyncio from icmplib import async_multiping import json def read_json(): ip_lst = [] with open("clients.json") as f: data = json.load(f) # Add one to test online status ip_lst.append('python-forum.io') for ip in data: ip_lst.append(ip["ip"]) return ip_lst async def are_alive(addresses): check_ip = [] hosts = await async_multiping(addresses, privileged=False) for host in hosts: if host.is_alive: print(f'{host.address} is up!') check_ip.append('up') else: print(f'{host.address} is down!') check_ip.append('down') return check_ip if __name__ == '__main__': ips = read_json() status = asyncio.run(are_alive(ips)) if 'up' in status: print('One host is online') # Do someting else: print('No host is online')
RE: Check if clients are online with ips stored in json - AlphaInc - Jun-27-2022 (Jun-26-2022, 05:15 PM)ibreeden Wrote: Hi @AlphaInc , Okay, now I understand how to read the json file. But I still have trouble to ping the ips I wrote in my json file. This is my current code: from subprocess import call, DEVNULL import platform import json import sys import os def folder(): path = os.getcwd() newPath = path+"/tmp" os.mkdir(newPath) def ip_check(host_or_ip: str) -> bool : with open("clients.json") as f: data = json.load(f) for i in data: print(i["ip"]) if platform.system().lower() == "windows": countoption = "/n" else: countoption = "-c" return not call(["ping", countoption, "1", host_or_ip], stdout=DEVNULL, stderr=DEVNULL) ip_check(host_or_ip) #End sys.exit()After executing the script I get this error message: Traceback (most recent call last): File "/home/pi/system/debug/modules/ipCheck/v0.6.py", line 31, in <module> ip_check(host_or_ip) NameError: name 'host_or_ip' is not defined RE: Check if clients are online with ips stored in json - ibreeden - Jun-27-2022 No. You must read the ip addresses from the json file one by one, and for each address test if it responds. from subprocess import call, DEVNULL import platform import json import os def folder(): path = os.getcwd() newPath = path + "/tmp" os.mkdir(newPath) def ping(host_or_ip: str) -> bool : """ping(): execute one ping to host_or_ip. Returns True if host_or_ip responded, else False. """ if platform.system().lower() == "windows": countoption = "/n" else: countoption = "-c" return not call(["ping", countoption, "1", host_or_ip], stdout=DEVNULL, stderr=DEVNULL) responding_hosts = 0 with open("clients.json") as f: data = json.load(f) for i in data: print(f"pinging: {i['ip']}") if ping(i["ip"]): responding_hosts += 1 print(f"Number of responding hosts: {responding_hosts}") if responding_hosts > 0 : folder() RE: Check if clients are online with ips stored in json - AlphaInc - Jun-27-2022 (Jun-27-2022, 07:16 AM)ibreeden Wrote: No. You must read the ip addresses from the json file one by one, and for each address test if it responds. Okay nice, this worked great! Sorry, but I have one last question. I tried to check for two different json files (one contains a list of IPs which should be offline and one which should be online) but I'm running into some problems once again: #!/usr/bin/env python3 #Imports from subprocess import call, DEVNULL import platform import json import os #IP Configuration responding_clients1 = 0 responding_clients2 = 0 #Folder Creation def folder(): path = os.getcwd() newPath = path + "/tmp" os.mkdir(newPath) #Pinp Configuration def ping(host_or_ip: str) -> bool : if platform.system().lower() == "windows": countoption = "/n" else: countoption = "-c" return not call(["ping", countoption, "1", host_or_ip], stdout=DEVNULL, stderr=DEVNULL) #Clients1 Check with open("clients1.json") as f1: data1 = json.load(f1) for i in data1: if ping(i["ip"]): responding_clients1 += 1 #Clients2 Check with open("clients2.json") as f2: data2 = json.load(f2) for i in data2: if ping(i["ip"]): responding_clients2 += 1 #ToDo if responding_clients1 > 0 : if responding_clients2 == 0: folder() #End sys.exit()And I get this error message: Traceback (most recent call last): File "/home/pi/system/debug/ipCheck/v1.0.py", line 37, in <module> data2 = json.load(f2) File "/usr/local/lib/python3.10/json/__init__.py", line 293, in load return loads(fp.read(), File "/usr/local/lib/python3.10/json/__init__.py", line 346, in loads return _default_decoder.decode(s) File "/usr/local/lib/python3.10/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/local/lib/python3.10/json/decoder.py", line 353, in raw_decode obj, end = self.scan_once(s, idx) json.decoder.JSONDecodeError: Expecting ',' delimiter: line 9 column 3 (char 112) RE: Check if clients are online with ips stored in json - AlphaInc - Jun-27-2022 (Jun-27-2022, 08:02 AM)AlphaInc Wrote:(Jun-27-2022, 07:16 AM)ibreeden Wrote: No. You must read the ip addresses from the json file one by one, and for each address test if it responds. Nevermind, there was a missing comma in my second .json file. Thank you all for your help |