OH4.0 Blockly compare stored value to string

Hi All.

As part of my move to Blockly I have set up the following rule:

which generates:

cache.private.put('partition3NewState', event.itemState);
cache.private.put('partition3PreviousState', event.oldItemState);
console.info(('New State is: - ' + String(cache.private.get('partition3NewState'))));
console.info(('Previous State was: - ' + String(cache.private.get('partition3PreviousState'))));
if (items.getItem('GPSMarkatHome').state == 'ON') {
  console.info('Partition 3 Changed and Mark not Home');
  actions.NotificationAction.sendBroadcastNotification((['Partition 3 Changed from ',cache.private.get('partition3PreviousState'),' to ',cache.private.get('partition3NewState')].join('')), 'alarm', 'info');
}
console.info('Partition 3 Changed notification sent!');
if ((cache.private.get('partition3NewState')) == 'Disarmed') {
  items.getItem('Partition3_Armed').sendCommand('OFF');
  console.info('Partition 3 Armed State Updated to OFF');
} else {
  console.info('Partition 3 New State Disarmed - NOT MET');
}
if ((cache.private.get('partition3NewState')) == 'Armed') {
  items.getItem('Partition3_Armed').sendCommand('ON');
  console.info('Partition 3 Armed State Updated to ON');
} else {
  console.info('Partition 3 New State Armed - NOT MET');
}

However I cannot work out why the last two if…do blocks fail?

From the logs I see:


17:08:40.401 [INFO ] [ion.script.ui.Partition_3_StateChange] - New State is: - Disarmed
17:08:40.402 [INFO ] [ion.script.ui.Partition_3_StateChange] - Previous State was: - Armed
17:08:40.403 [INFO ] [ion.script.ui.Partition_3_StateChange] - Partition 3 Changed and Mark not Home
17:08:40.403 [INFO ] [ion.script.ui.Partition_3_StateChange] - Partition 3 Changed notification sent!
17:08:40.404 [INFO ] [ion.script.ui.Partition_3_StateChange] - Partition 3 New State Disarmed - NOT MET
17:08:40.405 [INFO ] [ion.script.ui.Partition_3_StateChange] - Partition 3 New State Armed - NOT MET

So partition3NewState is "Disarmed", so this block should be met (unless I am doing something dumb)?

Any hints would be appreciated.
Mark

There is absolutely no reason to use the private cache in this case. No matter what was in the private cache when the rule was triggered, it gets overwritten immediately when the rule runs again. You can’t share data between rules using the private cache. Why use it at all? Just use contextual info new state of item and contextual info previous state of item and get rid of the complexities added by using the private cache.

The two if blocks fail because nether value stored in the cache is a String. They are State Objects. But you are trying to compare them to a String. By shoving these into the private cache you lose information about them which hinders it’s ability to convert the State to a String for you.

It might work by simply dropping the use of the cache here, since it is not just pointless but might be working against you. If that’s not sufficient, I think you can convert the State to a String using the to item append text block.

Thank you. I had already tried using contextual info previous state. That did not work.

However you put me on the right track - my searches etc were just not great.

Solution was:

This did not catch my attention… But I now have it working by converting to string using the “TIP”.

Working Rule is now:

Which generates:

var partition3NewState, partition3PreviousState;


partition3NewState = event.itemState;
partition3PreviousState = event.oldItemState;
partition3NewState += '';
partition3PreviousState += '';
console.info(('New State is: - ' + String(partition3NewState)));
console.info(('Previous State was: - ' + String(partition3PreviousState)));
if (items.getItem('GPSMarkatHome').state == 'ON') {
  console.info('Partition 3 Changed and Mark not Home');
  actions.NotificationAction.sendBroadcastNotification((['Partition 3 Changed from ',partition3PreviousState,' to ',partition3NewState].join('')), 'alarm', 'info');
}
console.info('Partition 3 Changed notification sent!');
if (partition3NewState == 'Disarmed') {
  items.getItem('Partition3_Armed').sendCommand('OFF');
  console.info('Partition 3 Armed State Updated to OFF');
} else {
  console.info('Partition 3 New State Disarmed - NOT MET');
}
if (partition3NewState == 'Armed') {
  items.getItem('Partition3_Armed').sendCommand('ON');
  console.info('Partition 3 Armed State Updated to ON');
} else {
  console.info('Partition 3 New State Armed - NOT MET');
}

event.itemState;

I am confused as to why :

works, but:

Doesn’t and the last needs conversion of State to String?

Because in OH 4 Blockly “compiles” into JS Scripting. JS Scripting provides a helper library which wraps almost all of the interactions with OH in JavaScript Objects and Classes in a way that works best for JavaScript. Consequently, unless you go out of your way to avoid it, the state of an Item is always a String. There are methods to get the state as a number, quantity, or even the raw Java State Object but the default .state always returns a String.

But the event Object gets injected into the rule independent of the Helper Library. So the Helper Library doesn’t have a chance to wrap it meaning event.itemState and event.oldItemState are both Java State Objects and not Strings.

1 Like