i’m trying to configure my deebot robot with mqtt using the Node-Red integration. I managed to configure everything on Node-red, but i can’t split values from the mqtt message.
This is what i get from the( i get many payloads with the same topic):
{"type":"CurrentUsedCustomAreaValues","value":""}
{"type":"CurrentUsedSpotAreas","value":""}
{"type":"CleanReport","value":"stop"}
{"type":"ChargeState","value":"charging"}
{"type":"SleepStatus","value":"1"}
{"type":"LifeSpan","value":{"filter":83.93,"side_brush":-0.42,"main_brush":51.92}}
{"type":"BatteryInfo","value":100,"unit":"%"}
This is how i tried to retrive the data to sensors in configuration.yaml but it's not working, i always get "unknown" sensor value
mqtt:
sensor:
- name: "filter_left"
state_topic: "vacuum/sensors"
unit_of_measurement: "h"
value_template: "{{ value_json['value'].filter }}"
- name: "main_brush_left"
state_topic: "vacuum/sensors"
unit_of_measurement: "h"
value_template: "{{ value_json['value'].main_brush }}"
- name: "side_brush_left"
state_topic: "vacuum/sensors"
unit_of_measurement: "h"
value_template: "{{ value_json['value'].side_brush }}"
- name: "vacuum_battery"
state_topic: "vacuum/sensors"
unit_of_measurement: "%"
value_template: "{{value_json.type.BatteryInfo}}"
Thanks in advance for any help
It looks like your main issue is that the MQTT message isn't valid JSON. If you take that LifeSpan line, for example, and plug it in to the template tool on Home Assistant (http://your-ha-machine.local:8123/developer-tools/template), you could insert the contents of that line (minus the curly braces), like this:
{% set my_test_json = {
"type":"LifeSpan","value":{"filter":83.93,"side_brush":-0.42,"main_brush":51.92}
}
%}
The filter life is at {{ my_test_json.value.filter }}.
You can use that tool to play around with the formatting, and figure out what's wrong with the syntax. You'll probably need to fix the MQTT message on the Node-Red side.
Related
In Ionic 6 I'm getting data from a central JSON service that is resolving data on an /:id page like so {{ product.title }}. The central JSON also feeds the wishlist and search facility.
central.json > page/:id
The JSON file is like this:
public product: Product[] = [
{
id:0,
title: 'UK Information',
description: 'Travel tips',
extrainfo:'',
...
I need to use ngx-translate. In the past {{ product.title | translate }} would have pulled the data from assets/i18n/en.json and assets/i18n/fr.json.
Any ideas how I can use ngx-translate to get the dynamic text from strings on a page?
Thanks for any help!
Your object is in an array.
<div>{{ product[0].title || translate }}</div>
My GET Request:
### Bank token idclaim
GET {{IdClaimEndpoint}}/tokens/v1/id
Content-Type: application/json
> {% client.log(response.body.id-claim); %}
Response body:
{
"documentation": "http://go/proofs",
"id-claim": "eyJ0eXAiOiJKV1QiLCJhbGc"
}
Error from Response handler:
ReferenceError: "claim" is not defined. (<jsHandler script>#143)Script finished
If I try to extract value of documentation it works fine but not working for "id-claim".
I tried wrapping it within single/double quotes and also saving it to env variable and passing the env variable as {{id-claim}}, none of them worked.
It is JavaScript. You can use response.body['id-claim'] syntax. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#syntax
For example, the next request works fine:
POST https://httpbin.org/post
Content-Type: application/json
{
"my-json-value": "value"
}
{%
// 'json' is a property in HTTPBin response JSON
client.log(response.body.json["my-json-value"])
%}
This works:
> {%
client.log(JSON.stringify(response.body.valueOf()).replace("\"documentation\":\"http:\/\/go\/proofs\",\"id-claim\":\"", "").replace("\"","").replace("{","").replace("}",""));
client.global.set("banktokenidclaim", JSON.stringify(response.body.valueOf()).replace("\"documentation\":\"http:\/\/go\/proofs\",\"id-claim\":\"", "").replace("\"","").replace("{","").replace("}",""));
%}
But is a lot of work for a simple thing. Not sure if there exists a easier/better solution.
I am working with Airflow 2.2.3 in GCP (Composer) and I am seeing inconsistent behavior which I can't explain when trying to use template values.
When I reference the templated value directly, it works without issue:
ts = '{{ ds }}' # results in 2022-05-09
When I reference the templated value in a function call, it doesn't work as expected:
ts_parts = '{{ ds }}'.split('-') # result ['2022-05-09']
The non-function call value is rendered without any issues, so it doesn't have any dependency on operator scope. There are examples here that show rendering outside of an operator, so I expect that not to be the issue. It's possible that Composer has setting configured so that Airflow will apply rendering to all python files.
Here's the full code for reference
dag.py
with DAG('rendering_test',
description='Testing template rendering',
schedule_interval=None, # only run on demand
start_date=datetime(2020, 11, 10), ) as rendering_dag:
ts = '{{ ds }}'
ts_parts = '{{ ds }}'.split('-')
literal_parts = '2022-05-09'.split('-')
print_gcs_info = BashOperator(
task_id='print_rendered_values',
bash_command=f'echo "ts: {ts}\nts_parts: {ts_parts}\nliteral_parts {literal_parts}"'
)
I thought that Airflow writes the files to some location with template values, then runs jinja against them with some supplied values, then runs the resulting python code. It looks like there is some logic applied if the line contains a function call? The documentation mentions none of these architectural principles and gives very limited examples.
Airflow does not render values outside of operator scope.
Rendering is a part of task execution which means that it's a step that happens only when task is in the worker (after being scheduled).
In your code the rendering is a top level code which is not part of operator templated fields thus Airflow consider it to be a regular string.
In your case the os.path.dirname() is executed on '{{ dag_run.conf.name }}' before it was rendered.
To fix your issue you need to set the Jinja string in templated fields of the operator.
bash_command=""" echo "path: {{ dag_run.conf.name }} path: os.path.dirname('{{ dag_run.conf.name }}')" """
Triggering DAG with {"name": "value"} will give:
Note that if you wish to use f-string with Jinja strings you must double the number of { }
source_file_path = '{{ dag_run.conf.name }}'
print_template_info = BashOperator(
task_id='print_template_info',
bash_command=f""" echo "path: { source_file_path } path: os.path.dirname('{{{{ dag_run.conf.name }}}}')" """
)
Edit:
Let me clarify - Airflow template fields as part of task execution.
You can see in the code base that Airflow invokes render_templates before it invokes pre_execute() and before it invokes execute(). This means that this step happens when the task is running on a worker. Trying to template outside of operator means the task doesn't even run - so the step of templating isn't running.
I am following a direction on Hashicorp's site regarding wrapping a CF Template in Terraform. There's a fair amount to the whole code, but the CF Template works, so the issue is with the "wrapping"...
Terraform plan gives me this error output:
terraform plan
Error: aws_cloudformation_stack.Momma: "template_body" contains an invalid JSON: invalid character 'A' looking for beginning of object key string
Error: aws_cloudformation_stack.Momma: : invalid or unknown key: source
So it seems that the "AWSTemplateFormatVersion" line is what it does not like. Hence the'A' it is picking up, I guess.
This is the Hashicorp page I am following, I'm wondering if there are any escape characters that are appropriate or, if anyone can see any immediate formatting issues with my JSON?
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack
terraform {}
provider "aws" {
version = "= 2.61"
region = "ap-southeast-2"
}
resource "aws_cloudformation_stack" "Momma" {
source = "../../aws_modules/aws-db-event-subscription"
name = "Momma-Stack"
template_body = <<STACK
{
AWSTemplateFormatVersion: 2010-09-09
Description: Team Server
Metadata:
'AWS::CloudFormation::Interface':
ParameterGroups:
- Label:
default: Deployment Options
Parameters:
- Environment
- KeyPairName
- VPCID
- Subnet1ID
- RemoteAccessCIDR
- Owner
ParameterLabels:
KeyPairName:
Default: Key Pair Name
RemoteAccessCIDR:
Default: External Access CIDR
VPCID:
Default: VPC ID
Owner:
Default: MommaTeam....
Thank you for any guidance offered.
There are at least two issues that are apparent:
source = "../../aws_modules/aws-db-event-subscription" is invalid. There is no attribute called source in aws_cloudformation_stack. You can remove it.
Your template_body should not begin with { in:
template_body = <<STACK
{
This is because you are using YAML for your template, not JSON.
How to pass a service json data(which already getting from services.js) to filter(filter.js)?
Example:JSON data:
{"name" :"stackoverflow"}
Services.js:
Here i have written service to get json data
{"getjsondataservice" }
Controller:
using "getjsondataservice" service here.
{}i need to get "getjsondataservice" service to filter.jsFilter:{}how should i write that filter?
In output code you should write filter name:
{{ stackoverflow | filter }}
Then the filter will work and you will receive the filtered variable.