This page last changed on May 24, 2013 by juha.

Lawrie writes:

For example, if I want to send an email or text from a rule, can I do that in OpenRemote?

Sending emails (and texts, or posting tweets, or facebook updates, etc. etc.) is a fairly common functionality request. At this point, the rules engine allows a function definition (corresponding roughly to Java's static method) and pretty much an arbitrary implementation there. From Drools documentation:

Functions are a way to put semantic code in your rule source file, as opposed to in normal Java classes. They can't do anything more than what you can do with helper classes. (In fact, the compiler generates the helper class for you behind the scenes.) The main advantage of using functions in a rule is that you can keep the logic all in one place, and you can change the functions as needed (which can be a good or a bad thing). Functions are most useful for invoking actions on the consequence (then) part of a rule, especially if that particular action is used over and over again, perhaps with only differing parameters for each rule.

A typical function declaration looks like:

function String hello(String name) {
    return "Hello "+name+"!";
}

Note that the function keyword is used, even though its not really part of Java. Parameters to the function are defined as for a method, and you don't have to have parameters if they are not needed. The return type is defined just like in a regular method.

Alternatively, you could use a static method in a helper class, e.g., Foo.hello(). Drools supports the use of function imports, so all you would need to do is:

import function my.package.Foo.hello

Irrespective of the way the function is defined or imported, you use a function by calling it by its name, in the consequence or inside a semantic code block. Example:

rule "using a static function"
when 
    eval( true )
then
    System.out.println( hello( "Bob" ) );
end

An idea I've been thinking about around this is to provide users generic code templates they can use from within the rules that hides some of the lower level details such as Java Mail API that is required to send emails. Reason being that for many users programming tasks are outside their comfort zone and error-prone.

This idea follows the current implementation with regards to how the commands are executed: we create a Java template class (a facade in other terms) that manages the details of command execution. This is handled in the rule by importing a 'global' variable which you can find in all our rule examples:

global org.openremote.controller.statuscache.CommandFacade execute;
global org.openremote.controller.statuscache.SwitchFacade switches;

(See Designer 2.0 - Controller Rules)

Now if you look at the actual implementation of the Command facade, it creates an API. A side note, not necessary to follow standard Java naming conventions in these facades since standard naming conventions may be obscure to users and lead to errors in rule definitions: CommandFacade.java

So therefore, the statement in rule:

global org.openremote.controller.statuscache.CommandFacade execute;

And a rule action definition:

then

  execute.command( "Music_On" );

end

is roughly equivalent to Java code:

new CommandFacade(namedCommands).command( "Music_On" );

It comes down to mapping magic and how we expose internals to the user in the most attractive way.


Now, for your specific question such as sending an email or text, I could foresee a definition of:

  • EmailFacade
  • SMSFacade

Where for example emails from rules are sent using a global variable 'email':

global org.openremote.controller.rules.EmailFacade email;

Where the EmailFacade.java defines a method send(String sender, String recipient, String topic, String content, ...)

Which then translates to a rule action such as:

then

  email.send( mailto:bob@house.com, mailto:bob@work.com, "Hello", "Your house is on fire!" );

end

Adopt to SMS accordingly:

global org.openremote.controller.rules.SMSFacade sms;

...

then

  sms.send( "Hello", "Your house is on fire!" );

end

If you get the gist of the idea above, I'd like to start fleshing it out further in terms of defining the API, documenting for users, etc.

There's an additional consideration of SMS or email as a protocol (where it can be triggered directly from the UI) vs the implementation facade for rules. If both the protocol and the rule facade is created, the implementation between the two should naturally be shared.

On configuration side the difference becomes in parameterizing the use of the method call. In case of commands, the user will need to create a command in the GUI where he fills in the parameters (sender, recipient, title, content, etc.) and the rule action becomes simply:

global org.openremote.controller.statuscache.CommandFacade execute;

...

then

  execute.command( "Send My Email" );

end

vs. the parameterized facade API that was shown above. The command seems preferred when both user triggered and device event triggered emails are used in the same configuration since it will then share the single location for the configuration in a 'command'.

The facade helps in convenience for those users who are comfortable writing their own rules and if the same sending functionality is not needed elsewhere in the design – it is quick to write in the rule definition (using a facade) without requiring any command configurations or GUI interaction.

Thoughts?

Lawrie writes:

I like the facades idea. Should we do FreeTTS like this, at least as an option, as the main use of text to speech is likely to be in rules.

We could have something like:

freetts.say("The house is on fire");

and also maybe:

freetts.say("musicserver",50000,"The house is on fire");

to use a remote TCP/IP server.

Lawrie

Think that would work. Although I probably wouldn't use freetts as the variable name (again just from the perspective of trying to sound least obscure as possible), instead using something like text-to-speech.say() if dashes are allowed (no clue), text2speech.say() or similar.

Makes it a little more readable in my eyes (but in the end the global variable name can be decided by the user writing the rule anyway, so this would be mainly just for documentation and example code purposes – people tend to adopt whatever conventions you show them in documentation).

Posted by juha at May 24, 2013 19:06

I have code in my HouseControl project that sends email using javax.mail and Google mail. Would you like me to contribute an Email protocol as a start towards the email case?

Posted by lawrie at May 25, 2013 15:35

Sounds good!

Posted by juha at May 25, 2013 16:33

Hi lawrie,

I'm looking for a way to send an email notification to a specified address. It would be really great if you can share the code/ how to with us.

Thanks in advance,

D1.

Posted by d1_sen at May 26, 2013 14:42

How do you want to send the notification. Is it from a rule?

Posted by lawrie at May 26, 2013 14:54

Yes Lawrie, I want to send a notification from a rule. For example if a presence detector is triggered I want it to send me an alert.

Posted by d1_sen at May 26, 2013 15:12

A quick and dirty method would be to define a Shell protocol command sending an e-mail and call it from the rule.

Of course method proposed by Juha would me much prettier but you would need to wait for a new code release.

Posted by aktur at May 26, 2013 15:19

Hi Michal,

My java knowledge is almost zero, I've been able to do what I have done so far using examples from here and there. If you can provide me with a simple example on how to go about it, it would be a great help

Thanks.

Posted by d1_sen at May 26, 2013 16:06

Hi Juha, Could you add this XML for the email protocol to the staging server if it looks OK. I probably need to add a regex for email validation. I have the email protocol working but not checked in yet, as I need to add a properties file to make it configurable.

<?xml version="1.0" encoding="UTF-8"?>

<!--

 OpenRemote, the Home of the Digital Home.
 Copyright 2008-2013, OpenRemote Inc.

 See the contributors.txt file in the distribution for a
 full listing of individual contributors.

 This is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as
 published by the Free Software Foundation; either version 3.0 of
 the License, or (at your option) any later version.

 This software is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 You should have received a copy of the GNU General Public
 License along with this software; if not, write to the Free
 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 02110-1301 USA, or see the FSF site: http://www.fsf.org.

-->

<!--
 |  Email protocol configuration for OpenRemote Designer.
 |
 |  Author: Lawrie Griffiths
 +-->
<openremote xmlns="http://www.openremote.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.openremote.org protocol.xsd">
	<protocol displayName="Email" tagName="email">
		<attr name="recipient" label="Recipient">
			<validations>
				<allowBlank>false</allowBlank>
			</validations>
		</attr>
		<attr name="subject" label="Subject">
			<validations>
				<allowBlank>false</allowBlank>
			</validations>
		</attr>
		<attr name="message" label="Message">
			<validations>
				<allowBlank>false</allowBlank>
			</validations>
		</attr>
	</protocol>
</openremote>
Posted by lawrie at May 26, 2013 16:25

Done.

Posted by juha at May 26, 2013 17:09

No Java needed, he means using this: OpenRemote 2.0 How To - Execute Shell commands

If you have an external command or script that can send email then you can create a rule like this:

package org.openremote.controller.protocol

global org.openremote.controller.statuscache.CommandFacade execute;
global org.openremote.controller.statuscache.SwitchFacade switches;

rule "Send My Email" when

  Event( source == "My Sensor", value == "on" )

then

  execute.command( "The name of the shell execution command I created in Designer" );

end

HTH

Posted by juha at May 26, 2013 17:13
Document generated by Confluence on Jun 05, 2016 09:30