refactored and added automated test stuff

This commit is contained in:
Edwin Eefting
2017-10-13 01:19:35 +02:00
parent 35f82ea616
commit 3c591f146e
5 changed files with 148 additions and 38 deletions
+5 -3
View File
@@ -1,7 +1,7 @@
units=[
nodes=[
{
'type' : 'wemos d1 mini v2.2.0',
'port' : '/dev/ttyUSB0',
'port' : '/dev/serial/by-path/pci-0000:00:14.0-usb-0:3.1:1.0-port0',
'ip' : '192.168.13.91',
'flash_cmd' : 'esptool.py --port {port} -b 1500000 write_flash 0x0 .pioenvs/dev_4096/firmware.bin --flash_size=32m -p',
'build_cmd' : 'platformio run --environment dev_4096'
@@ -9,7 +9,7 @@ units=[
{
'type' : 'nodemcu geekcreit ESP12E devkit v2',
'port' : '/dev/serial/by-path/pci-0000:00:14.0-usb-0:3.4.3:1.0-port0',
'port' : '/dev/serial/by-path/pci-0000:00:14.0-usb-0:3.2:1.0-port0',
'ip' : '192.168.13.92',
'flash_cmd' : 'esptool.py --port {port} -b 1500000 write_flash 0x0 .pioenvs/dev_4096/firmware.bin --flash_size=32m -p',
'build_cmd' : 'platformio run --environment dev_4096'
@@ -17,6 +17,8 @@ units=[
]
mqtt_broker="192.168.13.236"
# TYPE2="geekcreit ESP12E devkit v2"
# SERIAL2=/dev/serial/by-path/pci-0000:00:14.0-usb-0:3.4.3:1.0-port0
# IP2=192.168.13.92
+31
View File
@@ -0,0 +1,31 @@
### High level ESPEasy config.
### Things like configging a controller or device via http
### I've created it in way that you can just copy/past form parameters from Chromium's header view
class EspEasy:
def __init__(self, node):
self._node=node
def controller_domoticz_mqtt(self, **kwargs):
self._node.http_post(
page="controllers",
params="""
index: {index}
""".format(**kwargs),
data="""
protocol:2
usedns:0
controllerip:{mqtt_broker}
controllerport:1883
controlleruser:
controllerpassword: http://urltje
controllersubscribe:domoticz/out
controllerpublish:domoticz/in
controllerenabled:on
""".format(**kwargs)
)
+33 -11
View File
@@ -4,10 +4,15 @@ import argparse
import json
import sys
import config
import esp
import node
import espeasy
import pydoc
import util
parser = argparse.ArgumentParser(description='ESPEasy testing framework', epilog=pydoc.render_doc(esp.Esp), formatter_class=argparse.RawDescriptionHelpFormatter)
def get_epilog():
return(pydoc.render_doc(node.Node) + pydoc.render_doc(espeasy.EspEasy))
parser = argparse.ArgumentParser(description='ESPEasy testing framework', epilog=get_epilog(), formatter_class=argparse.RawDescriptionHelpFormatter)
# parser.add_argument('--url', default='http://localhost:8080/rpc', help='url of rpc server to connect to. default: %(default)s')
# parser.add_argument('--user', default=None, help='user to login.')
@@ -18,21 +23,30 @@ parser = argparse.ArgumentParser(description='ESPEasy testing framework', epilog
# parser.add_argument('--short', action='store_true', help='return short single-line JSON output (for scripting)')
# parser.add_argument('--verbose', action='store_true', help='request verbose mode (module help output)')
# parser.add_argument('--insecure', action='store_true', help='dont verify SSL certificates. (use with self-signed certificates)')
parser.add_argument('command', nargs=1, help='Function from the Esp class to run (help below)')
parser.add_argument('unit', type=int,nargs=1, help='Unit number (from config)')
parser.add_argument('--debug', action='store_true', help='enable http debugging output')
parser.add_argument('module', nargs=1, help='Module to use (node or espeasy)')
parser.add_argument('node', type=int,nargs=1, help='Node number (from config)')
parser.add_argument('command', nargs=1, help='Function from the module (help below)')
parser.add_argument('params', default=[], nargs='*', help='command parameters. in foo=bar form ')
args = parser.parse_args()
try:
if args.unit[0]<1:
raise(Exception("unit number should be 1 or higher"))
if args.node[0]<1:
raise(Exception("node number should be 1 or higher"))
if args.debug:
util.enable_http_debug()
unit=args.unit[0]-1
node_index=args.node[0]-1
config.nodes[node_index]['node']=args.node[0]
#we always need a node instance
node_instance=node.Node(config.nodes[node_index])
config.units[unit]['unit']=args.unit[0]
e=esp.Esp(config.units[unit])
#determine rpc parameters
params={}
@@ -40,8 +54,16 @@ try:
(key,value)=param.split("=")
params[key]=value
command = getattr(e, args.command[0])
command(**params)
if args.module[0]=='node':
command = getattr(node_instance, args.command[0])
command(**params)
elif args.module[0]=='espeasy':
espeasy_instance=espeasy.EspEasy(node_instance)
command = getattr(espeasy_instance, args.command[0])
command(**params)
else:
raise(Exception("Unknown module:"+args.module[0]))
sys.exit(0)
+57 -24
View File
@@ -1,3 +1,6 @@
### Generic lowlevel ESP and espeasy per-node stuff.
### Used for things like flashing, serial communication, resetting, wificonfig, http communication
import serial
import sys
import time
@@ -5,16 +8,16 @@ import subprocess
import wificonfig
import requests
import serial.tools.miniterm
import re
def log(txt):
print(txt, end="", flush=True)
class Esp():
class Node():
def __init__(self, config):
print("Using unit {unit} ({type}) with ip {ip}".format(**config))
print("Using node {node} ({type}) with ip {ip}".format(**config))
self._config=config
self._url="http://{ip}/".format(**self._config)
self._serial_initialized=False
@@ -126,28 +129,58 @@ class Esp():
self.serial()
def config_device(self):
def http_post(self, page, params, data):
"""http post to espeasy webinterface"""
# transform easy copy/pastable chromium data into a dict
params_dict={}
for line in params.split("\n"):
m=re.match(" *(.*?):(.*)",line)
if (m):
params_dict[m.group(1)]=m.group(2)
data_dict={}
for line in data.split("\n"):
m=re.match(" *(.*?):(.*)",line)
if (m):
data_dict[m.group(1)]=m.group(2)
r=requests.post(
self._url+"devices",
params={
'index':1,
'page':1
},
data={
'TDNUM':1,
'TDN': "",
'TDE': 'on',
'taskdevicepin1': 12,
'plugin_001_type':1,
'plugin_001_button':0,
'TDT':0,
'TDSD1':'on',
'TDID1':1,
'TDVN1':'Switch',
'edit':1,
'page':1
}
self._url+page,
params=params_dict,
data=data_dict
)
r.raise_for_status()
#
# return(r)
#
#
# def config_device(self):
#
# r=requests.post(
# self._url+"devices",
# params={
# 'index':1,
# 'page':1
# },
# data={
# 'TDNUM':1,
# 'TDN': "",
# 'TDE': 'on',
# 'taskdevicepin1': 12,
# 'plugin_001_type':1,
# 'plugin_001_button':0,
# 'TDT':0,
# 'TDSD1':'on',
# 'TDID1':1,
# 'TDVN1':'Switch',
# 'edit':1,
# 'page':1
# }
# )
print(r.url)
# print(r.url)
+22
View File
@@ -0,0 +1,22 @@
def enable_http_debug():
import requests
import logging
# These two lines enable debugging at httplib level (requests->urllib3->http.client)
# You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# The only thing missing will be the response.body which is not logged.
try:
import http.client as http_client
except ImportError:
# Python 2
import httplib as http_client
http_client.HTTPConnection.debuglevel = 1
# You must initialize logging, otherwise you'll not see debug output.
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True