This repository has been archived by the owner on Feb 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4f6b15a
commit 2f2af05
Showing
2 changed files
with
392 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
"""Example API handler.""" | ||
|
||
|
||
import functools | ||
import json | ||
import os | ||
from time import sleep | ||
import datetime | ||
import subprocess | ||
|
||
|
||
try: | ||
from gateway_addon import APIHandler, APIResponse | ||
print("succesfully loaded APIHandler and APIResponse from gateway_addon") | ||
except: | ||
print("Import APIHandler and APIResponse from gateway_addon failed. Use at least WebThings Gateway version 0.10") | ||
|
||
print = functools.partial(print, flush=True) | ||
|
||
|
||
class PowerSettingsAPIHandler(APIHandler): | ||
"""Power settings API handler.""" | ||
|
||
def __init__(self, verbose=False): | ||
"""Initialize the object.""" | ||
print("INSIDE API HANDLER INIT") | ||
try: | ||
manifest_fname = os.path.join( | ||
os.path.dirname(__file__), | ||
'..', | ||
'manifest.json' | ||
) | ||
#self.adapter = adapter | ||
#print("ext: self.adapter = " + str(self.adapter)) | ||
|
||
with open(manifest_fname, 'rt') as f: | ||
manifest = json.load(f) | ||
|
||
APIHandler.__init__(self, manifest['id']) | ||
self.manager_proxy.add_api_handler(self) | ||
|
||
self.DEBUG = True | ||
|
||
|
||
print("self.manager_proxy = " + str(self.manager_proxy)) | ||
print("Created new API HANDLER: " + str(manifest['id'])) | ||
except Exception as e: | ||
print("Failed to init UX extension API handler: " + str(e)) | ||
|
||
|
||
|
||
def handle_request(self, request): | ||
""" | ||
Handle a new API request for this handler. | ||
request -- APIRequest object | ||
""" | ||
|
||
try: | ||
print(">>>>>> INCOMING API REQUEST <<<<<<<<<") | ||
print(">>> REQUEST.PATH = " + str(request.path)) | ||
print(">>> REQUEST.BODY = " + str(request.body)) | ||
|
||
|
||
if request.method != 'POST': | ||
return APIResponse(status=404) | ||
|
||
if request.path == '/init' or request.path == '/set-time' or request.path == '/set-ntp' or request.path == '/shutdown' or request.path == '/reboot': | ||
|
||
try: | ||
if request.path == '/init': | ||
response = {} | ||
|
||
if self.DEBUG: | ||
print("Initialising") | ||
try: | ||
now = datetime.datetime.now() | ||
current_ntp_state = True | ||
|
||
try: | ||
for line in run_command("timedatectl show").splitlines(): | ||
if self.DEBUG: | ||
print(line) | ||
if line.startswith( 'NTP=no' ): | ||
current_ntp_state = False | ||
except Exception as ex: | ||
print("Error getting NTP status: " + str(ex)) | ||
|
||
|
||
response = {'hours':now.hour,'minutes':now.minute,'ntp':current_ntp_state} | ||
if self.DEBUG: | ||
print("Init response: " + str(response)) | ||
except Exception as ex: | ||
print("Init error: " + str(ex)) | ||
|
||
return APIResponse( | ||
status=200, | ||
content_type='application/json', | ||
content=json.dumps(response), | ||
) | ||
|
||
|
||
elif request.path == '/set-time': | ||
#print(str(request.values)) | ||
#new_time_values = request.values; | ||
#print("new_time_values = " + str(new_time_values)) | ||
try: | ||
#j = json.loads(request.body) | ||
print("hours from json = " + str(request.body['hours'])) | ||
self.set_time(str(request.body['hours']),request.body['minutes']) | ||
return APIResponse( | ||
status=200, | ||
content_type='application/json', | ||
#content=json.dumps(request.body), | ||
content=json.dumps("Time set"), | ||
) | ||
except Exception as ex: | ||
print("Error setting time: " + str(ex)) | ||
return APIResponse( | ||
status=200, | ||
content_type='application/json', | ||
#content=json.dumps(request.body), | ||
content=json.dumps("Error while setting time: " + str(ex)), | ||
) | ||
|
||
|
||
|
||
|
||
elif request.path == '/set-ntp': | ||
print("New NTP state = " + str(request.body['ntp'])) | ||
self.set_ntp_state(request.body['ntp']) | ||
return APIResponse( | ||
status=200, | ||
content_type='application/json', | ||
content=json.dumps("Changed Network Time state to " + str(request.body['ntp'])), | ||
) | ||
|
||
elif request.path == '/shutdown': | ||
self.shutdown() | ||
return APIResponse( | ||
status=200, | ||
content_type='application/json', | ||
content=json.dumps("Shutting down"), | ||
) | ||
|
||
elif request.path == '/reboot': | ||
self.reboot() | ||
return APIResponse( | ||
status=200, | ||
content_type='application/json', | ||
content=json.dumps("Restarting"), | ||
) | ||
|
||
except Exception as ex: | ||
print(str(ex)) | ||
|
||
else: | ||
return APIResponse(status=404) | ||
|
||
except Exception as e: | ||
print("Failed to handle UX extension API request: " + str(e)) | ||
|
||
|
||
def set_time(self, hours, minutes, seconds=0): | ||
print("Setting the new time") | ||
|
||
if int(hours).is_integer() and int(minutes).is_integer(): | ||
|
||
|
||
the_date = str(datetime.now().strftime('%Y-%m-%d')) | ||
|
||
time_command = "sudo date --set '" + the_date + " " + str(hours) + ":" + str(minutes) + ":00'" | ||
print("new set date command: " + str(time_command)) | ||
|
||
try: | ||
os.system(time_command) | ||
except Exception as e: | ||
print("Error setting new time: " + str(e)) | ||
|
||
|
||
def set_ntp_state(self,new_state): | ||
print("Setting NTP state") | ||
try: | ||
if new_state: | ||
os.system('sudo timedatectl set-ntp on') | ||
print("Network time turned on") | ||
else: | ||
os.system('sudo timedatectl set-ntp off') | ||
print("Network time turned off") | ||
except Exception as e: | ||
print("Error changing NTP state: " + str(e)) | ||
|
||
|
||
def shutdown(self): | ||
print("Shutting down gateway") | ||
try: | ||
os.system('sleep 1s; sudo shutdown now') | ||
except Exception as e: | ||
print("Error shutting down: " + str(e)) | ||
|
||
|
||
def reboot(self): | ||
print("Rebooting gateway") | ||
try: | ||
os.system('sleep 1s; sudo reboot') | ||
except Exception as e: | ||
print("Error rebooting: " + str(e)) | ||
|
||
|
||
|
||
def unload(self): | ||
if self.DEBUG: | ||
print("Shutting down adapter") | ||
|
||
|
||
|
||
def run_command(cmd, timeout_seconds=60): | ||
try: | ||
|
||
p = subprocess.run(cmd, timeout=timeout_seconds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines=True) | ||
|
||
if p.returncode == 0: | ||
return p.stdout + '\n' + "Command success" #.decode('utf-8') | ||
#yield("Command success") | ||
else: | ||
if p.stderr: | ||
return "Error: " + str(p.stderr) + '\n' + "Command failed" #.decode('utf-8')) | ||
|
||
except Exception as e: | ||
print("Error running Arduino CLI command: " + str(e)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
"""Candle adapter for Mozilla WebThings Gateway.""" | ||
|
||
import os | ||
import sys | ||
import time | ||
#from time import sleep | ||
#from datetime import datetime, timedelta | ||
import logging | ||
import datetime | ||
import urllib | ||
import requests | ||
#import string | ||
#import urllib2 | ||
#import json | ||
#import re | ||
import subprocess | ||
#from subprocess import STDOUT, check_output | ||
#import threading | ||
#from threading import Timer | ||
#import serial #as ser | ||
#import serial.tools.list_ports as prtlst | ||
#from flask import Flask,Response, request,render_template,jsonify, url_for | ||
|
||
#import asyncio | ||
|
||
from gateway_addon import Adapter, Device, Database | ||
|
||
|
||
try: | ||
#from gateway_addon import APIHandler, APIResponse | ||
from .api_handler import * | ||
print("PowerSettingsAPIHandler imported.") | ||
except: | ||
print("Unable to load PowerSettingsAPIHandler (which is used for UX extention)") | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
_TIMEOUT = 3 | ||
|
||
__location__ = os.path.realpath( | ||
os.path.join(os.getcwd(), os.path.dirname(__file__))) | ||
|
||
_CONFIG_PATHS = [ | ||
os.path.join(os.path.expanduser('~'), '.mozilla-iot', 'config'), | ||
] | ||
|
||
if 'MOZIOT_HOME' in os.environ: | ||
_CONFIG_PATHS.insert(0, os.path.join(os.environ['MOZIOT_HOME'], 'config')) | ||
|
||
|
||
|
||
|
||
# | ||
# ADAPTER | ||
# | ||
|
||
class PowerSettingsAdapter(Adapter): | ||
"""Adapter for Power settings""" | ||
|
||
def __init__(self, verbose=True): | ||
""" | ||
Initialize the object. | ||
verbose -- whether or not to enable verbose logging | ||
""" | ||
print("initialising adapter from class") | ||
self.adding_via_timer = False | ||
self.pairing = False | ||
self.name = self.__class__.__name__ | ||
self.adapter_name = 'power-settings' | ||
Adapter.__init__(self, self.adapter_name, self.adapter_name, verbose=verbose) | ||
#print("Adapter ID = " + self.get_id()) | ||
|
||
print("paths:" + str(_CONFIG_PATHS)) | ||
|
||
self.add_on_path = os.path.join(os.path.expanduser('~'), '.mozilla-iot', 'addons', self.adapter_name) | ||
print("self.add_on_path = " + str(self.add_on_path)) | ||
|
||
self.DEBUG = True | ||
|
||
|
||
# Get the user's settings | ||
#self.add_from_config() | ||
|
||
|
||
|
||
|
||
def set_time(self, hours, minutes, seconds=0): | ||
print("Setting the new time") | ||
|
||
from datetime import datetime | ||
the_date = str(datetime.now().strftime('%Y-%m-%d')) | ||
|
||
time_command = "sudo date --set '" + the_date + " " + hours + ":" + minutes + ":" + seconds + "'" | ||
print("new set date command: " + str(time_command)) | ||
|
||
try: | ||
os.system(time_command) | ||
except Exception as e: | ||
print("Error setting new time: " + str(e)) | ||
|
||
|
||
def shutdown(self): | ||
print("Shutting down gateway") | ||
try: | ||
os.system('sudo shutdown now') | ||
except Exception as e: | ||
print("Error shutting down: " + str(e)) | ||
|
||
|
||
def reboot(self): | ||
print("Rebooting gateway") | ||
try: | ||
os.system('sudo reboot') | ||
except Exception as e: | ||
print("Error rebooting: " + str(e)) | ||
|
||
|
||
|
||
def unload(self): | ||
if self.DEBUG: | ||
print("Shutting down adapter") | ||
|
||
|
||
|
||
def run_command(cmd, timeout_seconds=60): | ||
try: | ||
|
||
p = subprocess.run(cmd, timeout=timeout_seconds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines=True) | ||
|
||
if p.returncode == 0: | ||
return p.stdout + '\n' + "Command success" #.decode('utf-8') | ||
#yield("Command success") | ||
else: | ||
if p.stderr: | ||
return "Error: " + str(p.stderr) + '\n' + "Command failed" #.decode('utf-8')) | ||
|
||
except Exception as e: | ||
print("Error running Arduino CLI command: " + str(e)) | ||
|
||
|
||
def run_command_json(cmd, timeout_seconds=60): | ||
try: | ||
|
||
result = subprocess.run(cmd, timeout=timeout_seconds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines=True) | ||
|
||
if result.returncode == 0: | ||
return result.stdout #.decode('utf-8') | ||
else: | ||
if result.stderr: | ||
return "Error: " + str(result.stderr) #.decode('utf-8')) | ||
#Style.error('Preprocess failed: ') | ||
#print(result.stderr) | ||
|
||
except Exception as e: | ||
print("Error running Arduino JSON CLI command: " + str(e)) |