Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for more complex JSONata extraction and publishing JSON payload for ON/OFF #53

Open
PaJaSoft opened this issue Nov 10, 2023 · 0 comments

Comments

@PaJaSoft
Copy link

Hi, my journey landed to this plugin however looking through the code, some changes are necessary.

I'm trying to control ZigBee power socket plug (a variation of this device) which operates like (lets imagine a friendly name as z2m/device/id1):

  1. publishes into topic z2m/device/id1 with payload like {"child_lock":"UNLOCK","current":0,"energy":0.04,"indicator_mode":"off/on","last_seen":"2023-11-10T22:53:42.395Z","linkquality":200,"power":0,"power_outage_memory":"restore","state":"ON","update":{"installed_version":192,"latest_version":192,"state":"idle"},"update_available":null,"voltage":241}
  2. can receive for ex. power switch command via JSON payload like {"state":"ON"} published to topic z2m/device/id1/set

So I was trying to force this plugin to work with this setting (it doesn't work!):
Using it as a switch
Subscribed topic: z2m/device/id1
JSONata: state = "OFF" ? {"state":"OFF"}:{"state":"ON"}
OFF message: {"state":"OFF"}
ON message: {"state":"ON"}
Publish topic: z2m/device/id1/set

I'm able either:

  1. receiving properly the current state -> JSONata expression evaluation from topic works with a simple expression like state and mapping to simple string value (OFF, ON) or e.g. transforming the state to Bool and use false/true as their values
  2. click triggers sending proper JSON payload to publishing topic (based on cfg.) however showed status isn't synced with the real state

unfortunately both don't work together.

I went through the code (I'm not expert on TypeScript nor JSONata) however I feel the issue lies around here where simple toString() is used instead of JSON.stringify(...).

My basic test:

var json = JSON.parse('{"child_lock":"UNLOCK","current":0,"energy":0.04,"indicator_mode":"off/on","last_seen":"2023-11-10T21:49:11.520Z","linkquality":204,"power":0,"power_outage_memory":"restore","state":"ON","update":{"installed_version":192,"latest_version":192,"state":"idle"},"update_available":null,"voltage":240}');
console.log("json: " + JSON.stringify(json));
var expression = jsonata('state = "OFF" ? {"state":"OFF"}:{"state":"ON"}')
var result = await expression.evaluate(json);
console.log("\nresult (toString): " + result.toString());
console.log("result (stringify): " + JSON.stringify(result));

console.log("------");

var expression2 = jsonata('state')
var result2 = await expression2.evaluate(json);
console.log("result (toString): " + result2.toString());
console.log("result (stringify): " + JSON.stringify(result2));

produces this output:

json: {"child_lock":"UNLOCK","current":0,"energy":0.04,"indicator_mode":"off/on","last_seen":"2023-11-10T21:49:11.520Z","linkquality":204,"power":0,"power_outage_memory":"restore","state":"ON","update":{"installed_version":192,"latest_version":192,"state":"idle"},"update_available":null,"voltage":240}

result (toString): [object Object]
result (stringify): {"state":"ON"}
------
result (toString): ON
result (stringify): "ON"

so as you can see a more complex evaluation (like my first test) can't be simply converted to String via result.toString() but JSON.stringify(result) produces a result which can be compared with ON/OFF values and makes sense...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant