Presence Simulation with Google Calendar Scheduler

Yes, from his screen snip above, it’s clear that the calendar event contained send Licht_sluis 50

Thanks. I’ll continue to look into this to see if I can track down the issue.

What is the item type of Licht_sluis?

Not sure, actually. I had assumed Dimmer, but you know what happens when you assume… :sunglasses:

Actually, in my post further up in this thread, I showed 2 log statements from my test case. My item PD300Z_Dimmer is defined as type Dimmer. In the first log statement, it appears that the job was stored as 53 (which is how the command appears in the calendar event). But, when it executes, it is 53.0.

2017-01-24 07:49:15.305 [DEBUG] [io.gcal.internal.GCalEventDownloader] - created new startJob '[PresenceSimulation] PD300Z_Dimmer' with details 'SchedulerJob [jobKey=ouh754uq40s74nmqule62qm59c@google.com_start, jobGroup=gcal, 1 triggers=[Tue Jan 24 07:52:00 EST 2017], content=send PD300Z_Dimmer 53'

2017-01-24 07:52:00.002 [DEBUG] [gcal.internal.util.ExecuteCommandJob] - Command [send, PD300Z_Dimmer, 53.0, ] has been sent

I wonder if it’s happening here. tokenizer.nval is defined as a double.

Yep, here’s the trace log from my earlier test.

2017-01-24 07:52:00.000 [TRACE] [gcal.internal.util.ExecuteCommandJob] - going to parse command 'send PD300Z_Dimmer 53'
2017-01-24 07:52:00.001 [TRACE] [gcal.internal.util.ExecuteCommandJob] - read value send from the given command
2017-01-24 07:52:00.001 [TRACE] [gcal.internal.util.ExecuteCommandJob] - read value PD300Z_Dimmer from the given command
2017-01-24 07:52:00.001 [TRACE] [gcal.internal.util.ExecuteCommandJob] - read value 53.0 from the given command
2017-01-24 07:52:00.001 [TRACE] [gcal.internal.util.ExecuteCommandJob] - read value  from the given command
2017-01-24 07:52:00.002 [DEBUG] [gcal.internal.util.ExecuteCommandJob] - Command [send, PD300Z_Dimmer, 53.0, ] has been sent

Good spot! I’m actually glad it’s in this code, because it would be a lot hairier if it were in the other possible places.

I have tested with other items and it seems that it works perfectly with switches but not with dimmers.

  21:01:02.554 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - Got calendar OH2 CalendarID: cbhubs9emat56dr7hfp9j49vto@group.calendar.google.com
    21:01:02.556 [DEBUG] [io.gcal.internal.GCalEventDownloader] - Downloading calendar feed for time interval: 2017-01-25T21:01:02.556+01:00 to  2017-01-25T21:03:02.556+01:00
    21:01:02.565 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - Loaded credential
    21:01:02.567 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - device access
    21:01:02.568 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - device refresh_token: 
    21:01:02.569 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - device expires_in: 1485378001037
    21:01:03.213 [DEBUG] [io.gcal.internal.GCalEventDownloader] - found 1 calendar events to process
    21:01:03.215 [DEBUG] [io.gcal.internal.GCalEventDownloader] - given event content doesn't match regular expression to extract start-, end commands - using whole content as startCommand (send Spot_afzuigkap 0)



21:07:06.096 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - Got calendar OH2 CalendarID: cbhubs9emat56dr7hfp9j49vto@group.calendar.google.com
21:07:06.097 [DEBUG] [io.gcal.internal.GCalEventDownloader] - Downloading calendar feed for time interval: 2017-01-25T21:07:06.097+01:00 to  2017-01-25T21:09:06.097+01:00
21:07:06.106 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - Loaded credential
21:07:06.108 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - device access token: 
21:07:06.109 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - device refresh_token: 
21:07:06.111 [DEBUG] [openhab.io.gcal.auth.GCalGoogleOAuth] - device expires_in: 1485378001037
21:07:06.808 [DEBUG] [io.gcal.internal.GCalEventDownloader] - found 1 calendar events to process
21:07:06.811 [DEBUG] [io.gcal.internal.GCalEventDownloader] - given event content doesn't match regular expression to extract start-, end commands - using whole content as startCommand (send toilet ON)
21:07:06.813 [DEBUG] [io.gcal.internal.GCalEventDownloader] - created new startJob '[PresenceSimulation] toilet' with details 'SchedulerJob [jobKey=ukeu0o8babg9rf3o29thlc3814@google.com_start, jobGroup=gcal, 1 triggers=[Wed Jan 25 21:08:00 CET 2017], content=send toilet ON'

21:08:00.005 [DEBUG] [gcal.internal.util.ExecuteCommandJob] - Command [send, toilet, ON, ] has been sent

It works when sending to a dimmer the value ON or OFF.
but worth 0 or 50 does not work.

The code declares “_”, “-”, and “.” to be part of a word token. So, clearly the expectation was that the number token must be an integer.

    StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(command));
    tokenizer.wordChars('_', '_');
    tokenizer.wordChars('-', '-');
    tokenizer.wordChars('.', '.');

That being the case, is the fix for this as simple as casting the token to an int.

                    token = String.valueOf((int) tokenizer.nval);

That would be a problem when the user really wanted decimal places in the command, right?

Maybe this suggestion would achieve the desired outcome?

Yes, I thought about that. But, I wasn’t sure what was behind the original intent of including a “.” in the definition of a word token.

Oddly, in the case of the command send MyItem 50.0, in the current implementation, wouldn’t the 50.0 be interpreted by the tokenizer as a word and be added to the tokens array literally?

I guess that argues in favor of your suggestion, which would eliminate completely the separate handling of a number token.

The problem with a TT_NUMBER is that nval is a double, whose string representation will always end in .0 if it’s otherwise a whole number. There’s a similar subject with the Gson library which is very tedious.

This quick-and-dirty program seems to suggest that the Stackoverflow person’s advice is good. Can you spot a case where I’m wrong?

import java.io.*;
import java.util.*;

public class Foo {

	public static void main(String [] args) {

		String [] tests = {
			"send Foo_bar \"12.0\"",
			"update TestItem ON",
			"send BedRoomLight 50",
			"send HouseAlarm \"OPEN\""
		};

		for (int i = 0; i < tests.length; i++) {
			System.out.println(Arrays.toString(getTokens(tests[i])));
		}
	}

	private static String [] getTokens(String command) {

	    StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(command));
        // treat all characters as ordinary, including digits, so we never
        // have to deal with doubles
        tokenizer.resetSyntax();
        tokenizer.wordChars(0x23, 0xFF);
        tokenizer.whitespaceChars(0x00, 0x20);
        tokenizer.quoteChar('"');

        List<String> tokens = new ArrayList<String>();
        try {
            int tokenType = 0;
            while (tokenType != StreamTokenizer.TT_EOF && tokenType != StreamTokenizer.TT_EOL) {
                tokenType = tokenizer.nextToken();
                String token = "";
                switch (tokenType) {
                    case StreamTokenizer.TT_WORD:
                    case 34 /* quoted String */:
                        token = tokenizer.sval;
                        break;
                }
                tokens.add(token);
                System.out.println("read value "+token+" from the given command");
            }
        } catch (IOException ioe) {
        }

        return tokens.toArray(new String[0]);
     }

}

output:

$ java Foo
read value send from the given command
read value Foo_bar from the given command
read value 12.0 from the given command
read value  from the given command
[send, Foo_bar, 12.0, ]
read value update from the given command
read value TestItem from the given command
read value ON from the given command
read value  from the given command
[update, TestItem, ON, ]
read value send from the given command
read value BedRoomLight from the given command
read value 50 from the given command
read value  from the given command
[send, BedRoomLight, 50, ]
read value send from the given command
read value HouseAlarm from the given command
read value OPEN from the given command
read value  from the given command
[send, HouseAlarm, OPEN, ]

Looks good.

What would happen with:

"send StringItem \"Multi word string.\""

and

"send StringItem \"A \\\"quoted\\\" example.\""

I’m not even sure what openhab will do with that last one…

Edit: Actually, it handles it just fine.

openhab> smarthome:send MoonPhase "A \"quoted\" example."
Command has been sent successfully.

looks correct to my eyes.

input:

		"send StringItem \"Multi word string.\"",
		"send StringItem \"A \\\"quoted\\\" example.\"",
		"send StringItem \"A \"quoted\" example.\"",

output:

read value send from the given command
read value StringItem from the given command
read value Multi word string. from the given command
read value  from the given command
[send, StringItem, Multi word string., ]
read value send from the given command
read value StringItem from the given command
read value A "quoted" example. from the given command
read value  from the given command
[send, StringItem, A "quoted" example., ]
read value send from the given command
read value StringItem from the given command
read value A  from the given command
read value quoted from the given command
read value  example. from the given command
read value  from the given command
[send, StringItem, A , quoted,  example., ]

Is it right that the double quotes are removed?

Isn’t this
send StringItem "Multi word string."

openhab> smarthome:send MoonPhase "Multi word string."
Command has been sent successfully.

different from this

send StringItem Multi word string.

openhab> smarthome:send MoonPhase Multi word string.
Command has been sent successfully.

You don’t have a mechanism at the console prompt to escape double quotes. They can only be used to surround strings with whitespace in them. That seems normal to me.

@Ferryb4 @mhilbush:

Could you try this JAR in your setup to make sure this fixes the problem with the unwanted “.0” on the end of numbers, and doesn’t introduce new issues?

1 Like

Unless I’m misunderstanding what you’re saying, this produces the expected result.

openhab> smarthome:send MoonPhase “A "quoted" example.”
Command has been sent successfully.

Oh geez, I’m up way past my bedtime. Of course you’re right.

Thanks John,

With this JAR it works great.

Thanks for fixing

Thanks for testing.