[SOLVED] First stab at Jython

The script gives this error when executed.

NameError: global name 'IsItDark' is not defined

Know how you see [ | ] in rules DSL a lot? Usually when creating Timers or in forEach statements? Those are lambdas, a function that you can pass to another function where it gets called.

In this case you are creating a lambda that calls events.sendCommand. if you have more than one thing you need to do when the timer expires, you will need to create a new function and create a lambda that calls your function.

Now that I look at it, you need to save the Timer to a going variable and reschedule it if it already exists.

1 Like

Unfortunately, no :frowning_face:

Oops… forgot the quotes…

events.sendCommand("IsItDark", “ON” if “set” in str(event.channel).split(":") else “OFF”)

I didn’t see your Items, so I made some guesses. This should be everything you’d need to setup area triggers and actions. Grab the latest Mode (Time of Day), since I fixed a bug related to the use of Channels.

In your Item file(s) add the following…

Group                          gArea_Trigger            "Area Triggers"                <presence>
    Group:Switch:OR(ON,OFF)        gPapillon_Trigger        "Papillon Trigger [%s]"        <presence>    (gArea_Trigger)
    Group:Switch:OR(ON,OFF)        gBasement_Trigger        "Basement Trigger [%s]"        <presence>    (gArea_Trigger)
    Group:Switch:OR(ON,OFF)        gOutside_Trigger         "Outside Trigger [%s]"         <presence>    (gArea_Trigger)
Group	                       gArea_Action             "Area Actions" 	               <presence>
    Group                          gPapillon_Action         "Papillon Action"              <presence>    (gArea_Action)
    Group                          gBasement_Action         "Basement Action"              <presence>    (gArea_Action)
    Group                          gOutside_Action          "Outside Action"               <presence>    (gArea_Action)

Switch    papillon_motion      "Papillon Motion [%s]"      <motion>	   (gPapillon_Trigger)    {channel="zwave:device:55555:node2:sensor_binary"}
Switch    papillon_light       "Papillon Light [%s]"       <switch>	   (gPapillon_Action)     {channel="zwave:device:55555:node3:switch_binary"}

Switch    basement_motion_1    "Basement Motion 1 [%s]"    <motion>	   (gBasement_Trigger)    {channel="zwave:device:55555:node4:sensor_binary"}
Switch    basement_motion_2    "Basement Motion 2 [%s]"    <motion>	   (gBasement_Trigger)    {channel="zwave:device:55555:node5:sensor_binary"}
Switch    basement_light       "Basement Light [%s]"       <switch>	   (gBasement_Action)     {channel="zwave:device:55555:node6:switch_binary"}

Switch    outside_trigger      "Outside Trigger [%s]"      <switch>	   (gOutside_Trigger)
Switch    christmas_lights     "Christmas Lights [%s]"     <switch>	   (gOutside_Action)     {channel="zwave:device:55555:node7:switch_binary"}

Create an /automation/jsr223/python/personal/metadata.py script and add the following to it. You can let this run after every startup, but it’s a little cleaner to just comment everything out.

from core.metadata import set_metadata

set_metadata("papillon_light", "area_triggers_and_actions", {
        "modes": {
            "Morning": {"brightness": 98},
            "Day":     {"brightness": 0},# if there is motion during Day mode, the light will not turn on
            "Evening": {"brightness": 98},
            "Night":   {"brightness": 98}
        },
        "actions": {
            "light_action": {"OFF": {"delay": 300}}# the turning off of the light will be delayed by 5 minutes
        }
    }, overwrite=True)

set_metadata("basement_light", "area_triggers_and_actions", {# there is no modes metadata, so the default values in configuration.area_triggers_and_actions_dict will be used
        "actions": {
            "light_action": {"OFF": {"delay": 120}}
        }
    }, overwrite=True)

set_metadata("christmas_lights", "area_triggers_and_actions", {
        "modes": {
            "Morning": {"brightness": 98},
            "Day":     {"brightness": 0},
            "Evening": {"brightness": 98}
            "Night":   {"brightness": 0}
        }
    }, overwrite=True)

Use these In configuration.mode_dict…

mode_dict = OrderedDict([
    ("Morning", {"hour": 5,  "minute": 45,  "second": 0}),
    ("Day",     {"channel": "astro:sun:local:rise#event", "event": "START"}),
    ("Evening", {"channel": "astro:sun:local:set#event", "event": "START"}),
    ("Night"  , {"hour": 21, "minute": 30,  "second": 0})
])

You will need to turn on/off your outside_light Item to trigger the Christmas lights, so you might want to add it to a sitemap.

3 Likes

I just got to work this morning. I will look at this later.

Pull up just about any Design Pattern post. Or search the forum for “createTimer” or “forEach”. Also look at Reusable Functions: A simple lambda example with copious notes.

1 Like

OK, at sunset it just switched OFF :frowning:

2019-10-22 18:30:00.003 [vent.ChannelTriggeredEvent] - astro:sun:local:set#event triggered START

2019-10-22 18:30:00.004 [.event.RuleStatusInfoEvent] - 77bc6078-84c0-4bb9-8ce8-b6b2443bb0e6 updated: RUNNING

2019-10-22 18:30:00.010 [ome.event.ItemCommandEvent] - Item 'IsItDark' received command OFF

2019-10-22 18:30:00.011 [.event.RuleStatusInfoEvent] - 77bc6078-84c0-4bb9-8ce8-b6b2443bb0e6 updated: IDLE
1 Like

Just setting it to ON would not work?

In case you are wondering, the times for Morning & Night were determined by a little trial & error and would vary by location.Morning is always before Sunrise in my location & Night is always after Sunset…

Yeah… I was meaning you’d need to manually toggle the switch rather than an automation controlling it.

Did you try out area triggers?!

I am configuring them ( and found a missing comma too.) .
Mode has come up as NIGHT instead of EVENING. I figure it might sort itself out since I started it after sunset but before the NIGHT time.

So far, I am configuring the system without many of the channel links until I get the automation working. I will then move the devices to this new controller.

Instead of

Switch    outside_trigger      "Outside Trigger [%s]"      <switch>	   (gOutside_Trigger)

Wouldn’t this work?

Group:Switch:EQUALITY(ON)  outside_trigger      "Outside Trigger [%s]"      <switch>	   (gOutside_Trigger)

Maybe as a piece, but on it’s own, no. You’d need an Item in the group or you’d need to send the group an update. But why?

Wouldn’t it be always on?

Depends on the members… but if you create members, then just use the Item

I misunderstand EQUALITY then.

I like the Mode idea for Time of Day.

My area trigger does not seem to trigger the action. I do not yet hav channel bindings, but when I trigger the Papillon motion ( in the correct mode) it does not turn on the light switch. I see in the logs it changes the group trigger though.
This is in Morning, for instance. All I see in the log o:

2019-10-23 06:26:08.656 [vent.ItemStateChangedEvent] - papillon_motion changed from OFF to ON

2019-10-23 06:26:08.656 [GroupItemStateChangedEvent] - gPapillon_Trigger changed from OFF to ON through papillon_motion

I will need to troubleshoot more after work.

OK I needed to add the area triggers pieces. My initial testing of the papillon light & motion look good now.

Programming wise you guys are far beyond me. I am just a network & systems administrator who uses programming to automate asks and simplify management.
Thank you very much @5iver

1 Like

Awesome! You’re the first confirmed user of area triggers!!!

Not in production yet, but getting closer…
Old men move s-l-o-w. (almost 65)

This thread is morphing a bit and that is OK. We are mixing Time of Day & triggers. Here are some observations & suggestions, not criticisms.

Triggers should have an option where the Mode IS the trigger. That is what is needed for one of my situations. I have some ideas for workarounds. The “always on” Switch keeps the lights on because there is no trigger to turn them off.

I see situations where you may want multiple Mode dictionaries for ToD to handle different situations. There is also a scalability issue, if I understand your metadata correctly. If you with to add a new mode, you need to adjust ALL your metadata rules to account for it.
It may also be useful to have a particular mode that could be time-adjusted from the UI.

One really bad thing with this automation is that the log rule names do not correspond to the text files unless you can refer back to when the file was first loaded.