Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Drivstoffpriser i HA


hjemmedude

Anbefalte innlegg

NeoID skrev (På 14.2.2024 den 19.23):
command_line:
  - sensor:
      name: Gas Prices
      command: >
        app_id="com.raskebiler.drivstoff.appen.android";
        api_brands="https://api.drivstoffappen.no/api/v1/brands";
        api_sessions="https://api.drivstoffappen.no/api/v1/authorization-sessions";
        api_stations="https://api.drivstoffappen.no/api/v1/stations?stationTypeId=1&includeDeleted=true&includePending=true&minUpdatedAt={{ (now() - timedelta(days=2)).strftime('%Y-%m-%dT%H:%M:%S%z') | urlencode }}";
        
        auth_token=$(curl -s $api_sessions | jq -r ".token");
        api_key=$(python -c "import hashlib; auth_token = \"$auth_token\"; shifted_auth_token = bytearray(auth_token, 'utf-8')[1:] + bytearray(auth_token, 'utf-8')[:1]; print(hashlib.md5(shifted_auth_token).hexdigest())");
        stations=$(curl -s -H "X-API-KEY: $api_key" -H "X-CLIENT-ID: $app_id" $api_stations);
        brands=$(curl -s -H "X-API-KEY: $api_key" -H "X-CLIENT-ID: $app_id" $api_brands);
        merged=$(jq -s '[.[0][] as $stations | .[1][] as $brands | select($stations.brandId == $brands.id) | $stations | .brand = $brands]' <(echo "$stations") <(echo "$brands"));
        echo "{\"stations\": $(echo "$merged") }"
      json_attributes:
        - stations
      value_template: 'OK'
      scan_interval: 1800

 

Topp! Mulig å slenge på en JQ her et sted så sensoren ikke blir så stor? Enten med stasjons IDer eller et visst område den skal hente fra? Er ikke så stødig på dette så usikker på hvor jeg skulle ha plassert JQen.

Lenke til kommentar
Del på andre sider

Chrulf skrev (2 timer siden):

 

Topp! Mulig å slenge på en JQ her et sted så sensoren ikke blir så stor? Enten med stasjons IDer eller et visst område den skal hente fra? Er ikke så stødig på dette så usikker på hvor jeg skulle ha plassert JQen.

Siste commando før "json_attributes:" kan da f.eks være med en jq filtrering: 

 

merged=$(jq -s '[.[0][] as $stations | .[1][] as $brands | select($stations.brandId == $brands.id) | $stations | .brand = $brands]' <(echo "$stations") <(echo "$brands"));
        echo "{\"stations\": $(echo "$merged" | jq -c '[ .[] | select( .id | contains(33, 34, 35, 62, 67, 89, 105, 126, 1083, 4456, 5887)) ]') }"

 

Der du legger inn dine stasjons ID'er i stedet for mine selvfølgelig.

  • Like 1
Lenke til kommentar
Del på andre sider

Sensor template for å lage egne sensorer for gitte stasjoner, kun navn, station_id og type_id som må tlpasses.
Selvfølgelig må station_id være med i spørringen til sensor.fuel_prices_command.

 

   circle_k_robsrud:
      friendly_name: "Circle K Robsrud 95 Oktan"
      icon_template: "mdi:gas-station"
      value_template: >
        {% set fuel_prices = state_attr('sensor.fuel_prices_command','verdi') %}
        {% set fuel_station_id = 716 %}
        {% set fuel_type_id = 1 %}
        {% set fuel_station = fuel_prices|selectattr('id','==', fuel_station_id)|list|first %}
        {% if fuel_station %}
         {% set price = fuel_station.prices|selectattr('fuelTypeId','==', fuel_type_id)|map(attribute='price')|list|first %}
         {{ price }}
        {% endif %}

 

Lenke til kommentar
Del på andre sider

terjemath skrev (På 16.2.2024 den 15.15):

merged=$(jq -s '[.[0][] as $stations | .[1][] as $brands | select($stations.brandId == $brands.id) | $stations | .brand = $brands]' <(echo "$stations") <(echo "$brands"));
        echo "{\"stations\": $(echo "$merged" | jq -c '[ .[] | select( .id | contains(33, 34, 35, 62, 67, 89, 105, 126, 1083, 4456, 5887)) ]') }"

 

Nydelig! Takk 🙂

Lenke til kommentar
Del på andre sider

  • 3 uker senere...

Fantastisk stykke arbeid som har blitt gjort i forhold til dette 🙂

 

Men for dem som ikke er helt rå på dette med koding å slikt og helt klarer å se for seg hvordan dette skal gjøres, så kan kanskje noen lage en liten forklaring for hvordan få dette til i node red med ferdig flow og eventuelt en ferdig .json fil?

 

  • Like 1
Lenke til kommentar
Del på andre sider

Kippy skrev (8 timer siden):

i node red med ferdig flow

 

Mitt Dieselprisbilde ser for tiden slik ut:

image.thumb.png.32df38099af50194eb90976b7197d18e.png

 

Og et søkbart bilde med mer fleksibelitet men mindre nytteverdi... Her finner en ID som trengs i hovedbildet:

image.thumb.png.fd76ccdcfa2287dae0a03a28980186eb.png

 

Node-RED Flow:

image.thumb.png.6f685079ed5a28ab6f7714e01462219f.png

 

De 10 funksjonsnodene med bensinstasjonsnavn  er det eneste som trenger endres for å tilpasse favorittene. Innholdet er slik:

image.thumb.png.0e9f194040b9bb12caa69dceaab5075c.png 

 

[{"id":"9103052baf82e5d0","type":"inject","z":"2447f70b5f1095ba","g":"1187eef693a5d073","name":"Hvert 10 min","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"*/10 6-23 * * *","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":140,"y":80,"wires":[["fb25d94b.139e78"]]},{"id":"c622a1c1b5d187fe","type":"function","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"List all stations & create flow.stations","func":"var brands = flow.get(\"brands\");\nvar statsRaw = flow.get(\"stationsRaw\");\n//flow.set(\"Stations\",msg.payload);\n//node.warn( \"pl.length: \" + statsRaw.length);\nvar arr = [];\nvar arr2 = [];\nvar obj2 = {}\nvar msg2 = {}\nvar i = 0;\nvar j = 0;\nfor (i = 0;i < statsRaw.length;i++){\n    let obj = {}\n    obj.id = statsRaw[i].id;\n//    obj.name = msg.payload[i].name || \"-\"\n//    obj.brand = msg.payload[i].brand || \"-\"\n//    obj.discountInfo = msg.payload[i].discountInfo || \"-\"\n    obj.name = statsRaw[i].name || \"-\"\n    // Find brand from brandId\n    for (j = 0;j < brands.length;j++){\n        if (Number(statsRaw[i].brandId) == Number(brands[j].id)){\n             obj.brand = brands[j].name || \"-\"\n             obj.logo = brands[j].pictureUrl || \"-\"\n             //node.warn(i + \" \" + j + \" \" + brands[j].name);\n             break;\n        }\n    }\n//    obj.brandId = msg.payload[i].brandId || \"-\"\n    obj.location = statsRaw[i].location || \"-\"\n    // Add prices\n    var obj3 = {}\n    //console.log(statsRaw[i].prices.length);\n    for (j = 0;j < statsRaw[i].prices.length;j++){\n        var ftid = statsRaw[i].prices[j].fuelTypeId;\n        if (ftid == 1 && statsRaw[i].prices[j].price != 0){ \n            obj3.D = {}\n            obj3.D.price = statsRaw[i].prices[j].price;\n            obj3.D.lastUpdated = statsRaw[i].prices[j].lastUpdated;\n            obj3.D.type = \"D\";\n        }\n        if (ftid == 2 && statsRaw[i].prices[j].price != 0){ \n            obj3.B95 = {}\n            obj3.B95.price = statsRaw[i].prices[j].price;\n            obj3.B95.lastUpdated = statsRaw[i].prices[j].lastUpdated;\n            obj3.B95.type = \"B95\";\n        } \n        if (ftid == 3 && statsRaw[i].prices[j].price != 0){\n            obj3.B98 = {}\n            obj3.B98.price = statsRaw[i].prices[j].price;\n            obj3.B98.lastUpdated = statsRaw[i].prices[j].lastUpdated;\n            obj3.B98.type = \"B98\";\n        }\n        if (ftid == 4 && statsRaw[i].prices[j].price != 0){\n            obj3.FD = {}\n            obj3.FD.price = statsRaw[i].prices[j].price;\n            obj3.FD.lastUpdated = statsRaw[i].prices[j].lastUpdated;\n            obj3.FD.type = \"FD\";\n        }\n    }\n//    console.log(obj3);\n    obj.prices = obj3;\n\n    \n    arr.push(obj);\n}\nmsg2.payload = arr;\nflow.set(\"stationsPrepd\",arr);\nreturn msg2;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":880,"wires":[["6ffebf4f1340a92e","f193882be2dc7762"]]},{"id":"6ffebf4f1340a92e","type":"ui_table","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","group":"0d788a3660f620b1","name":"All stations","order":4,"width":"12","height":"22","columns":[{"field":"name","title":"","width":"26%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"brand","title":"","width":"27%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"location","title":"","width":"31%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"id","title":"id","width":"13%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":1,"cts":true,"x":1100,"y":880,"wires":[["fc1b2554d6e80f6b"]]},{"id":"fc1b2554d6e80f6b","type":"function","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"add to favs","func":"var favs = flow.get(\"Favs\") || []\nvar pl = msg.payload;\nvar arr = [];\nvar exists = false;\narr = favs;\n\nfor (var i = 0;i < favs.length;i++){\n    if (favs[i].id == pl.id) exists = true;\n}\nif (exists == false) arr.push(pl);\n\nflow.set(\"Favs\", arr);\nreturn msg; ","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":920,"wires":[["6bfcbbe7c43dcc84"]]},{"id":"5fd3c4e366a636d6","type":"ui_table","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","group":"0d788a3660f620b1","name":"Selected stations","order":5,"width":"14","height":"23","columns":[{"field":"name","title":"name","width":"30%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"brand","title":"brand","width":"30%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"location","title":"location","width":"30%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"id","title":"id","width":"10%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":1,"cts":true,"x":1120,"y":920,"wires":[["03dc6f5b94c49e02"]]},{"id":"6bfcbbe7c43dcc84","type":"function","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"List fav stations","func":"var favs = flow.get(\"Favs\") || []\nvar arr = []\nvar msg2 = {}\nfor (var i = 0;i < favs.length;i++){\n    let obj = {}\n    obj.id = favs[i].id;\n    obj.name = favs[i].name;\n    obj.brand = favs[i].brand;\n    obj.location = favs[i].location;\n    arr.push(obj);\n}\nmsg2.payload = arr;\nreturn msg2; ","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":860,"y":920,"wires":[["5fd3c4e366a636d6","f193882be2dc7762"]]},{"id":"03dc6f5b94c49e02","type":"function","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"Remove station from fav","func":"var i,j = 0;\nvar favs = flow.get(\"Favs\") || []\nvar favs2 = []\nvar remove = msg.payload;\nvar arr = []\nvar msg2 = {}\nfor (i = 0;i < favs.length;i++){\n    if (favs[i].id != remove.id){\n        favs2[j] = favs[i];\n        j++;\n    }\n}\nflow.set(\"Favs\", favs2)\nreturn msg; ","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":890,"y":970,"wires":[["6bfcbbe7c43dcc84"]]},{"id":"4d95ecb3e17e80a4","type":"ui_table","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","group":"0d788a3660f620b1","name":"Drivstoffpriser","order":6,"width":"13","height":"23","columns":[{"field":"brand","title":"","width":"20%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"name","title":"","width":"25%","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"type","title":"","width":"15%","align":"right","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"price","title":"Kr","width":"15%","align":"right","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"age","title":"hrs.","width":"15%","align":"right","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":1,"cts":true,"x":1110,"y":1010,"wires":[[]]},{"id":"bf43e528a5851b0d","type":"function","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"List priser for favs","func":"var favs = flow.get(\"Favs\") || []\nvar stats = flow.get(\"stationsPrepd\") || []\nvar arr = []\nvar msg2 = {}\nvar now = Number(new Date());\nvar age = 0;\n\nfor (var i = 0;i < stats.length;i++){   //bla gjennom alle stasjoner\n    for (var j = 0;j < favs.length;j++){    // bla gjennom favoritter\n        if (stats[i].id == favs[j].id){ //er gjeldende stasjon i favoritter?\n//                console.log(stats[i].prices);\n//            for (var k = 0; k < stats[i].prices.length; k++){  // bla gjennom drivstofftyper\n            for (var k in stats[i].prices){  // bla gjennom drivstofftyper\n//                console.log(stats[i].id);\n                let obj = {}\n                obj.name = stats[i].name;\n                obj.brand = stats[i].brand;\n                obj.location = stats[i].location;\n                obj.type = stats[i].prices[k].type;\n                obj.price = stats[i].prices[k].price;\n                obj.age = ((now - stats[i].prices[k].lastUpdated) / 3600 / 1000).toFixed(1);// + \"h\"; //age in hours\n                arr.push(obj);\n            }\n        }\n    }\n}\nmsg2.payload = arr;\nreturn msg2;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":870,"y":1010,"wires":[["4d95ecb3e17e80a4"]]},{"id":"f193882be2dc7762","type":"delay","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":660,"y":1010,"wires":[["bf43e528a5851b0d"]]},{"id":"d9d0882ba114f2ae","type":"ui_text_input","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"","label":"Søk...","tooltip":"","group":"0d788a3660f620b1","order":7,"width":"10","height":"1","passthru":true,"mode":"text","delay":300,"topic":"topic","sendOnBlur":true,"className":"","topicType":"msg","x":610,"y":840,"wires":[["dd937fc64214f72d"]]},{"id":"dd937fc64214f72d","type":"function","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"List selected stations","func":"var stats = flow.get(\"stationsPrepd\") || []\nvar searchText = msg.payload;\nvar arr = [];\nvar msg2 = {}\nfor (var i = 0;i < stats.length;i++){\n    let obj = {}\n    obj.id = stats[i].id;\n    obj.name = stats[i].name || \"-\"\n    obj.brand = stats[i].brand || \"-\"\n    obj.location = stats[i].location || \"-\"\n    // plukk ut bare stasjoner som inneholder søkebegrepet\n    if (obj.name.includes(searchText) || obj.brand.includes(searchText) || obj.location.includes(searchText)){\n        arr.push(obj);\n    }\n}\nmsg2.payload = arr;\nreturn msg2;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":840,"wires":[["6ffebf4f1340a92e"]]},{"id":"13d4a47fe1d5ae74","type":"ui_text","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","group":"0d788a3660f620b1","order":1,"width":"12","height":"1","name":"","label":"Alle stasjoner","format":"{{msg.payload}}","layout":"row-spread","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1340,"y":850,"wires":[]},{"id":"65cdb903a6486baf","type":"ui_text","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","group":"0d788a3660f620b1","order":2,"width":"14","height":"1","name":"","label":"Favoritter","format":"{{msg.payload}}","layout":"row-spread","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1320,"y":880,"wires":[]},{"id":"6e102042f9d3270e","type":"ui_text","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","group":"0d788a3660f620b1","order":3,"width":"13","height":"1","name":"","label":"Priser","format":"{{msg.payload}}","layout":"row-spread","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1310,"y":910,"wires":[]},{"id":"8aef97ddf9f7d1d0","type":"comment","z":"2447f70b5f1095ba","g":"1187eef693a5d073","name":"Hent drivstoffpriser fra Drivstoffappen","info":"","x":190,"y":50,"wires":[]},{"id":"cf5b28121ebac9d8","type":"comment","z":"2447f70b5f1095ba","g":"516b853f82e2fd07","name":"Vis universalliste drivstoffpriser i egen tab","info":"","x":720,"y":790,"wires":[]},{"id":"08c3e48feae420a1","type":"inject","z":"2447f70b5f1095ba","g":"1187eef693a5d073","name":"Hvert 60 min","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"0 0-5 * * *","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":140,"y":110,"wires":[["fb25d94b.139e78"]]},{"id":"fb25d94b.139e78","type":"http request","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"Get Token","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://api.drivstoffappen.no/api/v1/authorization-sessions","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":140,"y":280,"wires":[["9b28d83a.0226d"]]},{"id":"9b28d83a.0226d","type":"function","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"Process Token","func":"msg.token = JSON.parse(msg.payload).token;\nmsg.tokenBytes = Buffer.from(msg.token);\nmsg.shiftedBytes = Buffer.concat([msg.tokenBytes.slice(1), msg.tokenBytes.slice(0, 1)]);\nmsg.shiftedToken = msg.shiftedBytes.toString();\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":150,"y":320,"wires":[["bc5b206f4b80b029"]]},{"id":"bc5b206f4b80b029","type":"md5","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"MD5","fieldToHash":"shiftedToken","fieldTypeToHash":"msg","hashField":"md5Hash","hashFieldType":"msg","x":120,"y":360,"wires":[["09f4eac7c81a8f68","372632c4f60d8424"]]},{"id":"36db2ee7d9dbc9dc","type":"json","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"","property":"payload","action":"","pretty":false,"x":120,"y":440,"wires":[["029b804564b2042d"]]},{"id":"372632c4f60d8424","type":"http request","z":"2447f70b5f1095ba","g":"66fed02de14cd5a7","name":"API Request","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://api.drivstoffappen.no/api/v1/brands?stationTypeId=1","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"X-API-KEY","valueType":"msg","valueValue":"md5Hash"},{"keyType":"other","keyValue":"X-CLIENT-ID","valueType":"other","valueValue":"com.raskebiler.drivstoff.appen.ios"}],"x":130,"y":610,"wires":[["77f438e4db6a6f68"]]},{"id":"77f438e4db6a6f68","type":"json","z":"2447f70b5f1095ba","g":"66fed02de14cd5a7","name":"","property":"payload","action":"","pretty":false,"x":110,"y":650,"wires":[["82d67472bd4bb8a0"]]},{"id":"82d67472bd4bb8a0","type":"change","z":"2447f70b5f1095ba","g":"66fed02de14cd5a7","name":"set flow.brands","rules":[{"t":"set","p":"brands","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":140,"y":690,"wires":[[]]},{"id":"09f4eac7c81a8f68","type":"http request","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"API Request","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://api.drivstoffappen.no/api/v1/stations?stationTypeId=1","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"X-API-KEY","valueType":"msg","valueValue":"md5Hash"},{"keyType":"other","keyValue":"X-CLIENT-ID","valueType":"other","valueValue":"com.raskebiler.drivstoff.appen.ios"}],"x":140,"y":400,"wires":[["36db2ee7d9dbc9dc"]]},{"id":"32028735556d59eb","type":"comment","z":"2447f70b5f1095ba","g":"66fed02de14cd5a7","name":"Hente \"brands\" fra drivstoffappen","info":"","x":170,"y":570,"wires":[]},{"id":"029b804564b2042d","type":"change","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"set flow.stationsRaw","rules":[{"t":"set","p":"stationsRaw","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":480,"wires":[["e6a31dc9dfb2064d"]]},{"id":"d9262ca78f365ae0","type":"comment","z":"2447f70b5f1095ba","g":"19e9dd7c0992a4db","name":"Hente \"stations\" fra drivstoffappen","info":"","x":180,"y":240,"wires":[]},{"id":"6d9e547c291b0fbc","type":"delay","z":"2447f70b5f1095ba","name":"+1 gang","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":420,"y":530,"wires":[["920c8e464a11c598"]]},{"id":"e6a31dc9dfb2064d","type":"change","z":"2447f70b5f1095ba","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"stationsPrepd","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":480,"wires":[["6d9e547c291b0fbc","920c8e464a11c598","c622a1c1b5d187fe"]]},{"id":"5301761a12ee53d3","type":"ui_button","z":"2447f70b5f1095ba","g":"1187eef693a5d073","name":"","group":"c5147f5beba7be52","order":23,"width":"3","height":"2","passthru":false,"label":"Oppdater","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":120,"y":150,"wires":[["fb25d94b.139e78"]]},{"id":"77e67d4e89c2c546","type":"group","z":"2447f70b5f1095ba","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["dc20c0baebcded39","52943a1fc077d28f","7014c2032a87fc3b","671050bdedc0c3cb","8e502b90702d3857","b1eaf76d80b124b2","13527989f83e29d2","a789bc33845b6aae","28fe85a134fe0971","dfb010ed7eafaf57","f10d3ac86fabfb52","4fdfe701f4a3afa0","920c8e464a11c598","80fadd7556b173c2","a25c248dc4ebd8e1","4845524c229e5de4","4bc7a1bfe0edbd3d","a0ed1589c7578ebc","313d717f04abb611","df6111373c9fcb74","9115f8c79d2fb5bf","bb875534cb2f1287","ef238c7de03c89ba","342412d6ccffa890","deb634361ea88282","7d2c0b671fe55eb5","73f01377bb3987bb","2ca32bed009a91c7","c4e4ad48e1be3967","fedddf6d961e47e1","f004caf9b1859658","f280cce61136ea5f","35afefb923880a86","13a80ea70008ef69","de080617e02b76c0","efb09c551659ae8e","c9be417364a0636a","c1e1c529d2ebbbe3","ba85ec803b447086","575ebc0b7826b668","a5b30e2c9a5b185b","5cdf4a4e44ba3e96","7907e0a5a1ff80b6","ee11d26aa7381961","c6597ae705c493fd","197fde062f906fe2","d3117ab9bbdc344d","a76caa7a16bac95c","99fbdbd6f1247a74","f41e2331b0b830d3","98ad46a8c1cec362","b4db27ab8e1249f9","211a49ea39c47dbf","345e2bc8bcaeeffd","f3a5b1da15641fda","f82266bbecc5f929","7ec8a975f4e62ea5","b4c42883c0d1b421","89f905a2a16a5653","bd92fd80ba8708f5","919354dd3a9d85e1","af920dde227a02ba","42965b35532dc0a6","198ea5a17cf29258","591771770c56781a","72b2d1bb06c9fd47","835b0df2bd3edcbb","69d3c375167219d4","e329d720082ab3ca"],"x":534,"y":9,"w":1182,"h":742},{"id":"2835c4be2e0c346c","type":"subflow","name":"subDrivstoffpris","info":"","category":"","in":[{"x":60,"y":80,"wires":[{"id":"629ced2da13dc595"}]}],"out":[{"x":440,"y":50,"wires":[{"id":"629ced2da13dc595","port":0}]},{"x":440,"y":110,"wires":[{"id":"629ced2da13dc595","port":1}]}],"env":[{"name":"station","type":"str","value":""},{"name":"statInt","type":"str","value":""},{"name":"statInt_Prev","type":"str","value":""}],"meta":{"version":"1.0","author":"SveinHa"},"color":"#DDAA99","outputLabels":["Trend","Skilt"]},{"id":"629ced2da13dc595","type":"function","z":"2835c4be2e0c346c","name":"Hjernen ;-)","func":"let sid = msg.id;\nvar station = msg.station;\nvar statInt = msg.statInt;\n//var statInt_Prev = statInt_Prev;\n\nvar prev = 0;\nvar diff = 0;\nvar msg2 = {}\n//console.log(msg.payload);\n//msg.payload = msg.payload.filter((/** @type {{ id: string; }} */ e) => e.id == sid);\nmsg.payload = msg.payload.filter((e) => e.id == sid);\n//console.log(msg.payload[0].brandId);\n//node.warn(msg);\n\n//msg.payload = msg.payload.filter((/** @type {{ discountInfo: string; }} */ e) => e.discountInfo == station); \n//console.log(msg.payload[0].prices.D.type);\n//msg.payload[0].type = msg.payload[0].prices.D.type;//.filter(e => e.type == 'D');\nvar price = msg.payload[0].prices.D.price;\n//console.log(price);\nvar now = Number(new Date());\nvar age = (now - msg.payload[0].prices.D.lastUpdated) / 3600 / 1000; //age in hours\nvar diffSymbol = \"\";\nflow.set(\"$parent.\" + statInt, price);\nprev = flow.get(\"$parent.\" + statInt + \"_Prev\") || 0\n\n//node.warn(\"ID: \" + msg.payload[0].id + \", name: \" + msg.payload[0].name + \", brand: \" + msg.payload[0].brand );\n\nvar snitt = flow.get(\"$parent.AvgPrice\");\nvar min = flow.get(\"$parent.MinPrice\");\nvar max = flow.get(\"$parent.MaxPrice\");\nvar lolim = snitt - ((max - min)/6);\nvar hilim = snitt + ((max - min)/6);\nif (price < lolim) msg2.color = \"LIME\";\nelse if (price > hilim) msg2.color = \"RED\";\nelse msg2.color = \"YELLOW\";\n//node.warn(min + \"-\" + lolim + \"-\" + snitt + \"-\" + hilim + \"-\" + max);\n\nif (price != prev) {\n    var ts = new Date();\n    flow.set(\"$parent.\" + statInt + \"_Diff\", Number((price - prev).toFixed(2)));\n    flow.set(\"$parent.\" + statInt + \"_Prev\", price);\n    flow.set(\"$parent.\" + statInt + \"_PrevT\", Number(ts));\n}\n\ndiff = flow.get(\"$parent.\" + statInt + \"_Diff\") || \"-\"\nvar tss = flow.get(\"$parent.\" + statInt + \"_PrevT\") || 0\nvar ageD = Number((Number(now) - Number(tss))) / 3600 / 1000; //age in hours\nif (ageD > 999.9) ageD = 999.9;\n\nif (diff >= 0) diffSymbol = \"<font color=RED> \" + diff;//.toFixed(2);\nelse diffSymbol = \"<font color=LIME> \" + diff;//.toFixed(2);\nflow.set(\"$parent.\" + statInt + \"_DiffS\", diffSymbol);\n\ndiffSymbol = flow.get(\"$parent.\" + statInt + \"_DiffS\") || \"-\"\nmsg2.payload = \"<font size=6>\" + price.toFixed(2) + \"<font size=2>\" + diffSymbol + \"(\" + ageD.toFixed(1) + \"h)\";\nmsg2.topic = station.slice(0,15);    //Forkort for lange navn\nmsg2.age = age.toFixed(1);\nif (age < 1) { msg2.stationcolor = \"LIME\"; }\nelse if (age < 6) { msg2.stationcolor = \"YELLOW\"; }\nelse if (age <= 12) { msg2.stationcolor = \"ORANGE\"; }\nelse if (age > 12) { msg2.stationcolor = \"RED\"; }\n\n//node.warn(msg2.topic + \"Price: \" + price + \" Prev: \" + prev + \"Diff: \" + diff);\nmsg2.pri  = flow.get(\"$parent.\" + statInt + \"_Pri\") \n//node.send([null,msg2]);\n//node.warn(\"$parent.\" + statInt + \"-\" + msg2.pri);\nmsg2.src = msg.payload[0].logo;\n\nmsg.payload = Number(price.toFixed(2));\nmsg.topic = station;\n\nreturn [msg, msg2];","outputs":2,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":220,"y":80,"wires":[[],[]]},{"id":"dc20c0baebcded39","type":"persist in","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Dieselpriser","storageNode":"8a6654beead70801","x":1500,"y":690,"wires":[]},{"id":"52943a1fc077d28f","type":"persist out","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Dieselpriser","storageNode":"8a6654beead70801","x":1280,"y":690,"wires":[["835b0df2bd3edcbb"]]},{"id":"7014c2032a87fc3b","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":5,"width":"6","height":"2","name":"Price 1","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":140,"wires":[]},{"id":"671050bdedc0c3cb","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":15,"width":"6","height":"2","name":"Price 6","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":440,"wires":[]},{"id":"8e502b90702d3857","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":17,"width":"6","height":"2","name":"Price 7","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":500,"wires":[]},{"id":"b1eaf76d80b124b2","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":13,"width":"6","height":"2","name":"Price 5","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":380,"wires":[]},{"id":"13527989f83e29d2","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":3,"width":"6","height":"2","name":"Price 0","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":80,"wires":[]},{"id":"a789bc33845b6aae","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":9,"width":"6","height":"2","name":"Price 3","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":260,"wires":[]},{"id":"28fe85a134fe0971","type":"debug","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"debug 89","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":590,"wires":[]},{"id":"dfb010ed7eafaf57","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Last update","func":"msg.label = \"Siste oppdatering\";\n//var d = new Date(msg.headers.date);\nvar d = new Date();\n//node.warn(d);\nmsg.payload = d.toLocaleString('nb-NO' );//.slice(0,16);\n//node.warn(msg.payload);\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":520,"wires":[["f10d3ac86fabfb52","a25c248dc4ebd8e1"]]},{"id":"f10d3ac86fabfb52","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":24,"width":"6","height":"2","name":"Siste oppdat","label":"{{msg.label}}","format":"{{msg.payload}}","layout":"row-left","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1090,"y":520,"wires":[]},{"id":"4fdfe701f4a3afa0","type":"comment","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Vis utvalgte dieselpriser m/trend","info":"","x":690,"y":50,"wires":[]},{"id":"920c8e464a11c598","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":560,"y":360,"wires":[["28fe85a134fe0971","dfb010ed7eafaf57","313d717f04abb611","7d2c0b671fe55eb5","9115f8c79d2fb5bf","bb875534cb2f1287","ef238c7de03c89ba","342412d6ccffa890","deb634361ea88282","73f01377bb3987bb","efb09c551659ae8e","c1e1c529d2ebbbe3","7907e0a5a1ff80b6","72b2d1bb06c9fd47"]]},{"id":"80fadd7556b173c2","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":25,"width":"6","height":"1","name":"Legend","label":"<font color=\"LIME\"><1h <font color=\"YELLOW\"><6h <font color=\"ORANGE\"><=12h <font color=\"RED\">>12h<font color=#43464B>","format":"","layout":"row-left","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1080,"y":590,"wires":[]},{"id":"a25c248dc4ebd8e1","type":"change","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"flow.get.AvgPrice","rules":[{"t":"set","p":"payload","pt":"msg","to":"AvgPrice","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":590,"wires":[["80fadd7556b173c2","4845524c229e5de4","575ebc0b7826b668"]]},{"id":"4845524c229e5de4","type":"change","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"Snitt","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1090,"y":560,"wires":[[]]},{"id":"4bc7a1bfe0edbd3d","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":7,"width":"6","height":"2","name":"Price 2","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":200,"wires":[]},{"id":"a0ed1589c7578ebc","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":11,"width":"6","height":"2","name":"Price 4","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":320,"wires":[]},{"id":"313d717f04abb611","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Esso Avaldsnes","func":"msg.id = 203;                   // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Esso Avaldsnes'; // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'EssoAval';       // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":120,"wires":[["df6111373c9fcb74"]]},{"id":"df6111373c9fcb74","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":120,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"9115f8c79d2fb5bf","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Uno-X Avaldsnes","func":"msg.id = 137;                       // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Uno-X Avaldsnes';    // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'UnoXAval';           // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":200,"wires":[["c4e4ad48e1be3967"]]},{"id":"bb875534cb2f1287","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"YX 7-Eleven Norheim","func":"msg.id = 269;                           // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'YX 7-Eleven Norheim';    // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'YX7ENorh';               // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":750,"y":240,"wires":[["fedddf6d961e47e1"]]},{"id":"ef238c7de03c89ba","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Tanken Helganes - Flyplassvegen","func":"msg.id = 1546;                                      // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Tanken Helganes - Flyplassvegen';    // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'TankFlyp';                           // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":280,"wires":[["f004caf9b1859658"]]},{"id":"342412d6ccffa890","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Cirkle K Kvala","func":"msg.id = 187;                   // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Circle K Kvala'; // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'CirKKval';       // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":320,"wires":[["f280cce61136ea5f"]]},{"id":"deb634361ea88282","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Revheim Storbilvask","func":"msg.id = 22828;                         // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Revheim Storbilvask';    // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'RevhStor';               // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":750,"y":360,"wires":[["35afefb923880a86"]]},{"id":"7d2c0b671fe55eb5","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Esso Raglamyr","func":"msg.id = 216;                   // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Esso Raglamyr';  // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'EssoRagl';       // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":160,"wires":[["2ca32bed009a91c7"]]},{"id":"73f01377bb3987bb","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Shell Norheim","func":"msg.id = 1342;                  // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Shell Norheim';  // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'ShelNorh';       // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":400,"wires":[["13a80ea70008ef69"]]},{"id":"2ca32bed009a91c7","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":160,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"c4e4ad48e1be3967","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":200,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"fedddf6d961e47e1","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":240,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"f004caf9b1859658","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":280,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"f280cce61136ea5f","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":320,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"35afefb923880a86","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":360,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"13a80ea70008ef69","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":400,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"de080617e02b76c0","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Beregn snittpris","func":"var sum = 0;\nvar temp = 0;\nvar antall = 0;\nvar minPrice = 999;\nvar maxPrice = 0;\n\nflow.keys().forEach(function(element) {\n//    if(element.substring(element.length -5,element.length)!=\"_Prev\"){\n    if(element.slice(-5) == \"_Prev\"){\n        temp = flow.get(element.slice(0, element.length -5));\n        sum += temp;\n        antall += 1;\n        if (temp > maxPrice) maxPrice = temp;\n        if (temp < minPrice) minPrice = temp;\n        //node.warn(element.slice(0,element.length -5) + \" Sum: \" + sum + \" Antall: \" + antall + \" temp: \" + temp);\n    }\n})\nmsg.payload = (sum / antall).toFixed(2);\nflow.set(\"AvgPrice\", Number(msg.payload));\nflow.set(\"MaxPrice\", Number(maxPrice));\nflow.set(\"MinPrice\", Number(minPrice));\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":900,"y":660,"wires":[["ba85ec803b447086"]]},{"id":"efb09c551659ae8e","type":"delay","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":710,"y":660,"wires":[["de080617e02b76c0"]]},{"id":"c9be417364a0636a","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Sorter på pris, store in flow","func":"var statList = []\nvar i = 0;\nvar temp = \"\";\n// Hent alle stasjoner of pris\nflow.keys().forEach(function(element) {\n    if(element.slice(-5) == \"_Prev\"){\n        temp = flow.get(element.slice(0, element.length -5));\n        var name = element.slice(0, element.length - 5);\n        var value = flow.get(element.slice(0, element.length - 5));\n        statList.push({ name, value });\n    }\n})\n// Sort lav->høy pris\nstatList.sort( (A,B) => A.value - B.value ) \n//node.warn((statList));\nstatList.forEach(function(element) {\n    flow.set(element.name + \"_Pri\", i);\n    i++;\n//    node.warn(element);\n})","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":940,"y":710,"wires":[[]]},{"id":"c1e1c529d2ebbbe3","type":"delay","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":720,"y":710,"wires":[["c9be417364a0636a"]]},{"id":"ba85ec803b447086","type":"debug","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Snittpris","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1080,"y":660,"wires":[]},{"id":"575ebc0b7826b668","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":26,"width":"6","height":"1","name":"Legend price","label":"","format":"<font color=\"LIME\" size=5>1/3 < <font color=\"YELLOW\">{{msg.payload}}<font color=\"RED\">< 1/3","layout":"row-left","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1090,"y":620,"wires":[]},{"id":"a5b30e2c9a5b185b","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":19,"width":"6","height":"2","name":"Price 8","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":560,"wires":[]},{"id":"5cdf4a4e44ba3e96","type":"ui_text","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","order":21,"width":"6","height":"2","name":"Price 9","label":"<font color=\"{{msg.stationcolor}}\">{{msg.topic}} ({{msg.age}}h)","format":"<font color=\"{{msg.color}}\">Kr.{{msg.payload}}","layout":"col-center","className":"","style":false,"font":"","fontSize":"","color":"#000000","x":1630,"y":620,"wires":[]},{"id":"7907e0a5a1ff80b6","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"CircleK Hafrsfjord","func":"msg.id = 3691;                  // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'CircleK Hafrsfjord';  // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'CirKHafr';       // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":440,"wires":[["ee11d26aa7381961"]]},{"id":"ee11d26aa7381961","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":440,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"c6597ae705c493fd","type":"subflow:2835c4be2e0c346c","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","x":1100,"y":480,"wires":[["69d3c375167219d4"],["e329d720082ab3ca"]]},{"id":"197fde062f906fe2","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 0","width":"2","height":"2","order":2,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":50,"wires":[[]]},{"id":"d3117ab9bbdc344d","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 1","width":"2","height":"2","order":4,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":110,"wires":[[]]},{"id":"a76caa7a16bac95c","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 2","width":"2","height":"2","order":6,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":170,"wires":[[]]},{"id":"99fbdbd6f1247a74","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 3","width":"2","height":"2","order":8,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":230,"wires":[[]]},{"id":"f41e2331b0b830d3","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 4","width":"2","height":"2","order":10,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":290,"wires":[[]]},{"id":"98ad46a8c1cec362","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 5","width":"2","height":"2","order":12,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":350,"wires":[[]]},{"id":"b4db27ab8e1249f9","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 6","width":"2","height":"2","order":14,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":410,"wires":[[]]},{"id":"211a49ea39c47dbf","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 7","width":"2","height":"2","order":16,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":470,"wires":[[]]},{"id":"345e2bc8bcaeeffd","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 8","width":"2","height":"2","order":18,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":530,"wires":[[]]},{"id":"f3a5b1da15641fda","type":"ui_media","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","group":"c5147f5beba7be52","name":"Brand 9","width":"2","height":"2","order":20,"category":"","file":"","layout":"adjust","showcontrols":false,"loop":false,"onstart":false,"scope":"local","tooltip":"","x":1630,"y":590,"wires":[[]]},{"id":"f82266bbecc5f929","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":70,"wires":[["13527989f83e29d2","197fde062f906fe2"]]},{"id":"7ec8a975f4e62ea5","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":130,"wires":[["7014c2032a87fc3b","d3117ab9bbdc344d"]]},{"id":"b4c42883c0d1b421","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":190,"wires":[["4bc7a1bfe0edbd3d","a76caa7a16bac95c"]]},{"id":"89f905a2a16a5653","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":250,"wires":[["a789bc33845b6aae","99fbdbd6f1247a74"]]},{"id":"bd92fd80ba8708f5","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":300,"wires":[["a0ed1589c7578ebc","f41e2331b0b830d3"]]},{"id":"919354dd3a9d85e1","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":360,"wires":[["b1eaf76d80b124b2","98ad46a8c1cec362"]]},{"id":"af920dde227a02ba","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":420,"wires":[["b4db27ab8e1249f9","671050bdedc0c3cb"]]},{"id":"42965b35532dc0a6","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":490,"wires":[["8e502b90702d3857","211a49ea39c47dbf"]]},{"id":"198ea5a17cf29258","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":550,"wires":[["a5b30e2c9a5b185b","345e2bc8bcaeeffd"]]},{"id":"591771770c56781a","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1530,"y":610,"wires":[["5cdf4a4e44ba3e96","f3a5b1da15641fda"]]},{"id":"72b2d1bb06c9fd47","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"Uno-X Tananger","func":"msg.id = 3589;                  // StasjonsID fra Drivstoffappen. Finnes i generelt \"Drivstoff\" tab.\nmsg.station = 'Uno-X Tananger';  // Visningsnavn. Kan tilpasses da stasjonsnavn i drivstoffappen ikke alltid er like beskrivende\nmsg.statInt = 'UnoXTana';       // Unikt kortnavn, 8 tegn, for bruk  i flow-variabler\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":480,"wires":[["c6597ae705c493fd"]]},{"id":"835b0df2bd3edcbb","type":"ui_chart","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"","group":"c5147f5beba7be52","order":1,"width":"32","height":"20","label":"Dieselpris (4u).","chartType":"line","legend":"true","xformat":"dddd","interpolate":"step","nodata":"No data...","dot":false,"ymin":"","ymax":"","removeOlder":"4","removeOlderPoints":"","removeOlderUnit":"604800","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#f9fafa","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#0501f9","#9467bd","#f5ed00"],"outputs":1,"useDifferentColor":false,"className":"","x":1410,"y":640,"wires":[["dc20c0baebcded39"]]},{"id":"69d3c375167219d4","type":"junction","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","x":1240,"y":630,"wires":[["835b0df2bd3edcbb"]]},{"id":"e329d720082ab3ca","type":"function","z":"2447f70b5f1095ba","g":"77e67d4e89c2c546","name":"pri-pens","func":"switch (msg.pri){\n    case 0:\n    return [msg,null,null,null,null,null,null,null,null,null]\n    case 1:\n    return [null,msg,null,null,null,null,null,null,null,null]\n    case 2:\n    return [null,null,msg,null,null,null,null,null,null,null]\n    case 3:\n    return [null,null,null,msg,null,null,null,null,null,null]\n    case 4:\n    return [null,null,null,null,msg,null,null,null,null,null]\n    case 5:\n    return [null,null,null,null,null,msg,null,null,null,null]\n    case 6:\n    return [null,null,null,null,null,null,msg,null,null,null]\n    case 7:\n    return [null,null,null,null,null,null,null,msg,null,null]\n    case 8:\n    return [null,null,null,null,null,null,null,null,msg,null]\n    case 9:\n    return [null,null,null,null,null,null,null,null,null,msg]\n}\n","outputs":10,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1370,"y":310,"wires":[["f82266bbecc5f929"],["7ec8a975f4e62ea5"],["b4c42883c0d1b421"],["89f905a2a16a5653"],["bd92fd80ba8708f5"],["919354dd3a9d85e1"],["af920dde227a02ba"],["42965b35532dc0a6"],["198ea5a17cf29258"],["591771770c56781a"]]},{"id":"8a6654beead70801","type":"persist-store","filename":"persist-diesel.json","interval":"600"},{"id":"0d788a3660f620b1","type":"ui_group","name":"Drivstoffpriser","tab":"1083c01bcc75e66c","order":1,"disp":true,"width":"40","collapse":false,"className":""},{"id":"c5147f5beba7be52","type":"ui_group","name":"Wide","tab":"8b4128994ad0c3a1","order":2,"disp":false,"width":"40","collapse":false,"className":""},{"id":"1083c01bcc75e66c","type":"ui_tab","name":"Drivstoff","icon":"local_gas_station","order":24,"disabled":false,"hidden":false},{"id":"8b4128994ad0c3a1","type":"ui_tab","name":"Dieselpriser","icon":"drive_eta","order":23,"disabled":false,"hidden":false}]

 

 

Regner med denne flow bare er å importere men må nok ha 2 opppdateringer av pris før tallene begynner å rime...

 

Persist nodene er viktige på slike chart der tidsspennet er 1 mnd. (trasig å miste historikken ved blink i lyset...).

  • Like 2
Lenke til kommentar
Del på andre sider

  • 2 uker senere...

Hei,

Nokså fersk i på dette feltet. men dere har fått dette til å funke?
Lurer bare på om noen kan hjelpe meg å få det til og 🙂

Lenke til kommentar
Del på andre sider

Noen der har kode hvis man har abonnement og vil få hentet data.
Fibaro støtter nemlig ikke eksterne luamoduler som md5 og utf8
EDIT!
Kom litt videre så nu har jeg den rigtige token , men hvordan den skal brukes eller konveteres vet jeg ikke. 😅

NeoID skrev (På 14.1.2024 den 16.21):

Jeg kan bekrefte at jeg har en løsning som fungerer. Vet hjelp av brukernavn, password og token får jeg nå ut en gyldig X-API-KEY 🙂

 

Endret av mike79
glemte tekst
Lenke til kommentar
Del på andre sider

  • 2 måneder senere...
  • 2 måneder senere...
NeoID skrev (På 5.2.2024 den 20.34):

Er ikke helt ferdig med API'et enda pga sykdom og andre ting som må prioriteres, men her er koden for de av dere som er interessert. Det vil genere en gyldig X-API-KEY, helt uten brukernavn eller passord. 😛
 

def get_api_key():
    # Get the session token
    r = requests.get('https://api.drivstoffappen.no/api/v1/authorization-sessions')
    api_token = r.json().get('token')

    # Shift the string by one byte
    shifted_bytes = bytearray(api_token.encode('utf-8'))[1:] + bytearray([api_token.encode('utf-8')[0]])
    shifted_string = shifted_bytes.decode('utf-8')

    # Calculate the MD5 hash of the shifted string
    md5_hash = hashlib.md5(shifted_string.encode('utf-8')).hexdigest()

    return md5_hash


Så kan du gjøre spørring via:
 

@app.get('/api/v1/brands')
async def get_brands():
    headers = { 'X-API-KEY': get_api_key(), 'X-CLIENT-ID': APPLICATION_ID }
    r = requests.get('https://api.drivstoffappen.no/api/v1/brands', headers=headers)

    if not r.ok:
        return {"error": f"Request failed with status code {r.status_code}"}
    return r.json()

 

Er der kommet nye Url, jeg får status 401

Endret av mike79
Lenke til kommentar
Del på andre sider

  • 2 måneder senere...
On 06/02/2024 at 22:23, feddiriko said:

Takk, fungerte bra. Aldri brukt Node-Red før, men her er flowen min. 

 

[{"id":"7ce7a7849c9c8b4e","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"276071b26f3e49a2","type":"inject","z":"7ce7a7849c9c8b4e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":220,"wires":[["fb25d94b.139e78"]]},{"id":"fb25d94b.139e78","type":"http request","z":"7ce7a7849c9c8b4e","name":"Get Token","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://api.drivstoffappen.no/api/v1/authorization-sessions","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":330,"y":220,"wires":[["9b28d83a.0226d"]]},{"id":"9b28d83a.0226d","type":"function","z":"7ce7a7849c9c8b4e","name":"Process Token","func":"msg.token = JSON.parse(msg.payload).token;\nmsg.tokenBytes = Buffer.from(msg.token);\nmsg.shiftedBytes = Buffer.concat([msg.tokenBytes.slice(1), msg.tokenBytes.slice(0, 1)]);\nmsg.shiftedToken = msg.shiftedBytes.toString();\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":220,"wires":[["bc5b206f4b80b029"]]},{"id":"17f2e29c.f0c2b3","type":"http request","z":"7ce7a7849c9c8b4e","name":"API Request","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://api.drivstoffappen.no/api/v1/stations?stationTypeId=1","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"X-API-KEY","valueType":"msg","valueValue":"md5Hash"},{"keyType":"other","keyValue":"X-CLIENT-ID","valueType":"other","valueValue":"com.raskebiler.drivstoff.appen.ios"}],"x":850,"y":220,"wires":[["77f3986f.d5f32c"]]},{"id":"77f3986f.d5f32c","type":"debug","z":"7ce7a7849c9c8b4e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1030,"y":220,"wires":[]},{"id":"bc5b206f4b80b029","type":"md5","z":"7ce7a7849c9c8b4e","name":"MD5","fieldToHash":"shiftedToken","fieldTypeToHash":"msg","hashField":"md5Hash","hashFieldType":"msg","x":690,"y":220,"wires":[["17f2e29c.f0c2b3"]]}]

Denne fungerer finfint, men ser ut til at min NodRed ikke takler den store datamangden som kommer i retur. Er det noen enkel måte å feks begrense dataforespørselen til Oslo?

Endret av Fjosepose
Lenke til kommentar
Del på andre sider

On 20/10/2024 at 16:18, Fjosepose said:

men ser ut til at min NodRed ikke takler den store datamangden som kommer i retur.


Node-Red kan takle mange GB så lenge du har nok minne 🙂

 

Debug.output viser ikkje all data men den er der.

Ligg inn denne function noden mellom API request og debug.output

 

[{"id":"f1b6358c9bf2e78e","type":"function","z":"7ce7a7849c9c8b4e","name":"Split Payload","func":"// Function Node: Split Payload into Individual Messages\n\n// Initialize an array to hold the new messages\nlet messages = [];\n\n// Function to send error and stop processing\nfunction sendError(errorMsg) {\n    node.error(errorMsg, msg);\n    return null;\n}\n\ntry {\n    // Step 1: Parse the payload if it's a string\n    let data;\n    if (typeof msg.payload === 'string') {\n        data = JSON.parse(msg.payload);\n    } else if (Buffer.isBuffer(msg.payload)) {\n        // If payload is a Buffer, convert to string and parse\n        data = JSON.parse(msg.payload.toString());\n    } else {\n        // If payload is already an object/array\n        data = msg.payload;\n    }\n\n    // Step 2: Ensure the parsed data is an array\n    if (!Array.isArray(data)) {\n        return sendError(\"Payload is not an array.\");\n    }\n\n    // Step 3: Iterate over each station object in the array\n    data.forEach((station, index) => {\n        // Create a new message for each station\n        let newMsg = {\n            _msgid: `${msg._msgid}-${index}`, // Optional: unique message ID\n            payload: station,\n        };\n        messages.push(newMsg);\n    });\n\n    // Step 4: Return the array of messages\n    return messages;\n\n} catch (error) {\n    // Handle JSON parsing errors or other exceptions\n    return sendError(`Error processing payload: ${error.message}`);\n}","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":340,"wires":[["77f3986f.d5f32c"]]}]

 

Lenke til kommentar
Del på andre sider

Bli med i samtalen

Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.