From 4192d739fd06dabfc64fd91d96cc57e4d97a3a18 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Wed, 15 Feb 2017 10:24:44 +0100 Subject: [PATCH 01/12] Shortend down on load.py and made it logically faster. --- status/load.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 status/load.py diff --git a/status/load.py b/status/load.py new file mode 100644 index 0000000..4f642d2 --- /dev/null +++ b/status/load.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +from subprocess import check_output +from re import findall +from platform import system + +def load(): + sysName = system() + if sysName == 'Linux': + arpOutput = check_output("cat /proc/loadavg", shell=True) + elif sysName == 'Darwin': + arpOutput = check_output("uptime", shell=True) + else: + return {"Error": "Running OS does not supported load."} + + arpOutput = arpOutput.decode() + return findall('[0-9]{1,2}[\.][0-9]{2}', arpOutput) + + +if __name__ == '__main__': + print(load()) From 4eb949c6617586ef767635d93bd190944466f4f1 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Wed, 15 Feb 2017 12:20:18 +0100 Subject: [PATCH 02/12] Removed depricated cpu temp script --- status/linuxcpureader.py | 48 ---------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 status/linuxcpureader.py diff --git a/status/linuxcpureader.py b/status/linuxcpureader.py deleted file mode 100644 index 72943c4..0000000 --- a/status/linuxcpureader.py +++ /dev/null @@ -1,48 +0,0 @@ - -from functools import partial -from os import path - - -class LinuxCpuTemperatureReader(): - files = [ - '/sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/thermal_zone/temp', - '/sys/bus/acpi/devices/LNXTHERM:00/thermal_zone/temp', - '/proc/acpi/thermal_zone/THM0/temperature', - '/proc/acpi/thermal_zone/THRM/temperature', - '/proc/acpi/thermal_zone/THR1/temperature' - ] - - @classmethod - def get_reader(cls): - readers = { - cls.files[0]: cls.reader1, - cls.files[1]: cls.reader1, - cls.files[2]: cls.reader2, - cls.files[3]: cls.reader2, - cls.files[4]: cls.reader2 - } - for file in cls.files: - if path.exists(file): - reader = readers.get(file) - if reader: - print(reader(file)) - return reader(file) - - @classmethod - def reader1(cls, file): - def reader(file): - temperature = open(file).read().strip() - temperature = int(temperature) // 1000 - return temperature - return partial(reader, file) - - @classmethod - def reader2(cls, file): - def reader(file): - temperature = open(file).read().strip() - temperature = temperature.lstrip('temperature :').rstrip(' C') - return int(temperature) - return partial(reader, file) - - -__all__ = ['LinuxCpuTemperatureReader'] From 2b3db61253b6bd29000bc9fbeb744321bce7e30f Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Wed, 15 Feb 2017 22:55:54 +0100 Subject: [PATCH 03/12] Made changes to cpuTemp to make sure cpu temp reads are do be done only if machine is linux and also added return of both max and min temps alongside avg. --- status/cpuTemp.py | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/status/cpuTemp.py b/status/cpuTemp.py index d2fcb82..fb1df05 100755 --- a/status/cpuTemp.py +++ b/status/cpuTemp.py @@ -1,16 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import psutil +from platform import system def getCpuTemp(): - # Check if sensors_temperatures exists - try: - # Define cpu as function of sensors_temperatures - cpu = psutil.sensors_temperatures() - except AttributeError: - error = "'sensors_temperatures' is not supported in this verison of psutil or your OS." - print(error) - return None + sysName = system() + if sysName != 'Linux': + return {"Error": "Running OS does not support cpu temp reads."} + + # Define cpu as function of sensors_temperatures + cpu = psutil.sensors_temperatures() # Array for temps for each core. curCpuTemps = [] @@ -19,17 +18,10 @@ def getCpuTemp(): curCpuTemps.append(temp[1]) # Append to list print(temp[0]+': '+str(temp[1])) # Print output - # Check if len of curCpuTemps is something so not to - # calculate on a empty list - if len(curCpuTemps) > 0: - # Compute avg of curCpuTemps - avgCpuTemps = sum(curCpuTemps)/len(curCpuTemps) - return avgCpuTemps - print("Avg: " + str(avgCpuTemps)) - else: - print("Couldn't get cpu temp. (division by zero)") - return None - + avgCpuTemps = sum(curCpuTemps)/len(curCpuTemps) + return {"Avg cpu temp": avgCpuTemps, "Max cpu temp": max(curCpuTemps), + "Min cpu temp": min(curCpuTemps)} + if __name__ == "__main__": print(getCpuTemp()) \ No newline at end of file From 57869e2d66b94922c37379d3d2bda63bd1c1c8ce Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:39:44 +0100 Subject: [PATCH 04/12] Added better header items --- status/cpuTemp.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/status/cpuTemp.py b/status/cpuTemp.py index fb1df05..8c75829 100755 --- a/status/cpuTemp.py +++ b/status/cpuTemp.py @@ -1,8 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# @Author: KevinMidboe +# @Date: 2017-02-15 23:37:36 +# @Last Modified by: KevinMidboe +# @Last Modified time: 2017-02-15 23:49:18 + import psutil from platform import system +# TODO: Add cpu reading for macOS + def getCpuTemp(): sysName = system() if sysName != 'Linux': From 53fe6d3ba3b1762cd43ca795bd32582b02993c44 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:40:23 +0100 Subject: [PATCH 05/12] Better error handling and dir setting --- status/diskusage.py | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/status/diskusage.py b/status/diskusage.py index b790b63..b27fe02 100755 --- a/status/diskusage.py +++ b/status/diskusage.py @@ -3,15 +3,17 @@ # @Author: KevinMidboe # @Date: 2017-01-28 10:54:06 # @Last Modified by: KevinMidboe -# @Last Modified time: 2017-01-31 22:29:43 +# @Last Modified time: 2017-02-18 11:39:00 # f_avail = free blocks avail to non sudo # frsize = fundamental file sys byte size # f_blocks = total number of blocks in the filesystem -from os import statvfs +from os import statvfs, path from re import sub +# TODO: Add multiple dirs. + def sizeof(num, suffix='B'): for unit in ['','K','M','G','T','P','E','Z']: if abs(num) < 1024.0: @@ -20,24 +22,18 @@ def sizeof(num, suffix='B'): return "%.1f%s%s" % (num, 'Y', suffix) # diskUsage uses statvfs to calculate disk size and availability for given disk -def diskUsage(optionalPath=None): - path = '/' - if optionalPath != None: - path += sub('\+', '/', optionalPath) +def diskUsage(rootPath=None): + if rootPath == None: rootPath = '/' + + if not path.isdir(rootPath): + return {"Error": "Directory does not exist."} - try: - s = statvfs(path) - byteLeft = s.f_bavail * s.f_frsize - byteTotal = s.f_blocks * s.f_frsize - byteUsed = byteTotal-byteLeft - - return { 'left':sizeof(byteLeft), 'used':sizeof(byteUsed), 'total':sizeof(byteTotal) } - - except FileNotFoundError: - return None - except TypeError: - return None + s = statvfs(rootPath) + byteLeft = s.f_bavail * s.f_frsize + byteTotal = s.f_blocks * s.f_frsize + byteUsed = byteTotal-byteLeft + print(byteLeft, byteTotal, byteUsed) + return { 'left': sizeof(byteLeft), 'used': sizeof(byteUsed), 'total': sizeof(byteTotal) } if __name__=="__main__": - n = diskUsage('/media/hdd1') - print(n) + print(diskUsage()) From edda38b3ef9c79ad9bc8af243707521c8f37557e Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:41:00 +0100 Subject: [PATCH 06/12] Changed print statement and error return statement --- status/diskusage.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/status/diskusage.py b/status/diskusage.py index b27fe02..2c219d7 100755 --- a/status/diskusage.py +++ b/status/diskusage.py @@ -3,7 +3,7 @@ # @Author: KevinMidboe # @Date: 2017-01-28 10:54:06 # @Last Modified by: KevinMidboe -# @Last Modified time: 2017-02-18 11:39:00 +# @Last Modified time: 2017-02-18 11:40:34 # f_avail = free blocks avail to non sudo # frsize = fundamental file sys byte size @@ -26,13 +26,12 @@ def diskUsage(rootPath=None): if rootPath == None: rootPath = '/' if not path.isdir(rootPath): - return {"Error": "Directory does not exist."} + return {"errors": "Directory does not exist."} s = statvfs(rootPath) byteLeft = s.f_bavail * s.f_frsize byteTotal = s.f_blocks * s.f_frsize byteUsed = byteTotal-byteLeft - print(byteLeft, byteTotal, byteUsed) return { 'left': sizeof(byteLeft), 'used': sizeof(byteUsed), 'total': sizeof(byteTotal) } if __name__=="__main__": From d073a1f1508377ba3c741800b19828f96884b751 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:44:04 +0100 Subject: [PATCH 07/12] Better error messages --- status/load.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) mode change 100644 => 100755 status/load.py diff --git a/status/load.py b/status/load.py old mode 100644 new mode 100755 index 4f642d2..55e23f9 --- a/status/load.py +++ b/status/load.py @@ -1,20 +1,25 @@ #!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# @Author: KevinMidboe +# @Date: 2017-02-15 23:45:16 +# @Last Modified by: KevinMidboe +# @Last Modified time: 2017-02-18 11:42:42 + from subprocess import check_output from re import findall from platform import system def load(): - sysName = system() + sysName = system() # Get system name if sysName == 'Linux': arpOutput = check_output("cat /proc/loadavg", shell=True) - elif sysName == 'Darwin': + elif sysName == 'Darwin': # macOS arpOutput = check_output("uptime", shell=True) else: - return {"Error": "Running OS does not supported load."} + return {"errors": "Running OS does not supported load."} arpOutput = arpOutput.decode() - return findall('[0-9]{1,2}[\.][0-9]{2}', arpOutput) - + return {"loads": findall('[0-9]{1,2}[\.][0-9]{2}', arpOutput)} if __name__ == '__main__': print(load()) From b87bc549bf3657ca72e2c829bf2295454db5d0bd Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:49:48 +0100 Subject: [PATCH 08/12] Added more error detection, but need moar --- status/uptime.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/status/uptime.py b/status/uptime.py index 5ab8e3e..c277e5d 100755 --- a/status/uptime.py +++ b/status/uptime.py @@ -3,7 +3,7 @@ # @Author: KevinMidboe # @Date: 2017-01-27 19:48:42 # @Last Modified by: KevinMidboe -# @Last Modified time: 2017-02-03 12:33:51 +# @Last Modified time: 2017-02-18 11:49:30 # TODO add better error handling to return statements @@ -14,8 +14,7 @@ def secToDay(seconds): days = int(seconds/86400) if days is 1: return str(days)+' day' - else: - return str(days)+' days' + return str(days)+' days' def secToHour(seconds): hours = (seconds)//3600 @@ -28,16 +27,15 @@ def timeSinceBoot(): currTime = time() # Use 'time()' to get seconds currently deltaSeconds = int(currTime-bootTime) - # Return in day format - if deltaSeconds >= 86400: - return secToDay(deltaSeconds) + if deltaSeconds >= 86400: # Return in day format + uptime = secToDay(deltaSeconds) - # Return in hour format elif deltaSeconds < 86400 and deltaSeconds >= 0: - return secToHour(deltaSeconds) + uptime = secToHour(deltaSeconds) else: - # TODO Throw error - return None + return {"errors": "Uptime not found"} + + return {"uptime": uptime} if __name__=="__main__": print(timeSinceBoot()) \ No newline at end of file From 659f306907f632ec5d1f2f499b3e9705bb1187ac Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:51:15 +0100 Subject: [PATCH 09/12] Changed how much logic is in app.py --- app.py | 51 +++++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/app.py b/app.py index 5bbd367..822d509 100755 --- a/app.py +++ b/app.py @@ -12,10 +12,11 @@ from werkzeug.security import generate_password_hash, \ from status.diskusage import diskUsage from status.uptime import timeSinceBoot +from status.load import load from status.cpuTemp import getCpuTemp -from plex.tmdb import tmdbSearch -from plex.plexMovies import getSpecificMovieInfo +from plex.tmdb import tmdbSearch +from plex.plexSearch import plexSearch app = Flask(__name__, static_url_path = "") auth = HTTPBasicAuth() @@ -67,32 +68,24 @@ def bad_request(error): # --- Apollo Activity --- # +@app.route('/api/v1/load', methods=['GET']) +def get_load(): + return jsonify(load()) + @app.route('/api/v1/disks', methods=['GET']) -@auth.login_required def get_diskUsage(): - returningDiskUsage = diskUsage(request.args.get('dir')) - if returningDiskUsage != None: - return jsonify(returningDiskUsage) - else: - abort(404) + return jsonify(diskUsage(request.args.get('dir'))) @app.route('/api/v1/uptimes', methods=['GET']) -@auth.login_required def get_uptimes(): - try: - return jsonify({ 'uptime': timeSinceBoot() }) - except: - abort(404) + return jsonify({ 'uptime': timeSinceBoot() }) @app.route('/api/v1/temps', methods=['GET']) def get_temps(): - cpuTemp = getCpuTemp() - if cpuTemp != None: - return jsonify( {"Avg cpu temp": cpuTemp} ) - else: - return jsonify( {"Error":"Temp reading not supported for host machine."} ) + return jsonify(getCpuTemp()) + # TODO PLEX # Search, watching, +photo @@ -106,12 +99,12 @@ def get_movieRequest(): else: return jsonify({ "Error": "Query not defined." }) @app.route('/api/v1/plex/movies', methods=['GET']) -@auth.login_required def getPlexMovies(): title = request.args.get('title') - movieInfo = getSpecificMovieInfo(title) + movieInfo = plexSearch(title) if movieInfo != None: + print(movieInfo) return jsonify(movieInfo) abort(500) @@ -127,24 +120,6 @@ def getPlexWatchings(): return jsonify(movieInfo) -@app.route('/api/v1/uptimes/duration', methods=['GET']) -@auth.login_required -def get_uptimesDuration(): - up = uptime.uptime() - return jsonify( {'Duration': up.duration} ) - -@app.route('/api/v1/uptimes/users', methods=['GET']) -@auth.login_required -def get_uptimesUsers(): - up = uptime.uptime() - return jsonify( {'Users': up.users} ) - -@app.route('/api/v1/uptimes/load', methods=['GET']) -@auth.login_required -def get_uptimesLoad(): - up = uptime.uptime() - return jsonify( {'Load': up.load} ) - if __name__ == '__main__': app.run(host="0.0.0.0",port=63590, debug=True) From 98eb2fff1de45184b4db1cc8b11df5c14f44fa90 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 18 Feb 2017 11:52:59 +0100 Subject: [PATCH 10/12] Changed from the plex scripts doing the comparisson to letting the client or another seperate script to it. --- app.py | 8 ++--- plex/plexSearch.py | 31 ++++++++++++------ plex/tmdb.py | 79 +++++++++++++++------------------------------- 3 files changed, 51 insertions(+), 67 deletions(-) diff --git a/app.py b/app.py index 822d509..32f60a5 100755 --- a/app.py +++ b/app.py @@ -52,7 +52,7 @@ def get_pw(username): # to not match. @auth.error_handler def unauthorized(): - return make_response(jsonify({'error': 'Unauthorized access'}), 401) + return make_response(jsonify({'errors': 'Unauthorized access'}), 401) # This would be replaced with a database, but single process and thread # can use local data like this for simplicity. @@ -61,10 +61,10 @@ def unauthorized(): # Want all return data to be JSON so create custom error response @app.errorhandler(404) def not_found(error): - return make_response(jsonify({'error': 'Not found'}), 404) + return make_response(jsonify({'errors': 'Not found'}), 404) @app.errorhandler(400) def bad_request(error): - return make_response(jsonify({'error': 'Bad request'}), 400) + return make_response(jsonify({'errors': 'Bad request'}), 400) # --- Apollo Activity --- # @@ -96,7 +96,7 @@ def get_movieRequest(): # TODO if list is empty return jsonify(tmdbSearch(query)) - else: return jsonify({ "Error": "Query not defined." }) + else: return jsonify({ "errors": "Query not defined." }) @app.route('/api/v1/plex/movies', methods=['GET']) def getPlexMovies(): diff --git a/plex/plexSearch.py b/plex/plexSearch.py index 3ff407f..8d15fcf 100755 --- a/plex/plexSearch.py +++ b/plex/plexSearch.py @@ -3,9 +3,10 @@ # @Author: KevinMidboe # @Date: 2017-02-08 14:00:04 # @Last Modified by: KevinMidboe -# @Last Modified time: 2017-02-10 01:31:43 +# @Last Modified time: 2017-02-18 11:37:08 -from requests import get +import requests +from pprint import pprint plexBaseURL = "http://10.0.0.41:32400/" @@ -42,21 +43,36 @@ def getShowInfo(item): return {"title":title, "year":year, "seasons":seasons, "episodes":episodes, "rating":rating, "art":art, "thumb":thumb} + + +def plexSearch(query): + payload = {"query":query, "type":"1,2"} + header = {'Accept': 'application/json'} + r = requests.get(plexBaseURL+"search",params=payload, headers=header) + + rObject = r.json()["MediaContainer"] + if (r.status_code != requests.codes.ok or rObject["size"] == 0): + return {"errors": "Nothing found for query: " + query} + + return rObject["Metadata"] + + ## MAJOR TODO # Seems to be a change in the return obj. # This looks way more like json. Need to re-write all this. # IDEA: Send the size and resolution for comaprison # No this is for a admin page. OR maybe a github project for # people wanting to update movies. MAJOR IDEA HERE NOW! :D -def plexSearch(query): +def plexXMLSearch(query): + print(query) requestType = "search?" requestQuery = "query=" + str(query) header = {'Accept': 'application/json'} url = plexBaseURL + requestType + requestQuery - response = get(url, headers=header) - print(response.json()) + response = requests.get(url, headers=header) + pprint(response.json()) if response.status_code == 200: resContent = response.json() media = [] @@ -74,7 +90,4 @@ def plexSearch(query): if __name__ == "__main__": # print(plexSearch("star+wars")) - tiss = plexSearch("star+wars") - for al in tiss: - if (al['year']==2015): - print('thishsihis') \ No newline at end of file + pprint(plexSearch("star")) diff --git a/plex/tmdb.py b/plex/tmdb.py index 0ce0db2..e0ba33d 100755 --- a/plex/tmdb.py +++ b/plex/tmdb.py @@ -3,77 +3,48 @@ # @Author: KevinMidboe # @Date: 2017-02-08 14:00:04 # @Last Modified by: KevinMidboe -# @Last Modified time: 2017-02-08 23:19:53 +# @Last Modified time: 2017-02-16 17:08:08 -from requests import get +import requests +from pprint import pprint try: from plexSearch import plexSearch except ImportError: from plex.plexSearch import plexSearch -tmdbBaseURL = "https://api.themoviedb.org/3/" - -def checkPlexExistance(tmdb, plex): - # THIS IS ONLY COMPARED ON YEAR - yearList = [movie["year"] for movie in plex] - print(yearList) - - for movie in tmdb["movies"]: - print(movie["year"]) - movie["exists"] = movie["year"] in str(yearList) - - return tmdb - -def createTMDBResultList(resContent): - movies = [] - tvshows = [] - - for res in resContent["results"]: - if res["media_type"] == "movie": - id = res["id"] - title = res["original_title"] - year = res["release_date"][:4] - poster_path = res["poster_path"] - - movies.append({"id": id, "title": title, "year": year, "poster_path": poster_path}) - - elif res["media_type"] == "tv": - id = res["id"] - name = res["original_name"] - year = res["first_air_date"][:4] - poster_path = res["poster_path"] - - tvshows.append({"id": id, "title": name, "year": year, "poster_path": poster_path}) - - return { "movies": movies, "tvshows": tvshows } +apiKey = "9fa154f5355c37a1b9b57ac06e7d6712" def tmdbSearch(query, page=1): - requestType = "search/multi?" - requestAPI = "api_key=" + "9fa154f5355c37a1b9b57ac06e7d6712" - requestQuery = "&query=" + str(query) - requestLanguage = "&language=en.US" - requestPage = "&page="+str(page) + payload = {"api_key":apiKey, "query":str(query), "language":"en.US", "page":str(page), } + header = {'Accept': 'application/json'} - url = tmdbBaseURL + requestType + requestAPI + requestQuery + requestLanguage + requestPage - print(url) + try: + r = requests.get("https://api.themoviedb.org/3/search/multi", params=payload, headers=header) + except requests.exceptions.ConnectionError: + return {"errors": "Could not connecting to: tmdb.com"} + except requests.exceptions.Timeout: + return {"errors": "Request timed out."} + except requests.exceptions.TooManyRedirects: + return {"errors": "Too many redirects, do you full network access?"} - response = get(url) - if response.status_code == 200: - resContent = response.json() + if r.status_code == 401: + return {"errors": "api key is not valid."} + elif r.status_code == 404: + return {"errors": "Please check url. (404)"} + elif r.status_code == requests.codes.ok and r.json()['total_results'] == 0: + return {"errors": "No results found."} + - plexSearchRes = plexSearch(query) - tmdbSearchRes = createTMDBResultList(resContent) - - return checkPlexExistance(tmdbSearchRes, plexSearchRes) + return r.json() if __name__ == "__main__": import sys print(sys.argv) if len(sys.argv) > 2: - print(tmdbSearch(sys.argv[1], int(sys.argv[2]))) + pprint(tmdbSearch(sys.argv[1], int(sys.argv[2]))) elif len(sys.argv) > 1: - print(tmdbSearch(sys.argv[1])) + pprint(tmdbSearch(sys.argv[1])) else: - print(tmdbSearch("star+wars",1)) \ No newline at end of file + pprint(tmdbSearch("star+wars",1)) \ No newline at end of file From 5aaa6dfe2f46386d636e3d7a6113779701502f0c Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 5 Mar 2017 00:31:59 +0100 Subject: [PATCH 11/12] Added empty readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..380323d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Node-Com-Handler +Internal API for getting status on all connected nodes on network + From 2d8f0f813f9348211ced71cddf9448a3ad664878 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 5 Mar 2017 00:34:14 +0100 Subject: [PATCH 12/12] Added few subsections to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 380323d..245be4a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # Node-Com-Handler Internal API for getting status on all connected nodes on network +## Setup + +## Other things to do when you fill in this document