Restructured testsuite. Added mainlight testcases. 3 failing.
This commit is contained in:
parent
f61b8ca92a
commit
ade031409a
@ -1,5 +1,6 @@
|
|||||||
from simulation.devices import tradfri_light
|
from simulation.devices import tradfri_light
|
||||||
|
|
||||||
|
from simulation.devices import silvercrest_powerplug
|
||||||
from simulation.devices import shelly as shelly_sw1
|
from simulation.devices import shelly as shelly_sw1
|
||||||
from simulation.devices import brennenstuhl_heatingvalve
|
from simulation.devices import brennenstuhl_heatingvalve
|
||||||
|
|
||||||
@ -29,7 +30,6 @@ shelly_pro3 = None
|
|||||||
tradfri_button = None
|
tradfri_button = None
|
||||||
hue_sw_br_ct = None
|
hue_sw_br_ct = None
|
||||||
silvercrest_button = None
|
silvercrest_button = None
|
||||||
silvercrest_powerplug = None
|
|
||||||
silvercrest_motion_sensor = None
|
silvercrest_motion_sensor = None
|
||||||
audio_status = None
|
audio_status = None
|
||||||
remote = None
|
remote = None
|
||||||
|
2
report
2
report
@ -1 +1 @@
|
|||||||
Subproject commit e2392c9f28d88ee54463681850acf95ae496c9a0
|
Subproject commit 152690007a3b87ee0047bcad78b2673111ff1928
|
@ -49,11 +49,6 @@ class gfw_floor(base):
|
|||||||
self.main_light_zigbee = pd.get(props.STG_ZGW, loc, roo, props.FUN_MAL) # , True, True, True, False
|
self.main_light_zigbee = pd.get(props.STG_ZGW, loc, roo, props.FUN_MAL) # , True, True, True, False
|
||||||
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee.power_on)
|
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee.power_on)
|
||||||
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee.power_off)
|
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee.power_off)
|
||||||
# TODO: Ist "self.main_light_zigbee" schon eine Gruppe???
|
|
||||||
# self.main_light_zigbee_2 = tradfri_light(mqtt_client, config.TOPIC_GFW_FLOOR_MAIN_LIGHT_ZIGBEE % 2, True, True, True, False)
|
|
||||||
# self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee_2.power_on)
|
|
||||||
# self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee_2.power_off)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_GFW_FLOOR_MAIN_LIGHT_VIDEV, True, True, True)
|
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_GFW_FLOOR_MAIN_LIGHT_VIDEV, True, True, True)
|
||||||
|
|
||||||
@ -176,12 +171,25 @@ class ffw_bath(base):
|
|||||||
self.videv_heating = videv_heating(mqtt_client, config.TOPIC_FFW_BATH_HEATING_VALVE_VIDEV)
|
self.videv_heating = videv_heating(mqtt_client, config.TOPIC_FFW_BATH_HEATING_VALVE_VIDEV)
|
||||||
|
|
||||||
|
|
||||||
|
class ffw_floor(base):
|
||||||
|
def __init__(self, mqtt_client, pd):
|
||||||
|
loc = props.LOC_FFW
|
||||||
|
roo = props.ROO_FLO
|
||||||
|
#
|
||||||
|
self.main_light = pd.get(props.STG_SHE, loc, roo, props.FUN_MAL)
|
||||||
|
self.main_light.configure(input_0_func=self.main_light.INPUT_FUNC_OUT1_TRIGGER)
|
||||||
|
self.main_light.add_channel_name(self.main_light.KEY_OUTPUT_0, "Main Light")
|
||||||
|
#
|
||||||
|
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFW_SLEEP_MAIN_LIGHT_VIDEV, True, False, False)
|
||||||
|
|
||||||
|
|
||||||
class ffw(base):
|
class ffw(base):
|
||||||
def __init__(self, mqtt_client, pd):
|
def __init__(self, mqtt_client, pd):
|
||||||
self.julian = ffw_julian(mqtt_client, pd)
|
self.julian = ffw_julian(mqtt_client, pd)
|
||||||
self.livingroom = ffw_livingroom(mqtt_client, pd)
|
self.livingroom = ffw_livingroom(mqtt_client, pd)
|
||||||
self.sleep = ffw_sleep(mqtt_client, pd)
|
self.sleep = ffw_sleep(mqtt_client, pd)
|
||||||
self.bath = ffw_bath(mqtt_client, pd)
|
self.bath = ffw_bath(mqtt_client, pd)
|
||||||
|
self.floor = ffw_floor(mqtt_client, pd)
|
||||||
|
|
||||||
|
|
||||||
class ffe_floor(base):
|
class ffe_floor(base):
|
||||||
@ -224,19 +232,18 @@ class ffe_diningroom(base):
|
|||||||
self.main_light.configure(input_0_func=self.main_light.INPUT_FUNC_OUT1_TRIGGER)
|
self.main_light.configure(input_0_func=self.main_light.INPUT_FUNC_OUT1_TRIGGER)
|
||||||
self.main_light.add_channel_name(self.main_light.KEY_OUTPUT_0, "Main Light")
|
self.main_light.add_channel_name(self.main_light.KEY_OUTPUT_0, "Main Light")
|
||||||
|
|
||||||
# TODO: Add this again...
|
self.floor_lamp = pd.get(props.STG_ZFE, loc, roo, props.FUN_FLL)
|
||||||
# self.floor_lamp = silvercrest_powerplug(mqtt_client, config.TOPIC_FFE_DININGROOM_FLOOR_LAMP_POWERPLUG)
|
self.floor_lamp.add_channel_name(self.floor_lamp.KEY_OUTPUT_0, "Floor Lamp")
|
||||||
# self.floor_lamp.add_channel_name(self.floor_lamp.KEY_OUTPUT_0, "Floor Lamp")
|
|
||||||
|
|
||||||
# if config.CHRISTMAS:
|
if config.CHRISTMAS:
|
||||||
# self.garland = silvercrest_powerplug(mqtt_client, config.TOPIC_FFE_DININGROOM_GARLAND_POWERPLUG)
|
self.garland = pd.get(props.STG_ZFE, loc, roo, props.FUN_GAR)
|
||||||
# self.garland.add_channel_name(self.garland, "Garland")
|
self.garland.add_channel_name(self.garland.KEY_OUTPUT_0, "Garland")
|
||||||
|
|
||||||
#
|
#
|
||||||
# self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFE_DININGROOM_MAIN_LIGHT_VIDEV, True, False, False)
|
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFE_DININGROOM_MAIN_LIGHT_VIDEV, True, False, False)
|
||||||
# self.videv_floor_lamp = videv_light(mqtt_client, config.TOPIC_FFE_DININGROOM_FLOOR_LAMP_VIDEV, True, False, False)
|
self.videv_floor_lamp = videv_light(mqtt_client, config.TOPIC_FFE_DININGROOM_FLOOR_LAMP_VIDEV, True, False, False)
|
||||||
# if config.CHRISTMAS:
|
if config.CHRISTMAS:
|
||||||
# self.videv_garland = videv_light(mqtt_client, config.TOPIC_FFE_DININGROOM_GARLAND_VIDEV, True, False, False)
|
self.videv_garland = videv_light(mqtt_client, config.TOPIC_FFE_DININGROOM_GARLAND_VIDEV, True, False, False)
|
||||||
|
|
||||||
|
|
||||||
class ffe_sleep(base):
|
class ffe_sleep(base):
|
||||||
@ -251,18 +258,17 @@ class ffe_sleep(base):
|
|||||||
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee.power_on)
|
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee.power_on)
|
||||||
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee.power_off)
|
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee.power_off)
|
||||||
|
|
||||||
# TODO: Add this again...
|
self.bed_light_di_zigbee = pd.get(props.STG_ZFE, loc, roo, props.FUN_BLD)
|
||||||
# self.bed_light_di_zigbee = tradfri_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_ZIGBEE, True, True, False)
|
self.bed_light_ma = pd.get(props.STG_ZFE, loc, roo, props.FUN_BLM)
|
||||||
# self.bed_light_ma = silvercrest_powerplug(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_MA_POWERPLUG)
|
self.bed_light_ma.add_channel_name(self.bed_light_ma.KEY_OUTPUT_0, "Bed light Marion")
|
||||||
|
|
||||||
self.heating_valve = pd.get(props.STG_ZFE, loc, roo, props.FUN_HEA)
|
self.heating_valve = pd.get(props.STG_ZFE, loc, roo, props.FUN_HEA)
|
||||||
|
|
||||||
#
|
#
|
||||||
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_VIDEV, True, True, True)
|
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_MAIN_LIGHT_VIDEV, True, True, True)
|
||||||
# TODO: Add this again...
|
|
||||||
# self.videv_bed_light_ma = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_MA_VIDEV, True, False, False)
|
self.videv_bed_light_ma = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_MA_VIDEV, True, False, False)
|
||||||
# self.videv_bed_light_di = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_VIDEV, True, True, False)
|
self.videv_bed_light_di = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_DI_VIDEV, True, True, False)
|
||||||
# self.videv_bed_light_ma = videv_light(mqtt_client, config.TOPIC_FFE_SLEEP_BED_LIGHT_MA_VIDEV, True, False, False)
|
|
||||||
|
|
||||||
self.videv_heating = videv_heating(mqtt_client, config.TOPIC_FFE_SLEEP_HEATING_VALVE_VIDEV)
|
self.videv_heating = videv_heating(mqtt_client, config.TOPIC_FFE_SLEEP_HEATING_VALVE_VIDEV)
|
||||||
|
|
||||||
@ -279,22 +285,19 @@ class ffe_livingroom(base):
|
|||||||
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee.power_on)
|
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, True, self.main_light_zigbee.power_on)
|
||||||
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee.power_off)
|
self.main_light.add_callback(self.main_light.KEY_OUTPUT_0, False, self.main_light_zigbee.power_off)
|
||||||
|
|
||||||
# TODO: Add this again...
|
self.floor_lamp_zigbee = pd.get(props.STG_ZFE, loc, roo, props.FUN_FLL)
|
||||||
# for i in range(1, 7):
|
|
||||||
# setattr(self, "floor_lamp_zigbee_%d" % i, tradfri_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_FLOOR_LAMP_ZIGBEE % i, True, True, True))
|
|
||||||
|
|
||||||
# if config.CHRISTMAS:
|
if config.CHRISTMAS:
|
||||||
# self.xmas_tree = silvercrest_powerplug(mqtt_client, config.TOPIC_FFE_LIVINGROOM_XMAS_TREE_POWERPLUG)
|
self.xmas_tree = pd.get(props.STG_ZFE, loc, roo, props.FUN_XTR)
|
||||||
# self.xmas_tree.add_channel_name(self.xmas_tree, "Xmas-Tree")
|
self.xmas_tree.add_channel_name(self.xmas_tree.KEY_OUTPUT_0, "Xmas-Tree")
|
||||||
# self.xmas_star = silvercrest_powerplug(mqtt_client, config.TOPIC_FFE_LIVINGROOM_XMAS_STAR_POWERPLUG)
|
self.xmas_star = pd.get(props.STG_ZFE, loc, roo, props.FUN_XST)
|
||||||
# self.xmas_star.add_channel_name(self.xmas_star, "Xmas-Star")
|
self.xmas_star.add_channel_name(self.xmas_star.KEY_OUTPUT_0, "Xmas-Star")
|
||||||
|
|
||||||
#
|
#
|
||||||
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_MAIN_LIGHT_VIDEV, True, True, True)
|
self.videv_main_light = videv_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_MAIN_LIGHT_VIDEV, True, True, True)
|
||||||
# TODO: Add this again...
|
self.videv_floor_lamp = videv_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_FLOOR_LAMP_VIDEV, True, True, True)
|
||||||
# self.videv_floor_lamp = videv_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_FLOOR_LAMP_VIDEV, True, True, True)
|
if config.CHRISTMAS:
|
||||||
# if config.CHRISTMAS:
|
self.videv_xmas_tree = videv_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_XMAS_TREE_VIDEV)
|
||||||
# self.videv_xmas_tree = videv_light(mqtt_client, config.TOPIC_FFE_LIVINGROOM_XMAS_TREE_VIDEV)
|
|
||||||
|
|
||||||
|
|
||||||
class ffe(base):
|
class ffe(base):
|
||||||
@ -325,5 +328,4 @@ class house(base):
|
|||||||
self.ffw = ffw(mqtt_client, pd)
|
self.ffw = ffw(mqtt_client, pd)
|
||||||
self.ffe = ffe(mqtt_client, pd)
|
self.ffe = ffe(mqtt_client, pd)
|
||||||
self.stairway = stairway(mqtt_client, pd)
|
self.stairway = stairway(mqtt_client, pd)
|
||||||
# TODO: Add this again...
|
self.warnings = videv_warnings(mqtt_client, config.TOPIC_WARNINGS)
|
||||||
# self.warnings = videv_warnings(mqtt_client, pd, config.TOPIC_WARNINGS)
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
import argparse
|
||||||
import config
|
import config
|
||||||
import devdi.devices
|
import devdi.devices
|
||||||
import mqtt
|
import mqtt
|
||||||
import readline
|
|
||||||
from simulation.rooms import house
|
from simulation.rooms import house
|
||||||
import sys
|
import report
|
||||||
from tests.all import test_smarthome
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
import tests.help
|
||||||
|
|
||||||
|
|
||||||
# TODO: Reimplement existing test
|
# TODO: Reimplement existing test
|
||||||
# TODO: Extend tests in simulation
|
# TODO: Extend tests in simulation
|
||||||
@ -16,95 +20,47 @@ from tests.all import test_smarthome
|
|||||||
# - Heating functionality (extended: mode switch off by other function, timer)
|
# - Heating functionality (extended: mode switch off by other function, timer)
|
||||||
# - Circulation pump (Extend Timer)
|
# - Circulation pump (Extend Timer)
|
||||||
# - Stairways (Extend Motion sensor and Timer)
|
# - Stairways (Extend Motion sensor and Timer)
|
||||||
|
def cleanup(tLogger):
|
||||||
|
time.sleep(0.5)
|
||||||
|
tLogger.debug("Collecting startup logs...")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# Command line arguments
|
||||||
|
tcel = {
|
||||||
|
"single": report.TCEL_SINGLE,
|
||||||
|
"full": report.TCEL_FULL
|
||||||
|
}
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("level", help="Set the execution level", choices=tcel.keys(), default="full")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
#
|
#
|
||||||
# MQTT Client
|
# MQTT Client
|
||||||
#
|
#
|
||||||
mc = mqtt.mqtt_client(host=config.MQTT_SERVER, port=config.MQTT_PORT, username=config.MQTT_USER,
|
mc = mqtt.mqtt_client(host=config.MQTT_SERVER, port=config.MQTT_PORT, username=config.MQTT_USER,
|
||||||
password=config.MQTT_PASSWORD, name=config.APP_NAME + '_simulation')
|
password=config.MQTT_PASSWORD, name=config.APP_NAME)
|
||||||
#
|
#
|
||||||
# Smarthome physical Devices
|
# Smarthome physical Devices
|
||||||
#
|
#
|
||||||
pd = devdi.devices.physical_devices(mc)
|
pd = devdi.devices.physical_devices(mc)
|
||||||
|
|
||||||
#
|
#
|
||||||
COMMANDS = ['quit', 'help']
|
# House instance
|
||||||
#
|
#
|
||||||
h = house(mc, pd)
|
h = house(mc, pd)
|
||||||
for name in h.getmembers():
|
|
||||||
d = h.getobjbyname(name)
|
|
||||||
if d.capabilities() is None:
|
|
||||||
print("\n\n" + 2*"**********\n" + "\n" + name + "\n\n" + 2*"**********\n" + "\n\n")
|
|
||||||
print(type(d))
|
|
||||||
sys.exit(2)
|
|
||||||
else:
|
|
||||||
for c in d.capabilities():
|
|
||||||
COMMANDS.append(name + '.' + c)
|
|
||||||
#
|
#
|
||||||
ts = test_smarthome(h, mc)
|
# Testsuite
|
||||||
for name in ts.getmembers():
|
#
|
||||||
d = ts.getobjbyname(name)
|
ts = tests.help.testSession(mc, tcel=tcel.get(args.level))
|
||||||
for c in d.capabilities():
|
# Clean-Up
|
||||||
COMMANDS.append('test.' + name + '.' + c)
|
ts.testCase('Clean-Up', report.TCEL_SINGLE, cleanup)
|
||||||
|
# Add and run tests
|
||||||
def reduced_list(text):
|
tests.add_all_testcases(ts, mc, h)
|
||||||
"""
|
# Export testresults
|
||||||
Create reduced completation list
|
BASEPATH = os.path.abspath(os.path.join(os.path.dirname(__file__)))
|
||||||
"""
|
ts.export_results_to(
|
||||||
reduced_list = {}
|
template_file=os.path.join(BASEPATH, 'unittest', 'templates', 'unittest.tex'),
|
||||||
for cmd in COMMANDS:
|
path=os.path.join(BASEPATH, "testresults")
|
||||||
next_dot = cmd[len(text):].find('.')
|
)
|
||||||
if next_dot >= 0:
|
|
||||||
reduced_list[cmd[:len(text) + next_dot + 1]] = None
|
|
||||||
else:
|
|
||||||
reduced_list[cmd] = None
|
|
||||||
return reduced_list.keys()
|
|
||||||
|
|
||||||
def completer(text, state):
|
|
||||||
"""
|
|
||||||
Our custom completer function
|
|
||||||
"""
|
|
||||||
options = [x for x in reduced_list(text) if x.startswith(text)]
|
|
||||||
return options[state]
|
|
||||||
|
|
||||||
def complete(text, state):
|
|
||||||
for cmd in COMMANDS:
|
|
||||||
if cmd.startswith(text):
|
|
||||||
if not state:
|
|
||||||
hit = ""
|
|
||||||
index = 0
|
|
||||||
sub_list = cmd.split('.')
|
|
||||||
while len(text) >= len(hit):
|
|
||||||
hit += sub_list[index] + '.'
|
|
||||||
return hit # cmd
|
|
||||||
else:
|
|
||||||
state -= 1
|
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
|
||||||
readline.parse_and_bind("tab: complete")
|
|
||||||
readline.set_completer(completer)
|
|
||||||
print("\nEnter command: ")
|
|
||||||
while True:
|
|
||||||
userfeedback = input('')
|
|
||||||
command = userfeedback.split(' ')[0]
|
|
||||||
if userfeedback == 'quit':
|
|
||||||
break
|
|
||||||
elif userfeedback == 'help':
|
|
||||||
print("Help is not yet implemented!")
|
|
||||||
elif userfeedback.startswith("test"):
|
|
||||||
ts.command(userfeedback)
|
|
||||||
elif command in COMMANDS[2:]:
|
|
||||||
h.command(userfeedback)
|
|
||||||
elif userfeedback != "":
|
|
||||||
print("Unknown command!")
|
|
||||||
else:
|
|
||||||
print()
|
|
||||||
else:
|
|
||||||
cmd = sys.argv[1]
|
|
||||||
if cmd.startswith('test'):
|
|
||||||
ts.command(cmd)
|
|
||||||
else:
|
|
||||||
h.command(cmd)
|
|
||||||
|
|
||||||
ts.close()
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,55 +1,11 @@
|
|||||||
import report
|
from .rooms import ffe, ffw, gfe, gfw, stw
|
||||||
import simulation.devices
|
|
||||||
from unittest.test import equivalency_chk
|
|
||||||
from unittest.jsonlog import TRUN_EXEC_LVL
|
|
||||||
|
|
||||||
DT_TOGGLE = 0.3
|
# TODO: Coverage, *Information (Chapter 1), ... ausblenden, wenn leer
|
||||||
|
|
||||||
|
|
||||||
class test_collection(object):
|
def add_all_testcases(ts, mc, h):
|
||||||
TCEL_DICT = {
|
ffe(ts, mc, h)
|
||||||
'full': report.TCEL_FULL,
|
ffw(ts, mc, h)
|
||||||
'short': report.TCEL_SHORT,
|
gfe(ts, mc, h)
|
||||||
'smoke': report.TCEL_SMOKE
|
gfw(ts, mc, h)
|
||||||
}
|
stw(ts, mc, h)
|
||||||
|
|
||||||
def __init__(self, test_instance):
|
|
||||||
super().__init__()
|
|
||||||
self.test_instance = test_instance
|
|
||||||
|
|
||||||
def capabilities(self):
|
|
||||||
return ['full', 'short', 'smoke']
|
|
||||||
|
|
||||||
def command(self, command):
|
|
||||||
for member in self.test_instance.getmembers():
|
|
||||||
obj = self.test_instance.getobjbyname(member)
|
|
||||||
if id(obj) != id(self):
|
|
||||||
tcel = self.TCEL_DICT.get(command, report.TCEL_FULL)
|
|
||||||
self.test_instance.tcl[TRUN_EXEC_LVL] = tcel
|
|
||||||
obj.test_all(tcel)
|
|
||||||
|
|
||||||
|
|
||||||
class testcase(object):
|
|
||||||
METHOD_EXECUTED = {}
|
|
||||||
|
|
||||||
def __init__(self, tcl):
|
|
||||||
self.tcl = tcl
|
|
||||||
self.__test_list__ = []
|
|
||||||
|
|
||||||
def capabilities(self):
|
|
||||||
if len(self.__test_list__) > 0 and not 'test_all' in self.__test_list__:
|
|
||||||
self.__test_list__.append('test_all')
|
|
||||||
self.__test_list__.sort()
|
|
||||||
return self.__test_list__
|
|
||||||
|
|
||||||
def test_all(self, tcel=report.TCEL_FULL):
|
|
||||||
for tc_name in self.capabilities():
|
|
||||||
if tc_name != "test_all":
|
|
||||||
self.command(tc_name, tcel)
|
|
||||||
|
|
||||||
def command(self, command, tcel=report.TCEL_SINGLE):
|
|
||||||
simulation.devices.OUTPUT_ACTIVE = False
|
|
||||||
tc = getattr(self, command)
|
|
||||||
self.tcl[TRUN_EXEC_LVL] = tcel
|
|
||||||
tc(tcel)
|
|
||||||
simulation.devices.OUTPUT_ACTIVE = True
|
|
||||||
|
145
tests/all.py
145
tests/all.py
@ -1,145 +0,0 @@
|
|||||||
import distro
|
|
||||||
import getpass
|
|
||||||
import inspect
|
|
||||||
import jinja2
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
import report
|
|
||||||
from tests import test_collection
|
|
||||||
from tests.heating import testcase_heating
|
|
||||||
from tests.light import testcase_light
|
|
||||||
from tests.synchronisation import testcase_synchronisation
|
|
||||||
from unittest import jsonlog
|
|
||||||
|
|
||||||
try:
|
|
||||||
from config import APP_NAME as ROOT_LOGGER_NAME
|
|
||||||
except ImportError:
|
|
||||||
ROOT_LOGGER_NAME = 'root'
|
|
||||||
|
|
||||||
|
|
||||||
class test_smarthome(object):
|
|
||||||
def __init__(self, rooms, mqtt_client):
|
|
||||||
self.mqtt_client = mqtt_client
|
|
||||||
self.__init__tcl__()
|
|
||||||
self.mqtt_client.add_callback('__info__', self.__test_system_info__)
|
|
||||||
self.mqtt_client.send('__info__', json.dumps(None))
|
|
||||||
# add testcases for switching devices
|
|
||||||
for name in rooms.getmembers():
|
|
||||||
obj = rooms.getobjbyname(name)
|
|
||||||
if obj.__class__.__name__ == "videv_light":
|
|
||||||
common_name = '.'.join(name.split('.')[:-1]) + '.' + name.split('.')[-1][6:]
|
|
||||||
try:
|
|
||||||
li_device = rooms.getobjbyname(common_name + '_zigbee') if obj.enable_brightness or obj.enable_color_temp else None
|
|
||||||
except AttributeError:
|
|
||||||
li_device = rooms.getobjbyname(common_name + '_zigbee_1') if obj.enable_brightness or obj.enable_color_temp else None
|
|
||||||
try:
|
|
||||||
sw_device = rooms.getobjbyname(common_name) if obj.enable_state else None
|
|
||||||
except AttributeError:
|
|
||||||
# must be a device without switching device
|
|
||||||
sw_device = li_device
|
|
||||||
setattr(self, common_name.replace('.', '_'), testcase_light(self.tcl, obj, sw_device, li_device))
|
|
||||||
# add testcases for heating devices
|
|
||||||
for name in rooms.getmembers():
|
|
||||||
obj = rooms.getobjbyname(name)
|
|
||||||
if obj.__class__.__name__ == "videv_heating":
|
|
||||||
common_name = '.'.join(name.split('.')[:-1]) + '.' + name.split('.')[-1][6:]
|
|
||||||
heat_device = rooms.getobjbyname(common_name + '_valve')
|
|
||||||
setattr(self, common_name.replace('.', '_'), testcase_heating(self.tcl, obj, heat_device))
|
|
||||||
# TODO: Add this again...
|
|
||||||
"""
|
|
||||||
# synchronisation
|
|
||||||
# gfw.dirk.amplifier with cd_player
|
|
||||||
self.gfw_dirk_cd_player_amplifier_sync = testcase_synchronisation(
|
|
||||||
self.tcl,
|
|
||||||
rooms.gfw.dirk.cd_player, None, None,
|
|
||||||
rooms.gfw.dirk.amplifier)
|
|
||||||
# gfw.floor.main_light_2 with gfw.floor.main_light_1
|
|
||||||
self.gfw_floor_main_light_sync = testcase_synchronisation(
|
|
||||||
self.tcl,
|
|
||||||
rooms.gfw.floor.main_light, rooms.gfw.floor.videv_main_light, rooms.gfw.floor.videv_main_light,
|
|
||||||
rooms.gfw.floor.main_light_zigbee_1, rooms.gfw.floor.main_light_zigbee_2
|
|
||||||
)
|
|
||||||
# ffe.diningroom.floorlamp with ffe.dinigroom.main_light
|
|
||||||
self.ffe_diningroom_main_light_floor_lamp_sync = testcase_synchronisation(
|
|
||||||
self.tcl,
|
|
||||||
rooms.ffe.diningroom.main_light, None, None,
|
|
||||||
rooms.ffe.diningroom.floor_lamp)
|
|
||||||
# ffe.livingroom.floorlamp_[1-6] with ffe.livingroom.main_light
|
|
||||||
self.ffe_livingroom_main_light_floor_lamp_sync = testcase_synchronisation(
|
|
||||||
self.tcl,
|
|
||||||
rooms.ffe.livingroom.main_light, rooms.ffe.livingroom.videv_floor_lamp, rooms.ffe.livingroom.videv_floor_lamp,
|
|
||||||
*[getattr(rooms.ffe.livingroom, "floor_lamp_zigbee_%d" % i) for i in range(1, 7)]
|
|
||||||
)
|
|
||||||
# add test collection
|
|
||||||
"""
|
|
||||||
self.all = test_collection(self)
|
|
||||||
|
|
||||||
def __init__tcl__(self):
|
|
||||||
system_info = {}
|
|
||||||
system_info[jsonlog.SYSI_ARCHITECTURE] = platform.architecture()[0]
|
|
||||||
system_info[jsonlog.SYSI_MACHINE] = platform.machine()
|
|
||||||
system_info[jsonlog.SYSI_HOSTNAME] = platform.node()
|
|
||||||
system_info[jsonlog.SYSI_DISTRIBUTION] = distro.name() + " " + distro.version() + " (" + distro.codename() + ")"
|
|
||||||
system_info[jsonlog.SYSI_SYSTEM] = platform.system()
|
|
||||||
system_info[jsonlog.SYSI_KERNEL] = platform.release() + ' (%s)' % platform.version()
|
|
||||||
system_info[jsonlog.SYSI_USERNAME] = getpass.getuser()
|
|
||||||
system_info[jsonlog.SYSI_PATH] = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
self.tcl = report.testSession(['__unittest__', ROOT_LOGGER_NAME])
|
|
||||||
self.tcl[jsonlog.MAIN_KEY_SYSTEM_INFO] = system_info
|
|
||||||
self.tcl["testcase_names"] = report.TCEL_NAMES
|
|
||||||
|
|
||||||
def __test_system_info__(self, client, userdata, message):
|
|
||||||
data = json.loads(message.payload)
|
|
||||||
if data is not None:
|
|
||||||
self.tcl[jsonlog.MAIN_KEY_TESTOBJECT_INFO] = data
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
path = os.path.abspath(os.path.join(os.path.basename(__file__), '..'))
|
|
||||||
|
|
||||||
with open(os.path.join(path, "testresults", "testrun.json"), "w") as fh:
|
|
||||||
fh.write(json.dumps(self.tcl, indent=4))
|
|
||||||
|
|
||||||
template_path = os.path.join(path, 'templates')
|
|
||||||
template_filename = 'unittest.tex'
|
|
||||||
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader(template_path))
|
|
||||||
template = jenv.get_template(template_filename)
|
|
||||||
with open(os.path.join(path, "testresults", "testrun.tex"), "w") as fh:
|
|
||||||
fh.write(template.render(data=self.tcl, details=False))
|
|
||||||
with open(os.path.join(path, "testresults", "testrun_full.tex"), "w") as fh:
|
|
||||||
fh.write(template.render(data=self.tcl, details=True))
|
|
||||||
|
|
||||||
def getmembers(self, prefix=''):
|
|
||||||
rv = []
|
|
||||||
for name, obj in inspect.getmembers(self):
|
|
||||||
if prefix:
|
|
||||||
full_name = prefix + '.' + name
|
|
||||||
else:
|
|
||||||
full_name = name
|
|
||||||
if not name.startswith('_'):
|
|
||||||
try:
|
|
||||||
if obj.__class__.__bases__[0].__name__ == "testcase" or obj.__class__.__name__ == "test_collection":
|
|
||||||
rv.append(full_name)
|
|
||||||
else:
|
|
||||||
rv.extend(obj.getmembers(full_name))
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
return rv
|
|
||||||
|
|
||||||
def getobjbyname(self, name):
|
|
||||||
if name.startswith("test."):
|
|
||||||
name = name[5:]
|
|
||||||
obj = self
|
|
||||||
for subname in name.split('.'):
|
|
||||||
obj = getattr(obj, subname)
|
|
||||||
return obj
|
|
||||||
|
|
||||||
def command(self, full_command):
|
|
||||||
try:
|
|
||||||
parameter = " " + full_command.split(' ')[1]
|
|
||||||
except IndexError:
|
|
||||||
parameter = ""
|
|
||||||
command = full_command.split(' ')[0].split('.')[-1] + parameter
|
|
||||||
device_name = '.'.join(full_command.split(' ')[0].split('.')[:-1])
|
|
||||||
self.getobjbyname(device_name).command(command)
|
|
27
tests/common_testcases.py
Normal file
27
tests/common_testcases.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
from unittest.test import equivalency_chk
|
||||||
|
|
||||||
|
from .help import DELAY_SET_GET
|
||||||
|
|
||||||
|
|
||||||
|
def device_follow(tLogger, master, master_key, slave, slave_key, values):
|
||||||
|
# Prepare devices to last state
|
||||||
|
start_state = values[-1]
|
||||||
|
master.set(master_key, start_state)
|
||||||
|
slave.set(master_key, start_state)
|
||||||
|
time.sleep(DELAY_SET_GET)
|
||||||
|
tLogger.debug("Prepare: Setting devices to last state %s", repr(start_state))
|
||||||
|
master_exp = master.get(master_key)
|
||||||
|
slave_exp = slave.get(slave_key)
|
||||||
|
time.sleep(DELAY_SET_GET)
|
||||||
|
equivalency_chk((master_exp, slave_exp), (start_state, start_state), tLogger, "Start state (master, slave)")
|
||||||
|
|
||||||
|
# Test devices
|
||||||
|
for value in values:
|
||||||
|
tLogger.debug("Setting state of %s to %s", master.topic, repr(value))
|
||||||
|
master.set(master_key, value)
|
||||||
|
time.sleep(DELAY_SET_GET)
|
||||||
|
expectation = slave.get(slave_key)
|
||||||
|
time.sleep(DELAY_SET_GET)
|
||||||
|
equivalency_chk(expectation, value, tLogger, f"Value for {slave.topic}")
|
152
tests/heating.py
152
tests/heating.py
@ -1,152 +0,0 @@
|
|||||||
import config
|
|
||||||
import inspect
|
|
||||||
import report
|
|
||||||
from tests import testcase, DT_TOGGLE
|
|
||||||
import time
|
|
||||||
from unittest.test import equivalency_chk, greater_chk
|
|
||||||
|
|
||||||
|
|
||||||
class testcase_heating(testcase):
|
|
||||||
def __init__(self, tcl, videv, valve):
|
|
||||||
super().__init__(tcl)
|
|
||||||
self.__videv__ = videv
|
|
||||||
self.__valve__ = valve
|
|
||||||
self.__default_temperature__ = config.DEFAULT_TEMPERATURE
|
|
||||||
self.__test_list__ = ["test_user_temperature_setpoint", "test_default_temperature", "test_summer_mode", "test_away_mode", "test_boost_mode"]
|
|
||||||
|
|
||||||
def test_user_temperature_setpoint(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("User temperature setpoint test for virtual device and device: %s" %
|
|
||||||
self.__valve__.topic, tcel, self.__test_user_temperature_setpoint__, tcel)
|
|
||||||
|
|
||||||
def __test_user_temperature_setpoint__(self, tLogger, tcel):
|
|
||||||
mtemp = round(self.__valve__.TEMP_RANGE[0] + (self.__valve__.TEMP_RANGE[1] - self.__valve__.TEMP_RANGE[0]) / 2, 1)
|
|
||||||
setp = self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT)
|
|
||||||
delta = 5 if setp < mtemp else -5
|
|
||||||
|
|
||||||
for i in range(0, 2):
|
|
||||||
self.__videv__.set(self.__videv__.KEY_USER_TEMPERATURE_SETPOINT, setp + delta)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing valve temperature setpoint to '%.1f'", setp + delta)
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_VALVE_TEMPERATURE_SETPOINT),
|
|
||||||
setp + delta, tLogger, "Virtual device valve temperature")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_USER_TEMPERATURE_SETPOINT),
|
|
||||||
setp + delta, tLogger, "Virtual device user temperature")
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT),
|
|
||||||
setp + delta, tLogger, "Valve temperature setpoint")
|
|
||||||
#
|
|
||||||
self.__videv__.set(self.__videv__.KEY_USER_TEMPERATURE_SETPOINT, setp)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing videv user temperature setpoint to '%.1f'", setp)
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT), setp, tLogger, "Valve device temperature setpoint")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_VALVE_TEMPERATURE_SETPOINT), setp, tLogger, "Virtual device valve temperature")
|
|
||||||
|
|
||||||
def test_default_temperature(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Default temperature test for device and virtual device: %s" %
|
|
||||||
self.__valve__.topic, tcel, self.__test_default_temperature__, tcel)
|
|
||||||
|
|
||||||
def __test_default_temperature__(self, tLogger, tcel):
|
|
||||||
dtemp = config.DEFAULT_TEMPERATURE
|
|
||||||
mtemp = round(self.__valve__.TEMP_RANGE[0] + (self.__valve__.TEMP_RANGE[1] - self.__valve__.TEMP_RANGE[0]) / 2, 1)
|
|
||||||
ptemp = dtemp + (5 if dtemp < mtemp else -5)
|
|
||||||
|
|
||||||
self.__videv__.set(self.__videv__.KEY_USER_TEMPERATURE_SETPOINT, config.DEFAULT_TEMPERATURE - 5)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions (Valve setpoint to %.1f)", ptemp)
|
|
||||||
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT) != dtemp,
|
|
||||||
True, tLogger, "Valve temperature setpoint (is not default temperature)")
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SET_DEFAULT_TEMPERATURE, None)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Triggering set to default temperature (%.1f)", dtemp)
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT), dtemp, tLogger, "Valve temperature setpoint")
|
|
||||||
|
|
||||||
def test_summer_mode(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Summer mode test: %s" % self.__valve__.topic, tcel, self.__test_summer_mode__, tcel)
|
|
||||||
|
|
||||||
def __test_summer_mode__(self, tLogger, tcel):
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SET_DEFAULT_TEMPERATURE, None)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions (Default setpoint)")
|
|
||||||
|
|
||||||
vtemp = self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT)
|
|
||||||
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_SUMMER_MODE), False, tLogger, "Summer mode")
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SUMMER_MODE, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Activating summer mode")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_SUMMER_MODE), True, tLogger, "Summer mode")
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT), 5, tLogger, "Temperature setpoint")
|
|
||||||
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SUMMER_MODE, False)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Deactivating summer mode")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_SUMMER_MODE), False, tLogger, "Summer mode")
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT), vtemp, tLogger, "Temperature setpoint")
|
|
||||||
|
|
||||||
def test_away_mode(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Away mode test: %s" % self.__valve__.topic, tcel, self.__test_away_mode__, tcel)
|
|
||||||
|
|
||||||
def __test_away_mode__(self, tLogger, tcel):
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SET_DEFAULT_TEMPERATURE, None)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions (Default setpoint)")
|
|
||||||
|
|
||||||
vtemp = self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT)
|
|
||||||
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_AWAY_MODE), False, tLogger, "Away mode")
|
|
||||||
self.__videv__.set(self.__videv__.KEY_AWAY_MODE, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Activating away mode")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_AWAY_MODE), True, tLogger, "Away mode")
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT), vtemp - 5, tLogger, "Temperature setpoint")
|
|
||||||
|
|
||||||
self.__videv__.set(self.__videv__.KEY_AWAY_MODE, False)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Deactivating away mode")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_AWAY_MODE), False, tLogger, "Away mode")
|
|
||||||
equivalency_chk(self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT), vtemp, tLogger, "Temperature setpoint")
|
|
||||||
|
|
||||||
def test_boost_mode(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Boost mode test: %s" % self.__valve__.topic, tcel, self.__test_boost_mode__, tcel)
|
|
||||||
|
|
||||||
def __test_boost_mode__(self, tLogger, tcel):
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SET_DEFAULT_TEMPERATURE, None)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions (Default setpoint)")
|
|
||||||
|
|
||||||
vtemp = self.__valve__.get(self.__valve__.KEY_TEMPERATURE_SETPOINT)
|
|
||||||
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_BOOST_TIMER), 0, tLogger, "Boost timer")
|
|
||||||
self.__videv__.set(self.__videv__.KEY_START_BOOST, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Activating boost mode")
|
|
||||||
greater_chk(self.__videv__.get(self.__videv__.KEY_BOOST_TIMER), 0, tLogger, "Boost timer")
|
|
||||||
|
|
||||||
self.__videv__.set(self.__videv__.KEY_SET_DEFAULT_TEMPERATURE, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting postconditions (Default setpoint)")
|
|
||||||
equivalency_chk(self.__videv__.get(self.__videv__.KEY_BOOST_TIMER), 0, tLogger, "Boost timer")
|
|
||||||
|
|
||||||
if tcel == report.TCEL_FULL:
|
|
||||||
# test boost timer
|
|
||||||
pass
|
|
87
tests/help.py
Normal file
87
tests/help.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import distro
|
||||||
|
import getpass
|
||||||
|
import jinja2
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import report
|
||||||
|
from report import testSession as testSessionBase
|
||||||
|
from unittest import jsonlog
|
||||||
|
|
||||||
|
from config import APP_NAME as ROOT_LOGGER_NAME
|
||||||
|
|
||||||
|
DELAY_SET_GET = 0.5
|
||||||
|
STATES_SW = (True, False)
|
||||||
|
|
||||||
|
|
||||||
|
class testSession(testSessionBase):
|
||||||
|
def __init__(self, mqtt_client, tcel=report.TCEL_FULL):
|
||||||
|
self.mqtt_client = mqtt_client
|
||||||
|
self.full_test_data = {}
|
||||||
|
param = {
|
||||||
|
jsonlog.TRUN_EXEC_LVL: tcel,
|
||||||
|
'interpreter': 'python'+sys.version.split(" ")[0]
|
||||||
|
}
|
||||||
|
super().__init__(['__unittest__', ROOT_LOGGER_NAME], **param)
|
||||||
|
# Get testobject information
|
||||||
|
self.mqtt_client.add_callback('__info__', self.__test_object_information__)
|
||||||
|
self.mqtt_client.send('__info__', json.dumps(None))
|
||||||
|
|
||||||
|
def __set_base_data__(self, **kwargs):
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_SYSTEM_INFO] = self.__system_info__()
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTOBJECT_INFO] = {"Name": "-"}
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_UNITTEST_INFO] = self.__unittest_information__()
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_SPECIFICATION] = self.__specification__()
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_LOST_SOULS] = {}
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTRUNS] = []
|
||||||
|
return super().__set_base_data__(**kwargs)
|
||||||
|
|
||||||
|
def __system_info__(self):
|
||||||
|
system_info = {}
|
||||||
|
system_info[jsonlog.SYSI_ARCHITECTURE] = platform.architecture()[0]
|
||||||
|
system_info[jsonlog.SYSI_MACHINE] = platform.machine()
|
||||||
|
system_info[jsonlog.SYSI_HOSTNAME] = platform.node()
|
||||||
|
system_info[jsonlog.SYSI_DISTRIBUTION] = distro.name() + " " + distro.version() + " (" + distro.codename() + ")"
|
||||||
|
system_info[jsonlog.SYSI_SYSTEM] = platform.system()
|
||||||
|
system_info[jsonlog.SYSI_KERNEL] = platform.release() + ' (%s)' % platform.version()
|
||||||
|
system_info[jsonlog.SYSI_USERNAME] = getpass.getuser()
|
||||||
|
system_info[jsonlog.SYSI_PATH] = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
return system_info
|
||||||
|
|
||||||
|
def __test_object_information__(self, client, userdata, message):
|
||||||
|
data = json.loads(message.payload)
|
||||||
|
if data is not None:
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTOBJECT_INFO]['Name'] = data.get("app_name", "-")
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTOBJECT_INFO]['Version'] = data.get("version", {}).get("readable", "-")
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTOBJECT_INFO]['Git URL'] = data.get("git", {}).get("url", "-")
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTOBJECT_INFO]['Git REF'] = data.get("git", {}).get("ref", "-")
|
||||||
|
|
||||||
|
def __unittest_information__(self):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def __specification__(self):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def __finalise__(self):
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_ITEMLIST] = []
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_LOST_SOULS][jsonlog.LOST_TESTCASELIST] = self["uid_list_sorted"][:]
|
||||||
|
self.full_test_data[jsonlog.MAIN_KEY_TESTRUNS].append(self)
|
||||||
|
|
||||||
|
def export_results_to(self, template_file, path):
|
||||||
|
self.__finalise__()
|
||||||
|
#
|
||||||
|
# Export json testrun data
|
||||||
|
#
|
||||||
|
with open(os.path.join(path, "testrun.json"), "w") as fh:
|
||||||
|
fh.write(json.dumps(self.full_test_data, indent=4))
|
||||||
|
#
|
||||||
|
# Export jinja templated data
|
||||||
|
#
|
||||||
|
template_path = os.path.dirname(template_file)
|
||||||
|
template_filename = os.path.basename(template_file)
|
||||||
|
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader(template_path))
|
||||||
|
template = jenv.get_template(template_filename)
|
||||||
|
with open(os.path.join(path, "testrun.tex"), "w") as fh:
|
||||||
|
fh.write(template.render(data=self.full_test_data))
|
105
tests/light.py
105
tests/light.py
@ -1,105 +0,0 @@
|
|||||||
import inspect
|
|
||||||
import report
|
|
||||||
from tests import testcase, DT_TOGGLE
|
|
||||||
import time
|
|
||||||
from unittest.test import equivalency_chk
|
|
||||||
|
|
||||||
|
|
||||||
class testcase_light(testcase):
|
|
||||||
def __init__(self, tcl, videv, sw_device, li_device):
|
|
||||||
super().__init__(tcl)
|
|
||||||
self.videv = videv
|
|
||||||
self.sw_device = sw_device
|
|
||||||
self.li_device = li_device
|
|
||||||
self.__test_list__ = []
|
|
||||||
if self.videv.enable_state:
|
|
||||||
self.__test_list__.append('test_power_on_off')
|
|
||||||
if self.videv.enable_brightness:
|
|
||||||
self.__test_list__.append('test_brightness')
|
|
||||||
if self.videv.enable_color_temp:
|
|
||||||
self.__test_list__.append('test_color_temp')
|
|
||||||
|
|
||||||
def test_power_on_off(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Power On/ Off test for device and virtual device: %s" % self.sw_device.topic, tcel, self.__test_power_on_off__, tcel)
|
|
||||||
|
|
||||||
def __test_power_on_off__(self, tLogger, tcel):
|
|
||||||
sw_state = self.sw_device.get(self.sw_device.KEY_OUTPUT_0)
|
|
||||||
|
|
||||||
for i in range(0, 2):
|
|
||||||
equivalency_chk(self.videv.get(self.videv.KEY_OUTPUT_0), sw_state, tLogger, "Virtual device state")
|
|
||||||
self.sw_device.set(self.sw_device.KEY_OUTPUT_0, not sw_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing switching device state to '%s'", not sw_state)
|
|
||||||
equivalency_chk(self.videv.get(self.videv.KEY_OUTPUT_0), not sw_state, tLogger, "Virtual device state")
|
|
||||||
#
|
|
||||||
equivalency_chk(self.sw_device.get(self.sw_device.KEY_OUTPUT_0), not sw_state, tLogger, "Switching device state")
|
|
||||||
self.videv.set(self.videv.KEY_OUTPUT_0, sw_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing virtual device state to '%s'", sw_state)
|
|
||||||
equivalency_chk(self.sw_device.get(self.sw_device.KEY_OUTPUT_0), sw_state, tLogger, "Switching device state")
|
|
||||||
|
|
||||||
def test_brightness(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Brightness test for device and virtual device: %s" % self.li_device.topic, tcel, self.__test_brightness__, tcel)
|
|
||||||
|
|
||||||
def __test_brightness__(self, tLogger, tcel):
|
|
||||||
br_state = self.li_device.get(self.li_device.KEY_BRIGHTNESS) or 50 # if br_state is None
|
|
||||||
delta = -15 if br_state > 50 else 15
|
|
||||||
self.sw_device.set(self.sw_device.KEY_OUTPUT_0, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions (Power on)")
|
|
||||||
|
|
||||||
for i in range(0, 2):
|
|
||||||
equivalency_chk(self.videv.get(self.videv.KEY_BRIGHTNESS), br_state, tLogger, "Virtual device brightness")
|
|
||||||
self.li_device.set(self.li_device.KEY_BRIGHTNESS, br_state + delta)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing light device brightness to '%d'", br_state + delta)
|
|
||||||
equivalency_chk(self.videv.get(self.videv.KEY_BRIGHTNESS), br_state + delta, tLogger, "Virtual device brightness")
|
|
||||||
#
|
|
||||||
equivalency_chk(self.li_device.get(self.li_device.KEY_BRIGHTNESS), br_state + delta, tLogger, "Light device brightness")
|
|
||||||
self.videv.set(self.videv.KEY_BRIGHTNESS, br_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing virtual device brightness to '%d'", br_state)
|
|
||||||
equivalency_chk(self.li_device.get(self.li_device.KEY_BRIGHTNESS), br_state, tLogger, "Light device brightness")
|
|
||||||
#
|
|
||||||
self.sw_device.set(self.sw_device.KEY_OUTPUT_0, False)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Resetting precondition (Power off)")
|
|
||||||
|
|
||||||
def test_color_temp(self, tcel=report.TCEL_FULL):
|
|
||||||
fname = inspect.currentframe().f_code.co_name
|
|
||||||
if tcel != report.TCEL_SMOKE or not self.METHOD_EXECUTED.get(fname, False):
|
|
||||||
self.METHOD_EXECUTED[fname] = True
|
|
||||||
#
|
|
||||||
self.tcl.testCase("Color temperature test for device and virtual device: %s" % self.li_device.topic, tcel, self.__test_color_temp__, tcel)
|
|
||||||
|
|
||||||
def __test_color_temp__(self, tLogger, tcel):
|
|
||||||
ct_state = self.li_device.get(self.li_device.KEY_COLOR_TEMP) or 5 # Use 5 if None
|
|
||||||
delta = -3 if ct_state > 5 else 3
|
|
||||||
self.sw_device.set(self.sw_device.KEY_OUTPUT_0, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions (Power on)")
|
|
||||||
|
|
||||||
for i in range(0, 2):
|
|
||||||
equivalency_chk(self.videv.get(self.videv.KEY_COLOR_TEMP), ct_state, tLogger, "Virtual device color temperature")
|
|
||||||
self.li_device.set(self.li_device.KEY_COLOR_TEMP, ct_state + delta)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing light device color temperature to '%d'", ct_state)
|
|
||||||
equivalency_chk(self.videv.get(self.videv.KEY_COLOR_TEMP), ct_state + delta, tLogger, "Virtual device color temperature")
|
|
||||||
#
|
|
||||||
equivalency_chk(self.li_device.get(self.li_device.KEY_COLOR_TEMP), ct_state + delta, tLogger, "Light device brightness")
|
|
||||||
self.videv.set(self.videv.KEY_COLOR_TEMP, ct_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing virtual device color temperature to '%d'", ct_state)
|
|
||||||
equivalency_chk(self.li_device.get(self.li_device.KEY_COLOR_TEMP), ct_state, tLogger, "Light device brightness")
|
|
||||||
#
|
|
||||||
self.sw_device.set(self.sw_device.KEY_OUTPUT_0, False)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Resetting precondition (Power off)")
|
|
112
tests/rooms.py
Normal file
112
tests/rooms.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
|
||||||
|
import report
|
||||||
|
|
||||||
|
from devdi.devices import physical_devices
|
||||||
|
from mqtt import mqtt_client
|
||||||
|
from simulation.rooms import house
|
||||||
|
|
||||||
|
from .help import testSession
|
||||||
|
from .help import STATES_SW
|
||||||
|
from tests.common_testcases import device_follow
|
||||||
|
|
||||||
|
|
||||||
|
def main_light_videv_shelly_sw(ts, testcase_id, room, single=False):
|
||||||
|
ts.testCase(
|
||||||
|
testcase_id, report.TCEL_SINGLE if single else report.TCEL_SMOKE, device_follow,
|
||||||
|
room.videv_main_light, room.videv_main_light.KEY_OUTPUT_0,
|
||||||
|
room.main_light, room.main_light.KEY_OUTPUT_0,
|
||||||
|
STATES_SW
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main_light_shelly_videv_sw(ts, testcase_id, room, single=False):
|
||||||
|
ts.testCase(
|
||||||
|
testcase_id, report.TCEL_SINGLE if single else report.TCEL_FULL, device_follow,
|
||||||
|
room.main_light, room.main_light.KEY_OUTPUT_0,
|
||||||
|
room.videv_main_light, room.videv_main_light.KEY_OUTPUT_0,
|
||||||
|
STATES_SW
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def ffe(ts: testSession, mc: mqtt_client, h: house):
|
||||||
|
# REQ 0001 - 0099
|
||||||
|
room = h.ffe.livingroom
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0001', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0002', room)
|
||||||
|
|
||||||
|
room = h.ffe.sleep
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0011', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0012', room)
|
||||||
|
|
||||||
|
room = h.ffe.diningroom
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0021', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0022', room)
|
||||||
|
|
||||||
|
room = h.ffe.kitchen
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0031', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0032', room)
|
||||||
|
|
||||||
|
h.ffe.floor
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0041', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0042', room)
|
||||||
|
|
||||||
|
|
||||||
|
def ffw(ts: testSession, mc: mqtt_client, h: house):
|
||||||
|
# REQ 0101 - 0199
|
||||||
|
room = h.ffw.livingroom
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0101', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0102', room)
|
||||||
|
|
||||||
|
room = h.ffw.sleep
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0111', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0112', room, True)
|
||||||
|
|
||||||
|
room = h.ffw.julian
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0121', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0122', room)
|
||||||
|
|
||||||
|
room = h.ffw.bath
|
||||||
|
|
||||||
|
room = h.ffw.floor
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0141', room, True)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0142', room, True)
|
||||||
|
|
||||||
|
|
||||||
|
def gfe(ts: testSession, mc: mqtt_client, h: house):
|
||||||
|
# REQ 0201 - 0299
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def gfw(ts: testSession, mc: mqtt_client, h: house):
|
||||||
|
# REQ 0301 - 0399
|
||||||
|
room = h.gfw.dirk
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0301', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0302', room)
|
||||||
|
|
||||||
|
room = h.gfw.marion
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0311', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0312', room)
|
||||||
|
|
||||||
|
room = h.gfw.floor
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0321', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0322', room)
|
||||||
|
|
||||||
|
|
||||||
|
def stw(ts: testSession, mc: mqtt_client, h: house):
|
||||||
|
# REQ 0401 - 0499
|
||||||
|
room = h.stairway
|
||||||
|
# main_light videv->shelly
|
||||||
|
main_light_videv_shelly_sw(ts, 'REQ-0401', room)
|
||||||
|
main_light_shelly_videv_sw(ts, 'REQ-0402', room)
|
@ -1,89 +0,0 @@
|
|||||||
import report
|
|
||||||
from tests import testcase, DT_TOGGLE
|
|
||||||
import time
|
|
||||||
from unittest.test import equivalency_chk
|
|
||||||
|
|
||||||
|
|
||||||
class testcase_synchronisation(testcase):
|
|
||||||
def __init__(self, tcl, sw_master, br_master, ct_master, *follower):
|
|
||||||
super().__init__(tcl)
|
|
||||||
self.sw_master = sw_master
|
|
||||||
self.br_master = br_master
|
|
||||||
self.ct_master = ct_master
|
|
||||||
self.follower = follower
|
|
||||||
#
|
|
||||||
self.__test_list__ = []
|
|
||||||
if sw_master is not None:
|
|
||||||
self.__test_list__.append('test_power_on_off_sync')
|
|
||||||
if br_master is not None:
|
|
||||||
self.__test_list__.append('test_brightness_sync')
|
|
||||||
if ct_master is not None:
|
|
||||||
self.__test_list__.append('test_color_temp_sync')
|
|
||||||
|
|
||||||
def test_power_on_off_sync(self, tcel=report.TCEL_FULL):
|
|
||||||
self.tcl.testCase("Power On/ Off synchronisation test: %s" % self.sw_master.topic, tcel, self.__test_power_on_off_sync__, tcel)
|
|
||||||
|
|
||||||
def __test_power_on_off_sync__(self, tLogger, tcel):
|
|
||||||
f_state = self.follower[0].get(self.follower[0].KEY_OUTPUT_0)
|
|
||||||
self.sw_master.set(self.sw_master.KEY_OUTPUT_0, f_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions for master device '%s'", f_state)
|
|
||||||
|
|
||||||
for i in range(0, 2):
|
|
||||||
f_state = not f_state
|
|
||||||
self.sw_master.set(self.sw_master.KEY_OUTPUT_0, f_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing master device state to '%s'", f_state)
|
|
||||||
|
|
||||||
for fo in self.follower:
|
|
||||||
equivalency_chk(fo.get(fo.KEY_OUTPUT_0), f_state, tLogger, "Follower device (%s) state" % fo.topic)
|
|
||||||
|
|
||||||
def test_brightness_sync(self, tcel=report.TCEL_FULL):
|
|
||||||
self.tcl.testCase("Brightness synchronisation test: %s" % self.br_master.topic, tcel, self.__test_brightness_sync__, tcel)
|
|
||||||
|
|
||||||
def __test_brightness_sync__(self, tLogger, tcel):
|
|
||||||
sw_state = self.sw_master.get(self.sw_master.KEY_OUTPUT_0)
|
|
||||||
self.sw_master.set(self.sw_master.KEY_OUTPUT_0, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions for master device '%s' (Power on)", True)
|
|
||||||
|
|
||||||
target = self.follower[0].get(self.follower[0].KEY_BRIGHTNESS)
|
|
||||||
delta = 15 if target < 50 else -15
|
|
||||||
for i in range(0, 2):
|
|
||||||
target = target + delta
|
|
||||||
self.br_master.set(self.br_master.KEY_BRIGHTNESS, target)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing master device brightness to '%d'", target)
|
|
||||||
for fo in self.follower:
|
|
||||||
equivalency_chk(fo.get(fo.KEY_BRIGHTNESS), target, tLogger, "Follower device (%s) brightness" % fo.topic)
|
|
||||||
delta = -delta
|
|
||||||
|
|
||||||
# reset changes of precondition
|
|
||||||
self.sw_master.set(self.sw_master.KEY_OUTPUT_0, sw_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Resetting preconditions for master device '%s' (Power off)", sw_state)
|
|
||||||
|
|
||||||
def test_color_temp_sync(self, tcel=report.TCEL_FULL):
|
|
||||||
self.tcl.testCase("Color temperature synchronisation test: %s" % self.ct_master.topic, tcel, self.__test_color_temp_sync__, tcel)
|
|
||||||
|
|
||||||
def __test_color_temp_sync__(self, tLogger, tcel):
|
|
||||||
sw_state = self.sw_master.get(self.sw_master.KEY_OUTPUT_0)
|
|
||||||
self.sw_master.set(self.sw_master.KEY_OUTPUT_0, True)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Setting preconditions for master device '%s' (Power on)", True)
|
|
||||||
|
|
||||||
target = self.follower[0].get(self.follower[0].KEY_COLOR_TEMP)
|
|
||||||
delta = 3 if target < 5 else -3
|
|
||||||
for i in range(0, 2):
|
|
||||||
target = target + delta
|
|
||||||
self.ct_master.set(self.br_master.KEY_COLOR_TEMP, target)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Changing master device color temperature to '%d'", target)
|
|
||||||
for fo in self.follower:
|
|
||||||
equivalency_chk(fo.get(fo.KEY_COLOR_TEMP), target, tLogger, "Follower device (%s) color temperature" % fo.topic)
|
|
||||||
delta = -delta
|
|
||||||
|
|
||||||
# reset changes of precondition
|
|
||||||
self.sw_master.set(self.sw_master.KEY_OUTPUT_0, sw_state)
|
|
||||||
time.sleep(DT_TOGGLE)
|
|
||||||
tLogger.debug("Resetting preconditions for master device '%s' (Power off)", sw_state)
|
|
Loading…
x
Reference in New Issue
Block a user