Skip to content

Commit

Permalink
feat(fire-event): Add option for data field to be a JSONata Expr
Browse files Browse the repository at this point in the history
Add option for data field to be a JSONata Exprression.
Removed merge context
  • Loading branch information
zachowj committed Jul 21, 2019
1 parent 37b54ce commit 526d083
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 90 deletions.
54 changes: 9 additions & 45 deletions nodes/fire-event/fire-event.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,19 @@
name: { value: "" },
server: { value: "", type: "server", required: true },
event: { value: "" },
data: {
value: "",
validate: function(v) {
// data isn't required since it could be either not needed or provided via payload
if (!v) {
return true;
}
try {
JSON.parse(v);
return true;
} catch (e) {
return false;
}
}
},
mergecontext: { value: null }
data: { value: "" },
dataType: { value: "json" }
},
oneditprepare: function() {
const NODE = this;
const $server = $("#node-input-server");

const node = this;
haServer.init(node, "#node-input-server");

$("#node-input-data")
.typedInput({
types: ["json"]
types: ["json", "jsonata"],
typeField: "#node-input-dataType"
})
.typedInput("width", "68%");

const utils = {
setDefaultServerSelection: function() {
let defaultServer;
RED.nodes.eachConfig(n => {
if (n.type === "server" && !defaultServer) defaultServer = n.id;
});
if (defaultServer) $server.val(defaultServer);
}
};

if (!NODE.server) {
utils.setDefaultServerSelection();
}
}
});
</script>
Expand All @@ -80,12 +52,8 @@

<div class="form-row">
<label for="node-input-data"><i class="fa fa-dot-circle-o"></i> Data</label>
<input type="text" id="node-input-data" placeholder="{ }"/>
</div>

<div class="form-row">
<label for="node-input-mergecontext"><i class="fa fa-dot-circle-o"></i> Merge Context</label>
<input type="text" id="node-input-mergecontext" placeholder="lightOptions"/>
<input type="text" id="node-input-data" />
<input type="hidden" id="node-input-dataType" />
</div>
</script>

Expand Down Expand Up @@ -128,13 +96,9 @@ <h3>Outputs</h3>

<h3>Details</h3>
<p>If the incoming message has a <code>payload</code> property with <code>event</code> set it will override any config values if set.</p>
<p>If the incoming message has a <code>payload.data</code> that is an object or parseable into an object these properties will be <strong>merged</strong> with any config values set.<p>
<p>If the incoming message has a <code>payload.data</code> that is an object or parsable into an object these properties will be <strong>merged</strong> with any config values set.<p>
<p>If the node has a property value in it&#39;s config for <code>Merge Context</code> then the <code>flow</code> and <code>global</code> contexts will be checked for this property which should be an object that will also be merged into the data payload.<p>

<h3>Merge Resolution</h3>
<p>As seen above the <code>data</code> property has a lot going on in the way of data merging, in the end all of these are optional and the right most will win in the event that a property exists in multiple objects<p>
<p>Config Data, Global Data, Flow Data, Payload Data ( payload data property always wins if provided )<p>

<h3>References</h3>
<ul>
<li><a href="https://developers.home-assistant.io/docs/en/dev_101_events.html#firing-events">HA Events</a></li>
Expand Down
76 changes: 31 additions & 45 deletions nodes/fire-event/fire-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = function(RED) {
server: { isNode: true },
event: {},
data: {},
mergecontext: {}
dataType: nodeDef => nodeDef.dataType || 'json'
},
input: {
event: {
Expand All @@ -27,6 +27,17 @@ module.exports = function(RED) {
haltOnFail: false,
schema: Joi.string().label('data')
}
},
dataType: {
messageProp: 'payload.dataType',
configProp: 'dataType',
default: 'json',
validation: {
haltOnFail: true,
schema: Joi.string()
.valid('json', 'jsonata')
.label('dataType')
}
}
}
};
Expand Down Expand Up @@ -54,22 +65,26 @@ module.exports = function(RED) {
this.node.context(),
this.utils.toCamelCase(this.nodeConfig.server.name)
);
const configData = RenderTemplate(
typeof parsedMessage.data.value === 'object'
? JSON.stringify(parsedMessage.data.value)
: parsedMessage.data.value,
message,
this.node.context(),
this.utils.toCamelCase(this.nodeConfig.server.name)
);
const eventData = this.getEventData(message.payload, configData);

if (!eventType) {
this.node.error(
'Fire event node is missing "event" property, not found in config or payload',
message
let eventData;
if (parsedMessage.dataType.value === 'jsonata') {
try {
eventData = JSON.stringify(
this.evaluateJSONata(parsedMessage.data.value, message)
);
} catch (e) {
this.setStatusFailed('Error');
this.node.error(e.message, message);
return;
}
} else {
eventData = RenderTemplate(
typeof parsedMessage.data.value === 'object'
? JSON.stringify(parsedMessage.data.value)
: parsedMessage.data.value,
message,
this.node.context(),
this.utils.toCamelCase(this.nodeConfig.server.name)
);
return;
}

this.debug(`Fire Event: ${eventType} -- ${JSON.stringify({})}`);
Expand Down Expand Up @@ -97,35 +112,6 @@ module.exports = function(RED) {
this.setStatusFailed('API Error');
});
}

getEventData(payload, data) {
let eventData;
let contextData = {};

let payloadData = this.utils.selectn('data', payload);
let configData = this.tryToObject(data);
payloadData = payloadData || {};
configData = configData || {};

// Calculate payload to send end priority ends up being 'Config, Global Ctx, Flow Ctx, Payload' with right most winning
if (this.nodeConfig.mergecontext) {
const ctx = this.node.context();
let flowVal = ctx.flow.get(this.nodeConfig.mergecontext);
let globalVal = ctx.global.get(this.nodeConfig.mergecontext);
flowVal = flowVal || {};
globalVal = globalVal || {};
contextData = this.utils.merge({}, globalVal, flowVal);
}

eventData = this.utils.merge(
{},
configData,
contextData,
payloadData
);

return eventData;
}
}

RED.nodes.registerType('ha-fire-event', FireEventNode);
Expand Down

0 comments on commit 526d083

Please sign in to comment.