I am receiving the below error when trying to compile the device_handler code for the Sylvania Smart+ Plug. The code comes from https://images-na.ssl-images-amazon.com/images/I/71PrgM-PamL.pdf
The error:
Org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: script_dth_metadata_0631e407_ffd8_4ceb_b49a_877fd47635df: 94: expecting ''', found '\r' # line 94, column 55. nalResult.value == "on" ? '{{ ^ 1 error
Line 94:
def descriptionText = finalResult.value == "on" ? '{{
metadata {
definition (name: "SYLVANIA Smart Plug", namespace: "ledvanceDH", author:
"Ledvance") {
capability "Actuator"
capability "Switch"
capability "Power Meter"
capability "Configuration"
capability "Refresh"
capability "Sensor"
capability "Health Check"
fingerprint profileId: "C05E", inClusters:
"1000,0000,0003,0004,0005,0006,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM",
model: "Plug 01", deviceJoinName: "SYLVANIA Smart Plug"
fingerprint profileId: "0104", inClusters:
"0000,0003,0004,0005,0006,0B05,FC01,FC08", outClusters: "0003,0019", manufacturer:
"LEDVACE", model: "PLUG", deviceJoinName: "SYLVANIA Smart Plug"
}
// simulator metadata
simulator {
// status messages
status "on": "on/off: 1"
status "off": "on/off: 0"
// reply messages
reply "zcl on-off on": "on/off: 1"
reply "zcl on-off off": "on/off: 0"
}
preferences {
section {
image(name: 'educationalcontent', multiple: true, images: [
"http://cdn.devicegse.smartthings.com/Outlet/US/OutletUS1.jpg",
"http://cdn.devicegse.smartthings.com/Outlet/US/OutletUS2.jpg"
])
}
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4,
canChangeIcon: true){
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
attributeState "on", label: 'On', action: "switch.off",
icon: "st.Appliances.appliances17", backgroundColor: "#79b821", nextState: "turningOff"
attributeState "off", label: 'Off', action: "switch.on",
icon: "st.Appliances.appliances17", backgroundColor: "#565C51", nextState: "turningOn"
attributeState "turningOn", label: 'Turning On', action:
"switch.off", icon: "st.Appliances.appliances17", backgroundColor: "#60903A", nextState:
"turningOff"
attributeState "turningOff", label: 'Turning Off', action:
"switch.on", icon: "st.Appliances.appliances17", backgroundColor: "#CACACA", nextState:
"turningOn"
}
tileAttribute ("power", key: "SECONDARY_CONTROL") {
attributeState "power", label:'${currentValue} W'
}
}
standardTile("refresh", "device.power", inactiveLabel: false, decoration:
"flat", width: 2, height: 2) {
state "default", label:'', action:"refresh.refresh",
icon:"st.secondary.refresh"
}
main "switch"
details(["switch","refresh"])
}
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
def finalResult = zigbee.getKnownDescription(description)
def event = [:]
//TODO: Remove this after getKnownDescription can parse it automatically
if (!finalResult && description!="updated")
finalResult =
getPowerDescription(zigbee.parseDescriptionAsMap(description))
if (finalResult) {
log.info "final result = $finalResult"
if (finalResult.type == "update") {
log.info "$device updates: ${finalResult.value}"
event = null
}
else if (finalResult.type == "power") {
def powerValue = (finalResult.value as Integer)/10
event = createEvent(name: "power", value: powerValue,
descriptionText: '{{ device.displayName }} power is {{ value }} Watts', translatable:
true)
/*
Dividing by 10 as the Divisor is 10000 and unit is kW for
the device. AttrId: 0302 and 0300. Simplifying to 10
power level is an integer. The exact power level with
correct units needs to be handled in the device type
to account for the different Divisor value (AttrId: 0302)
and POWER Unit (AttrId: 0300). CLUSTER for simple metering is 0702
*/
}
else {
def descriptionText = finalResult.value == "on" ? '{{
device.displayName }} is On' : '{{ device.displayName }} is Off'
event = createEvent(name: finalResult.type, value:
finalResult.value, descriptionText: descriptionText, translatable: true)
}
}
else {
def cluster = zigbee.parse(description)
if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07){
if (cluster.data[0] == 0x00) {
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
event = createEvent(name: "checkInterval", value: 60 * 12,
displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}
else {
log.warn "ON/OFF REPORTING CONFIG FAILED- error
code:${cluster.data[0]}"
event = null
}
}
else {
log.warn "DID NOT PARSE MESSAGE for description : $description"
log.debug "${cluster}"
}
}
return event
}
def off() {
zigbee.off()
}
def on() {
zigbee.on()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
return zigbee.onOffRefresh()
}
def refresh() {
zigbee.onOffRefresh() + zigbee.electricMeasurementPowerRefresh()
}
def configure() {
// Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
// enrolls with default periodic reporting until newer 5 min interval is confirmed
sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false,
data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
// OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no
activity
refresh() + zigbee.onOffConfig(0, 300) + powerConfig()
}
//power config for devices with min reporting interval as 1 seconds and reporting
interval if no activity as 10min (600s)
//min change in value is 01
def powerConfig() {
[
"zdo bind 0x${device.deviceNetworkId} 1 ${endpointId} 0x0B04
{${device.zigbeeId}} {}", "delay 2000",
"zcl global send-me-a-report 0x0B04 0x050B 0x29 1 600 {05 00}",
//The send-me-a-report is custom to the attribute type for CentraLite
"delay 200",
"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 2000"
]
}
private getEndpointId() {
new BigInteger(device.endpointId, 16).toString()
}
//TODO: Remove this after getKnownDescription can parse it automatically
def getPowerDescription(descMap) {
def powerValue = "undefined"
if (descMap.cluster == "0B04") {
if (descMap.attrId == "050b") {
if(descMap.value!="ffff")
powerValue = zigbee.convertHexToInt(descMap.value)
}
}
else if (descMap.clusterId == "0B04") {
if(descMap.command=="07"){
return [type: "update", value : "power (0B04) capability configured
successfully"]
}
}
if (powerValue != "undefined"){
return [type: "power", value : powerValue]
}
else {
return [:]
}
}
I should have thought of it sooner... The problem is with the copy/paste. The long lines were broken by a "return". I removed the returns and the script compiled.
in a working jest + puppeteer project,
i'm moving to jest-circus in order to use the jest-circus retry feature.
As documented, i installed jest-circus and i set as runner but running test as usual i obtain
Validation Error:
Preset jest-puppeteer is invalid:
The "id" argument must be of type string. Received type object
TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received type object
at validateString (internal/validators.js:112:11)
at Module.require (internal/modules/cjs/loader.js:842:3)
at require (internal/modules/cjs/helpers.js:74:18)
at setupPreset (C:\src\qa-e2e-update-stack\node_modules\jest-config\build\normalize.js:348:14)
at normalize (C:\src\qa-e2e-update-stack\node_modules\jest-config\build\normalize.js:703:15)
at readConfig (C:\src\qa-e2e-update-stack\node_modules\jest-config\build\index.js:220:68)
at async readConfigs (C:\src\qa-e2e-update-stack\node_modules\jest-config\build\index.js:401:26)
at async runCLI (C:\src\qa-e2e-update-stack\node_modules\#jest\core\build\cli\index.js:203:59)
at async Object.run (C:\src\qa-e2e-update-stack\node_modules\jest\node_modules\jest-cli\build\cli\index.js:216:37)
Configuration Documentation:
https://jestjs.io/docs/configuration.html
this is my jest.config.js file
const fs = require('fs')
reportFolder = "reports"
if (!fs.existsSync(reportFolder)){
fs.mkdirSync(reportFolder)
}
module.exports = {
preset: "jest-puppeteer",
testRunner: "jest-circus/runner",
setupFilesAfterEnv: [ // NOT setupFiles
"./configurazioni/custom-configuration.js",
"./configurazioni/shared-require.js",
"jest-allure/dist/setup"
],
"reporters": [
"default",
["./node_modules/jest-html-reporter", {
"pageTitle": "Test Report",
"includeFailureMsg": true,
"includeConsoleLog": true,
"outputPath":"reports/"+new Date().getDate() + "-" +
(new Date().getMonth() + 1) + "-"
+ new Date().getFullYear()+ "-"
+ new Date().getHours().toString() + "-"
+ (new Date().getMinutes() + 1 ).toString() + "-"
+ (new Date().getSeconds() + 1 ).toString()
+"-run.html"
}],
["jest-junit", { outputName: "reports/junitreport.xml" }]
],
moduleNameMapper: {
'^\\$lib\/(.*)': `<rootDir>/lib/$1`,
},
};
i don't found any page talking about my issue, jest-circus and jest-preset cannot coexists?
I've got such error when rootDir was set incorrectly in jest config file.
I would suggest to check whether your node packages are properly installed. I encountered the very same issue when my node_modules folder got deleted.
Latest Jenkins used.
edit: pastebin of full Java exception - https://pastebin.com/zZDNj18E
Goal: loop through all nodes, check for offline, email alert for each offline node.
(tried emailext alerts as well, could not use "offline")
Failed: My jenkinsfile runs perfectly with no email.
With email in the for loop or separately defined in a function, the job crashes after the first email is sent.
[Pipeline] End of Pipeline an exception which occurred: in field hudson.model.Slave.launcher in object hudson.slaves.DumbSlave#ae938e61 .... and many more
My jenkinsfile:
pipeline {
agent{
label 'master'
}
options {
// Enable timestamps in log
timestamps()
skipDefaultCheckout()
timeout(time: 4, unit: 'MINUTES')
}
stages {
stage('Monitor') {
steps{
script{
def offlineSlaves = []
for (aSlave in hudson.model.Hudson.instance.slaves) {
def thisSlave = aSlave.name
echo 'Name: ' + thisSlave + ' is being checked.'
if ( aSlave.getComputer().isOffline().toString() == 'true') {
slaveState = 'OFFLINE'
echo 'Name: ' + thisSlave + ' is ' + slaveState + ' !'
emailext (
mimeType: 'text/html',
body: "${env.JOB_NAME} found an OFFLINE node: ${name} ",
subject: "Jenkins ERROR: Build Node ${name} is OFFLINE " ,
to: 'jfisher#xxx')
}
}
}
}
}
}
post {
failure {
emailext (
body: 'Monitor Nodes Jenkins Job failed !',
presendScript: '$DEFAULT_PRESEND_SCRIPT',
recipientProviders: [requestor(),culprits()],
subject: 'Monitor Nodes Jenkins Failed',
to: 'jfisher#intouchhealth.com')
}
}
}
The problem with this code is the getComputer() part. In the pipeline you should only use Serializable and the SlaveComputer returned from getComputer() isn't.
https://javadoc.jenkins.io/hudson/slaves/SlaveComputer.html
What you should do is move this part to a function annotated with NonCPS
#NonCPS
def shallTrigger() {
for (aSlave in hudson.model.Hudson.instance.slaves) {
def thisSlave = aSlave.name
echo 'Name: ' + thisSlave + ' is being checked.'
if ( aSlave.getComputer().isOffline().toString() == 'true') {
slaveState = 'OFFLINE'
echo 'Name: ' + thisSlave + ' is ' + slaveState + ' !'
emailext (
mimeType: 'text/html',
body: "${env.JOB_NAME} found an OFFLINE node: ${name} ",
subject: "Jenkins ERROR: Build Node ${name} is OFFLINE " ,
to: 'jfisher#xxx')
}
}
}
I'm trying to use Watson Classifier from node. I've started by implementing the example in the API reference, found at https://www.ibm.com/watson/developercloud/natural-language-classifier/api/v1/node.html?node#create-classifier
My code (sensitive information replaced with stars):
58 create: function(args, cb) {
59 var params = {
60 metadata: {
61 language: 'en',
62 name: '*********************'
63 },
64 training_data: fs.createReadStream(config.data.prepared.training)
65 };
66
67 params.training_data.on("readable", function () {
68 nlc.createClassifier(params, function(err, response) {
69 if (err)
70 return cb(err);
71 console.log(JSON.stringify(response, null, 2));
72 cb();
73 });
74 });
75 },
The file I am trying to make a stream from exists. The stream works (I've managed to read from it on "readable"). I've placed the on("readable") part because it made sense for me to do all of this once the stream becomes available, and also because I wanted to be able to check that I can read from it. It does not change the outcome, however.
nlc is the natural_langauge_classifier instance.
I'm getting this:
octav#****************:~/watsonnlu$ node nlc.js create
/home/octav/watsonnlu/node_modules/delayed-stream/lib/delayed_stream.js:33
source.on('error', function() {});
^
TypeError: source.on is not a function
at Function.DelayedStream.create (/home/octav/watsonnlu/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
at FormData.CombinedStream.append (/home/octav/watsonnlu/node_modules/combined-stream/lib/combined_stream.js:44:37)
at FormData.append (/home/octav/watsonnlu/node_modules/form-data/lib/form_data.js:74:3)
at appendFormValue (/home/octav/watsonnlu/node_modules/request/request.js:321:21)
at Request.init (/home/octav/watsonnlu/node_modules/request/request.js:334:11)
at new Request (/home/octav/watsonnlu/node_modules/request/request.js:128:8)
at request (/home/octav/watsonnlu/node_modules/request/index.js:53:10)
at Object.createRequest (/home/octav/watsonnlu/node_modules/watson-developer-cloud/lib/requestwrapper.js:208:12)
at NaturalLanguageClassifierV1.createClassifier (/home/octav/watsonnlu/node_modules/watson-developer-cloud/natural-language-classifier/v1-generated.js:143:33)
at ReadStream.<anonymous> (/home/octav/watsonnlu/nlc.js:68:8)
I tried debugging it myself for a while, but I'm not sure what this source is actually supposed to be. It's just an object composed of the metadata I put in and the "emit" function if I print it before the offending line in delayed-stream.js.
{ language: 'en',
name: '*******************',
emit: [Function] }
This is my package.json file:
1 {
2 "name": "watsonnlu",
3 "version": "0.0.1",
4 "dependencies": {
5 "csv-parse": "2.0.0",
6 "watson-developer-cloud": "3.2.1"
7 }
8 }
Any ideas how to make the example work?
Cheers!
Octav
I got the answer in the meantime thanks to the good people at IBM. It seems you have to send the metadata as a stringified JSON:
59 var params = {
60 metadata: JSON.stringify({
61 language: 'en',
62 name: '*********************'
63 }),
64 training_data: fs.createReadStream(config.data.prepared.training)
65 };
I'm using the the NoUiSlider 7 (jQuery Version) and i want a callback function if the User types a value below min value.
$('#slider').noUiSlider({
start: 100,
step: 10,
range: {
'min': Number(range[0]),
'max': Number(range[1])
},
serialization: {
lower: [
$.Link({
target: $('#ausgabe_klassisch_betrag')
})
],
format: {
thousand: '.',
postfix: ' E',
mark: ',',
decimals:0
}
}
});
So i tried to slice the value (because i use 2 characters postfix) and if the value is below then alert:
$("#slider_klassisch_betrag").on({
change: function(){
$val = $("#slider_klassisch_betrag").val().slice(0,-1);
if($val < 30 ){ alert(); }
}
});
But this does not work. the change only works if the slider changes and not with change by the input field