Summary
/**
- Copyright 2020 Markus Liljergren
-
- Version: v1.0.1.0425Tb
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at:
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
// BEGIN:getDefaultImports()
/** Default Imports */
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
// Used for MD5 calculations
import java.security.MessageDigest
// END: getDefaultImports()
metadata {
// Do NOT rename the child driver name unless you also change the corresponding code in the Parent!
definition (name: "Tasmota - Universal Metering Plug/Outlet (Child)", namespace: "tasmota", author: "Markus Liljergren", importUrl: "https://raw.githubusercontent.com/markus-li/Hubitat/development/drivers/expanded/tasmota-universal-metering-plug-outlet-child-expanded.groovy") {
capability "Actuator"
capability "Switch"
capability "Outlet"
capability "Sensor"
capability "Refresh"
// BEGIN:getDefaultMetadataCapabilitiesForEnergyMonitor()
// Default Capabilities for Energy Monitor
capability "VoltageMeasurement"
capability "PowerMeter"
capability "EnergyMeter"
// END: getDefaultMetadataCapabilitiesForEnergyMonitor()
// BEGIN:getDefaultMetadataAttributesForEnergyMonitor()
// Default Attributes for Energy Monitor
attribute "current", "string"
attribute "apparentPower", "string"
attribute "reactivePower", "string"
attribute "powerFactor", "string"
attribute "energyToday", "string"
attribute "energyYesterday", "string"
attribute "energyTotal", "string"
attribute "voltageWithUnit", "string"
attribute "powerWithUnit", "string"
// END: getDefaultMetadataAttributesForEnergyMonitor()
// BEGIN:getMinimumChildAttributes()
// Attributes used by all Child Drivers
attribute "driver", "string"
// END: getMinimumChildAttributes()
}
preferences {
// BEGIN:getDefaultMetadataPreferences()
// Default Preferences
input(name: "debugLogging", type: "bool", title: addTitleDiv("Enable debug logging"), description: "" , defaultValue: false, submitOnChange: true, displayDuringSetup: false, required: false)
input(name: "infoLogging", type: "bool", title: addTitleDiv("Enable descriptionText logging"), description: "", defaultValue: false, submitOnChange: true, displayDuringSetup: false, required: false)
// END: getDefaultMetadataPreferences()
}
// The below line needs to exist in ALL drivers for custom CSS to work!
// BEGIN:getMetadataCustomizationMethods()
// Here getPreferences() can be used to get the above preferences
metaDataExporter()
if(isCSSDisabled() == false) {
preferences {
input(name: "hiddenSetting", description: "" + getDriverCSSWrapper(), title: "None", displayDuringSetup: false, type: "paragraph", element: "paragraph")
}
}
// END: getMetadataCustomizationMethods()
}
// BEGIN:getDeviceInfoFunction()
String getDeviceInfoByName(infoName) {
// DO NOT EDIT: This is generated from the metadata!
// TODO: Figure out how to get this from Hubitat instead of generating this?
Map deviceInfo = ['name': 'Tasmota - Universal Metering Plug/Outlet (Child)', 'namespace': 'tasmota', 'author': 'Markus Liljergren', 'importUrl': 'https://raw.githubusercontent.com/markus-li/Hubitat/development/drivers/expanded/tasmota-universal-metering-plug-outlet-child-expanded.groovy']
//logging("deviceInfo[${infoName}] = ${deviceInfo[infoName]}", 1)
return(deviceInfo[infoName])
}
// END: getDeviceInfoFunction()
/* These functions are unique to each driver */
void parse(List description) {
description.each {
if (it.name in ["current", "apparentPower", "reactivePower", "powerFactor", "energyToday",
"energyYesterday", "energyTotal", "voltageWithUnit", "powerWithUnit",
"voltage", "power", "energy", "switch"]) {
logging(it.descriptionText, 100)
sendEvent(it)
} else {
log.warn "Got '$it.name' attribute data, but doesn't know what to do with it! Did you choose the right device type?"
}
}
}
void updated() {
log.info "updated()"
// BEGIN:getChildComponentDefaultUpdatedContent()
// This is code needed to run in updated() in ALL Child drivers
getDriverVersion()
// END: getChildComponentDefaultUpdatedContent()
refresh()
}
void installed() {
log.info "installed()"
device.removeSetting("logLevel")
device.updateSetting("logLevel", "100")
refresh()
}
void refresh() {
// BEGIN:getChildComponentMetaConfigCommands()
// metaConfig is what contains all fields to hide and other configuration
// processed in the "metadata" context of the driver.
def metaConfig = clearThingsToHide()
metaConfig = setDatasToHide(['metaConfig', 'isComponent', 'preferences', 'label', 'name'], metaConfig=metaConfig)
// END: getChildComponentMetaConfigCommands()
parent?.componentRefresh(this.device)
}
void on() {
parent?.componentOn(this.device)
}
void off() {
parent?.componentOff(this.device)
}
/**
-
- Everything below here are LIBRARY includes and should NOT be edited manually!
-
- --- Nothing to edit here, move along! ---------------------------------------
-
*/
// BEGIN:getDefaultFunctions()
/* Default Driver Methods go here */
private String getDriverVersion() {
//comment = ""
//if(comment != "") state.comment = comment
String version = "v1.0.1.0425Tb"
logging("getDriverVersion() = ${version}", 100)
sendEvent(name: "driver", value: version)
updateDataValue('driver', version)
return version
}
// END: getDefaultFunctions()
// Don't need this include anymore:
//#include:getHelperFunctions('all-debug')
/**
- ALL DEFAULT METHODS (helpers-all-default)
-
- Helper functions included in all drivers/apps
*/
boolean isDriver() {
try {
// If this fails, this is not a driver...
getDeviceDataByName('_unimportant')
logging("This IS a driver!", 0)
return true
} catch (MissingMethodException e) {
logging("This is NOT a driver!", 0)
return false
}
}
void deviceCommand(cmd) {
def jsonSlurper = new JsonSlurper()
cmd = jsonSlurper.parseText(cmd)
logging("deviceCommand: ${cmd}", 0)
r = this."${cmd['cmd']}"(*cmd['args'])
logging("deviceCommand return: ${r}", 0)
updateDataValue('appReturn', JsonOutput.toJson(r))
}
/*
initialize
Purpose: initialize the driver/app
Note: also called from updated()
This is called when the hub starts, DON'T declare it with return as void,
that seems like it makes it to not run? Since testing require hub reboots
and this works, this is not conclusive...
*/
// Call order: installed() -> configure() -> updated() -> initialize()
def initialize() {
logging("initialize()", 100)
unschedule("updatePresence")
// disable debug logs after 30 min, unless override is in place
if (debugLogging == true || (logLevel != "0" && logLevel != "100")) {
if(runReset != "DEBUG") {
log.warn "Debug logging will be disabled in 30 minutes..."
} else {
log.warn "Debug logging will NOT BE AUTOMATICALLY DISABLED!"
}
runIn(1800, "logsOff")
}
if(isDriver()) {
if(!isDeveloperHub()) {
device.removeSetting("logLevel")
device.updateSetting("logLevel", "0")
} else {
device.removeSetting("debugLogging")
device.updateSetting("debugLogging", "false")
device.removeSetting("infoLogging")
device.updateSetting("infoLogging", "false")
}
}
try {
// In case we have some more to run specific to this driver/app
initializeAdditional()
} catch (MissingMethodException e) {
// ignore
}
refresh()
}
/**
-
Automatically disable debug logging after 30 mins.
-
-
Note: scheduled in Initialize()
*/
void logsOff() {
if(runReset != "DEBUG") {
log.warn "Debug logging disabled..."
// Setting logLevel to "0" doesn't seem to work, it disables logs, but does not update the UI...
//device.updateSetting("logLevel",[value:"0",type:"string"])
//app.updateSetting("logLevel",[value:"0",type:"list"])
// Not sure which ones are needed, so doing all... This works!
if(isDriver()) {
device.clearSetting("logLevel")
device.removeSetting("logLevel")
device.updateSetting("logLevel", "0")
state?.settings?.remove("logLevel")
device.clearSetting("debugLogging")
device.removeSetting("debugLogging")
device.updateSetting("debugLogging", "false")
state?.settings?.remove("debugLogging")
} else {
//app.clearSetting("logLevel")
// To be able to update the setting, it has to be removed first, clear does NOT work, at least for Apps
app.removeSetting("logLevel")
app.updateSetting("logLevel", "0")
app.removeSetting("debugLogging")
app.updateSetting("debugLogging", "false")
}
} else {
log.warn "OVERRIDE: Disabling Debug logging will not execute with 'DEBUG' set..."
if (logLevel != "0" && logLevel != "100") runIn(1800, "logsOff")
}
}
boolean isDeveloperHub() {
return generateMD5(location.hub.zigbeeId as String) == "125fceabd0413141e34bb859cd15e067_disabled"
}
def getEnvironmentObject() {
if(isDriver()) {
return device
} else {
return app
}
}
private def getFilteredDeviceDriverName() {
def deviceDriverName = getDeviceInfoByName('name')
if(deviceDriverName.toLowerCase().endsWith(' (parent)')) {
deviceDriverName = deviceDriverName.substring(0, deviceDriverName.length()-9)
}
return deviceDriverName
}
private def getFilteredDeviceDisplayName() {
def deviceDisplayName = device.displayName.replace(' (parent)', '').replace(' (Parent)', '')
return deviceDisplayName
}
/*
General Mathematical and Number Methods
*/
BigDecimal round2(BigDecimal number, Integer scale) {
Integer pow = 10;
for (Integer i = 1; i < scale; i++)
pow *= 10;
BigDecimal tmp = number * pow;
return ( (Float) ( (Integer) ((tmp - (Integer) tmp) >= 0.5f ? tmp + 1 : tmp) ) ) / pow;
}
String generateMD5(String s) {
if(s != null) {
return MessageDigest.getInstance("MD5").digest(s.bytes).encodeHex().toString()
} else {
return "null"
}
}
Integer extractInt(String input) {
return input.replaceAll("[^0-9]", "").toInteger()
}
/**
- --END-- ALL DEFAULT METHODS (helpers-all-default)
*/
/**
- DRIVER METADATA METHODS (helpers-driver-metadata)
-
- These methods are to be used in (and/or with) the metadata section of drivers and
- is also what contains the CSS handling and styling.
*/
// These methods can be executed in both the NORMAL driver scope as well
// as the Metadata scope.
private Map getMetaConfig() {
// This method can ALSO be executed in the Metadata Scope
def metaConfig = getDataValue('metaConfig')
if(metaConfig == null) {
metaConfig = [:]
} else {
metaConfig = parseJson(metaConfig)
}
return metaConfig
}
boolean isCSSDisabled(Map metaConfig=null) {
if(metaConfig==null) metaConfig = getMetaConfig()
boolean disableCSS = false
if(metaConfig.containsKey("disableCSS")) disableCSS = metaConfig["disableCSS"]
return disableCSS
}
// These methods are used to set which elements to hide.
// They have to be executed in the NORMAL driver scope.
private void saveMetaConfig(Map metaConfig) {
updateDataValue('metaConfig', JsonOutput.toJson(metaConfig))
}
private Map setSomethingToHide(String type, List something, Map metaConfig=null) {
if(metaConfig==null) metaConfig = getMetaConfig()
def oldData = []
something = something.unique()
if(!metaConfig.containsKey("hide")) {
metaConfig["hide"] = [type:something]
} else {
//logging("setSomethingToHide 1 else: something: '$something', type:'$type' (${metaConfig["hide"]}) containsKey:${metaConfig["hide"].containsKey(type)}", 1)
if(metaConfig["hide"].containsKey(type)) {
//logging("setSomethingToHide 1 hasKey else: something: '$something', type:'$type' (${metaConfig["hide"]}) containsKey:${metaConfig["hide"].containsKey(type)}", 1)
metaConfig["hide"][type].addAll(something)
} else {
//logging("setSomethingToHide 1 noKey else: something: '$something', type:'$type' (${metaConfig["hide"]}) containsKey:${metaConfig["hide"].containsKey(type)}", 1)
metaConfig["hide"][type] = something
}
//metaConfig["hide"]["$type"] = oldData
//logging("setSomethingToHide 2 else: something: '$something', type:'$type' (${metaConfig["hide"]}) containsKey:${metaConfig["hide"].containsKey(type)}", 1)
}
saveMetaConfig(metaConfig)
logging("setSomethingToHide() = ${metaConfig}", 1)
return metaConfig
}
private Map clearTypeToHide(String type, Map metaConfig=null) {
if(metaConfig==null) metaConfig = getMetaConfig()
if(!metaConfig.containsKey("hide")) {
metaConfig["hide"] = [(type):[]]
} else {
metaConfig["hide"][(type)] = []
}
saveMetaConfig(metaConfig)
logging("clearTypeToHide() = ${metaConfig}", 1)
return metaConfig
}
Map clearThingsToHide(Map metaConfig=null) {
metaConfig = setSomethingToHide("other", [], metaConfig=metaConfig)
metaConfig["hide"] = [:]
saveMetaConfig(metaConfig)
logging("clearThingsToHide() = ${metaConfig}", 1)
return metaConfig
}
Map setDisableCSS(boolean value, Map metaConfig=null) {
if(metaConfig==null) metaConfig = getMetaConfig()
metaConfig["disableCSS"] = value
saveMetaConfig(metaConfig)
logging("setDisableCSS(value = $value) = ${metaConfig}", 1)
return metaConfig
}
Map setStateCommentInCSS(String stateComment, Map metaConfig=null) {
if(metaConfig==null) metaConfig = getMetaConfig()
metaConfig["stateComment"] = stateComment
saveMetaConfig(metaConfig)
logging("setStateCommentInCSS(stateComment = $stateComment) = ${metaConfig}", 1)
return metaConfig
}
Map setCommandsToHide(List commands, Map metaConfig=null) {
metaConfig = setSomethingToHide("command", commands, metaConfig=metaConfig)
logging("setCommandsToHide(${commands})", 1)
return metaConfig
}
Map clearCommandsToHide(Map metaConfig=null) {
metaConfig = clearTypeToHide("command", metaConfig=metaConfig)
logging("clearCommandsToHide(metaConfig=${metaConfig})", 1)
return metaConfig
}
Map setStateVariablesToHide(List stateVariables, Map metaConfig=null) {
metaConfig = setSomethingToHide("stateVariable", stateVariables, metaConfig=metaConfig)
logging("setStateVariablesToHide(${stateVariables})", 1)
return metaConfig
}
Map clearStateVariablesToHide(Map metaConfig=null) {
metaConfig = clearTypeToHide("stateVariable", metaConfig=metaConfig)
logging("clearStateVariablesToHide(metaConfig=${metaConfig})", 1)
return metaConfig
}
Map setCurrentStatesToHide(List currentStates, Map metaConfig=null) {
metaConfig = setSomethingToHide("currentState", currentStates, metaConfig=metaConfig)
logging("setCurrentStatesToHide(${currentStates})", 1)
return metaConfig
}
Map clearCurrentStatesToHide(Map metaConfig=null) {
metaConfig = clearTypeToHide("currentState", metaConfig=metaConfig)
logging("clearCurrentStatesToHide(metaConfig=${metaConfig})", 1)
return metaConfig
}
Map setDatasToHide(List datas, Map metaConfig=null) {
metaConfig = setSomethingToHide("data", datas, metaConfig=metaConfig)
logging("setDatasToHide(${datas})", 1)
return metaConfig
}
Map clearDatasToHide(Map metaConfig=null) {
metaConfig = clearTypeToHide("data", metaConfig=metaConfig)
logging("clearDatasToHide(metaConfig=${metaConfig})", 1)
return metaConfig
}
Map setPreferencesToHide(List preferences, Map metaConfig=null) {
metaConfig = setSomethingToHide("preference", preferences, metaConfig=metaConfig)
logging("setPreferencesToHide(${preferences})", 1)
return metaConfig
}
Map clearPreferencesToHide(Map metaConfig=null) {
metaConfig = clearTypeToHide("preference", metaConfig=metaConfig)
logging("clearPreferencesToHide(metaConfig=${metaConfig})", 1)
return metaConfig
}
// These methods are for executing inside the metadata section of a driver.
def metaDataExporter() {
//log.debug "getEXECUTOR_TYPE = ${getEXECUTOR_TYPE()}"
List filteredPrefs = getPreferences()['sections']['input'].name[0]
//log.debug "filteredPrefs = ${filteredPrefs}"
if(filteredPrefs != []) updateDataValue('preferences', "${filteredPrefs}".replaceAll("\s",""))
}
// These methods are used to add CSS to the driver page
// This can be used for, among other things, to hide Commands
// They HAVE to be run in getDriverCSS() or getDriverCSSWrapper()!
/* Example usage:
r += getCSSForCommandsToHide(["off", "refresh"])
r += getCSSForStateVariablesToHide(["alertMessage", "mac", "dni", "oldLabel"])
r += getCSSForCurrentStatesToHide(["templateData", "tuyaMCU", "needUpdate"])
r += getCSSForDatasToHide(["preferences", "appReturn"])
r += getCSSToChangeCommandTitle("configure", "Run Configure2")
r += getCSSForPreferencesToHide(["numSwitches", "deviceTemplateInput"])
r += getCSSForPreferenceHiding('', overrideIndex=getPreferenceIndex('', returnMax=true) + 1)
r += getCSSForHidingLastPreference()
r += '''
form[action*="preference"]::before {
color: green;
content: "Hi, this is my content"
}
form[action*="preference"] div.mdl-grid div.mdl-cell:nth-of-type(2) {
color: green;
}
form[action*="preference"] div[for^=preferences] {
color: blue;
}
h3, h4, .property-label {
font-weight: bold;
}
'''
*/
String getDriverCSSWrapper() {
Map metaConfig = getMetaConfig()
boolean disableCSS = isCSSDisabled(metaConfig=metaConfig)
String defaultCSS = '''
/* This is part of the CSS for replacing a Command Title /
div.mdl-card__title div.mdl-grid div.mdl-grid .mdl-cell p::after {
visibility: visible;
position: absolute;
left: 50%;
transform: translate(-50%, 0%);
width: calc(100% - 20px);
padding-left: 5px;
padding-right: 5px;
margin-top: 0px;
}
/ This is general CSS Styling for the Driver page */
h3, h4, .property-label {
font-weight: bold;
}
.preference-title {
font-weight: bold;
}
.preference-description {
font-style: italic;
}
'''
String r = ""
if(disableCSS == false) {
r += "$defaultCSS "
try{
// We always need to hide this element when we use CSS
r += " ${getCSSForHidingLastPreference()} "
if(disableCSS == false) {
if(metaConfig.containsKey("hide")) {
if(metaConfig["hide"].containsKey("command")) {
r += getCSSForCommandsToHide(metaConfig["hide"]["command"])
}
if(metaConfig["hide"].containsKey("stateVariable")) {
r += getCSSForStateVariablesToHide(metaConfig["hide"]["stateVariable"])
}
if(metaConfig["hide"].containsKey("currentState")) {
r += getCSSForCurrentStatesToHide(metaConfig["hide"]["currentState"])
}
if(metaConfig["hide"].containsKey("data")) {
r += getCSSForDatasToHide(metaConfig["hide"]["data"])
}
if(metaConfig["hide"].containsKey("preference")) {
r += getCSSForPreferencesToHide(metaConfig["hide"]["preference"])
}
}
if(metaConfig.containsKey("stateComment")) {
r += "div#stateComment:after { content: \"${metaConfig["stateComment"]}\" }"
}
r += " ${getDriverCSS()} "
}
}catch(MissingMethodException e) {
if(!e.toString().contains("getDriverCSS()")) {
log.warn "getDriverCSS() Error: $e"
}
} catch(e) {
log.warn "getDriverCSS() Error: $e"
}
}
r += " </style>"
return r
}
Integer getCommandIndex(String cmd) {
List commands = device.getSupportedCommands().unique()
Integer i = commands.findIndexOf{ "$it" == cmd}+1
//log.debug "getCommandIndex: Seeing these commands: '${commands}', index=$i}"
return i
}
String getCSSForCommandHiding(String cmdToHide) {
Integer i = getCommandIndex(cmdToHide)
String r = ""
if(i > 0) {
r = "div.mdl-card__title div.mdl-grid div.mdl-grid .mdl-cell:nth-of-type($i){display: none;}"
}
return r
}
String getCSSForCommandsToHide(List commands) {
String r = ""
commands.each {
r += getCSSForCommandHiding(it)
}
return r
}
String getCSSToChangeCommandTitle(String cmd, String newTitle) {
Integer i = getCommandIndex(cmd)
String r = ""
if(i > 0) {
r += "div.mdl-card__title div.mdl-grid div.mdl-grid .mdl-cell:nth-of-type($i) p {visibility: hidden;}"
r += "div.mdl-card__title div.mdl-grid div.mdl-grid .mdl-cell:nth-of-type($i) p::after {content: '$newTitle';}"
}
return r
}
Integer getStateVariableIndex(String stateVariable) {
def stateVariables = state.keySet()
Integer i = stateVariables.findIndexOf{ "$it" == stateVariable}+1
//log.debug "getStateVariableIndex: Seeing these State Variables: '${stateVariables}', index=$i}"
return i
}
String getCSSForStateVariableHiding(String stateVariableToHide) {
Integer i = getStateVariableIndex(stateVariableToHide)
String r = ""
if(i > 0) {
r = "ul#statev li.property-value:nth-of-type($i){display: none;}"
}
return r
}
String getCSSForStateVariablesToHide(List stateVariables) {
String r = ""
stateVariables.each {
r += getCSSForStateVariableHiding(it)
}
return r
}
String getCSSForCurrentStatesToHide(List currentStates) {
String r = ""
currentStates.each {
r += "ul#cstate li#cstate-$it {display: none;}"
}
return r
}
Integer getDataIndex(String data) {
def datas = device.getData().keySet()
Integer i = datas.findIndexOf{ "$it" == data}+1
//log.debug "getDataIndex: Seeing these Data Keys: '${datas}', index=$i}"
return i
}
String getCSSForDataHiding(String dataToHide) {
Integer i = getDataIndex(dataToHide)
String r = ""
if(i > 0) {
r = "table.property-list tr li.property-value:nth-of-type($i) {display: none;}"
}
return r
}
String getCSSForDatasToHide(List datas) {
String r = ""
datas.each {
r += getCSSForDataHiding(it)
}
return r
}
Integer getPreferenceIndex(String preference, boolean returnMax=false) {
def filteredPrefs = getPreferences()['sections']['input'].name[0]
//log.debug "getPreferenceIndex: Seeing these Preferences first: '${filteredPrefs}'"
if(filteredPrefs == [] || filteredPrefs == null) {
d = getDataValue('preferences')
//log.debug "getPreferenceIndex: getDataValue('preferences'): '${d}'"
if(d != null && d.length() > 2) {
try{
filteredPrefs = d[1..d.length()-2].tokenize(',')
} catch(e) {
// Do nothing
}
}
}
Integer i = 0
if(returnMax == true) {
i = filteredPrefs.size()
} else {
i = filteredPrefs.findIndexOf{ "$it" == preference}+1
}
//log.debug "getPreferenceIndex: Seeing these Preferences: '${filteredPrefs}', index=$i"
return i
}
String getCSSForPreferenceHiding(String preferenceToHide, Integer overrideIndex=0) {
Integer i = 0
if(overrideIndex == 0) {
i = getPreferenceIndex(preferenceToHide)
} else {
i = overrideIndex
}
String r = ""
if(i > 0) {
r = "form[action*="preference"] div.mdl-grid div.mdl-cell:nth-of-type($i) {display: none;} "
}else if(i == -1) {
r = "form[action*="preference"] div.mdl-grid div.mdl-cell:nth-last-child(2) {display: none;} "
}
return r
}
String getCSSForPreferencesToHide(List preferences) {
String r = ""
preferences.each {
r += getCSSForPreferenceHiding(it)
}
return r
}
String getCSSForHidingLastPreference() {
return getCSSForPreferenceHiding(null, overrideIndex=-1)
}
/**
- --END-- DRIVER METADATA METHODS (helpers-driver-metadata)
*/
/**
- STYLING (helpers-styling)
-
- Helper functions included in all Drivers and Apps using Styling
*/
String addTitleDiv(title) {
return '' + title + '
'
}
String addDescriptionDiv(description) {
return '
' + description + '
'
}
String makeTextBold(s) {
// DEPRECATED: Should be replaced by CSS styling!
if(isDriver()) {
return "$s"
} else {
return "$s"
}
}
String makeTextItalic(s) {
// DEPRECATED: Should be replaced by CSS styling!
if(isDriver()) {
return "$s"
} else {
return "$s"
}
}
String getDefaultCSS(boolean includeTags=true) {
String defaultCSS = '''
/* This is part of the CSS for replacing a Command Title /
div.mdl-card__title div.mdl-grid div.mdl-grid .mdl-cell p::after {
visibility: visible;
position: absolute;
left: 50%;
transform: translate(-50%, 0%);
width: calc(100% - 20px);
padding-left: 5px;
padding-right: 5px;
margin-top: 0px;
}
/ This is general CSS Styling for the Driver page */
h3, h4, .property-label {
font-weight: bold;
}
.preference-title {
font-weight: bold;
}
.preference-description {
font-style: italic;
}
'''
if(includeTags == true) {
return "$defaultCSS "
} else {
return defaultCSS
}
}
/**
- --END-- STYLING METHODS (helpers-styling)
*/
// BEGIN:getLoggingFunction(specialDebugLevel=True)
/* Logging function included in all drivers */
private boolean logging(message, level) {
boolean didLogging = false
Integer logLevelLocal = (logLevel != null ? logLevel.toInteger() : 0)
//if(!isDeveloperHub()) {
logLevelLocal = 0
if (infoLogging == true) {
logLevelLocal = 100
}
if (debugLogging == true) {
logLevelLocal = 1
}
//}
if (logLevelLocal != 0){
switch (logLevelLocal) {
case -1: // Insanely verbose
if (level >= 0 && level < 100) {
log.debug "$message"
didLogging = true
} else if (level == 100) {
log.info "$message"
didLogging = true
}
break
case 1: // Very verbose
if (level >= 1 && level < 99) {
log.debug "$message"
didLogging = true
} else if (level == 100) {
log.info "$message"
didLogging = true
}
break
case 10: // A little less
if (level >= 10 && level < 99) {
log.debug "$message"
didLogging = true
} else if (level == 100) {
log.info "$message"
didLogging = true
}
break
case 50: // Rather chatty
if (level >= 50 ) {
log.debug "$message"
didLogging = true
}
break
case 99: // Only parsing reports
if (level >= 99 ) {
log.debug "$message"
didLogging = true
}
break
case 100: // Only special debug messages, eg IR and RF codes
if (level == 100 ) {
log.info "$message"
didLogging = true
}
break
}
}
return didLogging
}
// END: getLoggingFunction(specialDebugLevel=True)