Script nodes question

  • 72 Views
  • Last Post 10 December 2013
SickPup404 posted this 06 December 2013

Awesome! Thanks for the link.

I'm setting up a simple script to check the battery level of the Multi-Sensors and send a mail when the batteries are low. I can just put them in the scene and use sceneDevices. Sweet!

Order By: Standard | Newest | Votes
Ryan-Scott posted this 06 December 2013

In the scripts, it uses the following to get nodes (devices?) to operate on:

[code]// Get all devices supplied in NodeIds rule data
var devices = getNodes(targetNodes);[/code]

Where do they come from?? I thought they would come from the device list in the scene.

Boy what I would give for some IntelliSense/AutoComplete data to try to get moving on the scripts! :D


IntelliSense would be way cool. Any volunteers for implementing it?

Check out our Github reference on scripts - it's not complete, but it does cover that part.

SickPup404 posted this 06 December 2013

Awesome! Thanks for the link.

I'm setting up a simple script to check the battery level of the Multi-Sensors and send a mail when the batteries are low. I can just put them in the scene and use sceneDevices. Sweet!

SickPup404 posted this 06 December 2013

Well, I think I have the script working, but still have a small issue.

When the script runs, I get a "Object reference not set to an instance of an object." message in LogFile.txt.

I get the email in my inbox with everything I'm expecting, just can't see what my error is... Any ideas?

The script:
[code]
[i]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MLS.ZWave.Service.Rules;
using MLS.ZWave.BusinessObjects;
using MLS.HA.DeviceController.Common.Device.ZWave;

///


/// This script will send an email when battery powered devices in the scene device list report battery level <=>
///


public class BatteryMonitor : ScriptBase, ScriptInterface {

public void runScript() {
try {
bool sendMailNeeded = false;
var subject = "Battery level alert";
var bodyLine = "Device '{0}' reports battery level of {1}%.
";
var body = "";

foreach (var sd in base.sceneDevices) {
var device = getNode((Guid)sd.deviceId);
if (device.level <= 100)="" {=""><===battery reporting="" percent="" here.="" 100="" for="">
sendMailNeeded = true;
body = body + string.Format(bodyLine, device.deviceName, device.level);
}
}

if (sendMailNeeded) {
sendEmail(string.Format(subject), string.Format(body));
}

} catch (Exception ex) {
// Log the exception here
var message = ex.Message;
writeLog(message);
}
}
}[/i]
[/code]

Ryan-Scott posted this 10 December 2013


The script:
[code]
[i]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MLS.ZWave.Service.Rules;
using MLS.ZWave.BusinessObjects;
using MLS.HA.DeviceController.Common.Device.ZWave;

///
/// This script will send an email when battery powered devices in the scene device list report battery level <=>
///


public class BatteryMonitor : ScriptBase, ScriptInterface {

public void runScript() {
try {
bool sendMailNeeded = false;
var subject = "Battery level alert";
var bodyLine = "Device '{0}' reports battery level of {1}%.
";
var body = "";

foreach (var sd in base.sceneDevices) {
var device = getNode((Guid)sd.deviceId);
if (device.level <= 100)="" {=""><===battery reporting="" percent="" here.="" 100="" for="">
sendMailNeeded = true;
body = body + string.Format(bodyLine, device.deviceName, device.level);
}
}

if (sendMailNeeded) {
sendEmail(string.Format(subject), string.Format(body));
}

} catch (Exception ex) {
// Log the exception here
var message = ex.Message;
writeLog(message);
}
}
}[/i]
[/code]


Does the log message include a stack trace with any line numbers by chance? If you still get the email OK, it's possible this script isn't the problem... there's not much code running after the email goes out, so there's not really anything that can crash.

If I had to guess though... I'd assume that device is null. You could add a check here:

[code]
// Before the for-each loop, make sure sceneDevices is not null
if (base.sceneDevices == null) {
return;
}

...

// Inside the for loop loop, do a check to make sure the device isn't null
if (device != null && device.level <= 100)="" {="">
....
}
[/code]

SickPup404 posted this 10 December 2013

Ran the existing script again and only got:
[code]12/10/2013 12:42:29 PM: SceneTrigger Daily Maintenance: Object reference not set to an instance of an object.
[/code]

The scene is set up in the "Pre-script" box and has the two motion sensor battery level devices in the device list.

Made your suggested changes and got the same result. Like I said, purely cosmetic at this point. Desired results of the battery report are coming in email for all the devices in the list. No worries!

(For reference, the current changed code):
[code]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MLS.ZWave.Service.Rules;
using MLS.ZWave.BusinessObjects;
using MLS.HA.DeviceController.Common.Device.ZWave;

///


/// This script will send an email when battery powered devices in the scene device list report battery level <=>
///


public class BatteryMonitor : ScriptBase, ScriptInterface {

public void runScript() {
try {
bool sendMailNeeded = false;
var subject = "Battery level alert";
var bodyLine = "Device '{0}' reports battery level of {1}%.
";
var body = "";

// Before the for-each loop, make sure sceneDevices is not null
if (base.sceneDevices == null) {
return;
}

foreach (var sd in base.sceneDevices) {
var device = getNode((Guid)sd.deviceId);
if (device != null && device.level <= 100)="" {=""><===battery reporting="" percent="" here.="" 100="" for="">
sendMailNeeded = true;
body = body + string.Format(bodyLine, device.deviceName, device.level);
}
}

if (sendMailNeeded) {
sendEmail(string.Format(subject), string.Format(body));
}

} catch (Exception ex) {
// Log the exception here
var message = ex.Message;
writeLog(message);
}
}
}[/code]

SickPup404 posted this 10 December 2013

Did some more debugging.

Looks like I'm either calling sendEmail with wrong/bad properties or there might be a bug in it.

Looks like you can call it via:
- sendEmail(string, string) passing Subject and Body
- sendEmail(string, string, string) passing To: address, Subject, and Body
- sendEmail(string, string, list) passing Subject, Body, and attachments
- sendEmail(string, string, string, list) passing To: address, Subject, Body, and attachments

Calling the method with:
sendEmail("Blah", "Blah");
generates the null reference.

HTH!

Close