jassak
Published © GPL3+

MQTT OBD Vehicle Telemetry

Fancy to see your's vehicle data online in real-time? If so, continue reading!

AdvancedFull instructions provided4,237
MQTT OBD Vehicle Telemetry

Things used in this project

Hardware components

Arduino MKR1000
Arduino MKR1000
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1
u-blox NEO-6M
GPS module
×1
ELM327
×1

Story

Read more

Schematics

ELM327 + NEO-6M connection to Arduino MRK1000

Wiring diagram

Code

Main .ino file

Arduino
#include <WiFi101.h>
#include <WiFiSSLClient.h>    //ak by sme bezali cez SSL (8883)
#include <MQTTClient.h>
#include <wiring_private.h>
#include <TinyGPS++.h>
#include "premenne.h"



/*****************************************/
/*        Serial2                        */
/*****************************************/

#define PIN_SERIAL2_RX       (1ul)                
#define PIN_SERIAL2_TX       (0ul)                
#define PAD_SERIAL2_TX       (UART_TX_PAD_0)      
#define PAD_SERIAL2_RX       (SERCOM_RX_PAD_1)   

Uart Serial2(&sercom3, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);

void SERCOM3_Handler()    
{
  Serial2.IrqHandler();
}



/*****************************************/
/*        WiFi                           */
/*****************************************/

char *ssid = "WIFI_AP";
char *pass = "AP_PWD_37";

WiFiClient net; // Vytvorime WiFi klienta, ktory sa vie pripojit k specifickej adrese a portu


/*****************************************/
/*        MQTT                          */
/*****************************************/

#define ORG "orgid"
#define DEVICE_TYPE "devid"
#define DEVICE_ID "devid2"
#define TOKEN "devtoken"

int status = WL_IDLE_STATUS;  // priradenie pre WiFi.status() docasny stav

char *client_id = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;
char *user_id = "use-token-auth";
char *pwd = TOKEN;
char *ibm_hostname = ORG ".messaging.internetofthings.ibmcloud.com";

/*****************************************/
/*        OSTATNE PREMENNE               */
/*****************************************/
unsigned long cas = 0;
TinyGPSPlus gps;
int awq=0;



/*****************************************/
/*        FUNKCIA PRE PRIPOJENIE         */
/*****************************************/

void connect_mqtt() {
  // Pokial nieje priopojene k wifi AP, bude vypisovat WIFI_CHYBA
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(" WIFI_CHYBA ");
    delay(1000);
  }

  // Pokial nieje pripojene k MQTT brokeru, bude vypisovat BROKER_CHYBA
  
  while (!client.connect(client_id, user_id, pwd)) {     // v zatvorke uvedene samotne pripojenie k vytvorenemu zariadeniu v IBM CLOUDE
    Serial.print(" BROKER_CHYBA ");
    delay(1000);
  }
  
  // Vypise pripojene, pri uspesnom pripojeni k AP a brokeru
  Serial.println("\nPripojene!");

  // ODBER TOPICU
  client.subscribe("iot-2/cmd/spojka/fmt/json");
}


/*****************************************/
/*        FUNKCIA NA SUBSCRIBE           */
/*****************************************/

void messageReceived(String &topic, String &payload) {
  int prevedene=payload.toInt();
  
  switch (prevedene) {
    case 1:
    statepmot=pTeplotum();
    client.publish("iot-2/evt/teplotam/fmt/json", statepmot);
    break;
    case 2:
    stanapat=pNapatie();
    client.publish("iot-2/evt/napatie/fmt/json", stanapat);
    break;
    case 3:
    stazta=pZatazm();
    client.publish("iot-2/evt/zatazm/fmt/json", stazta);
    break;
    case 4:
    stateplosan=pTeplotasania();
    client.publish("iot-2/evt/teplotasania/fmt/json", stateplosan);
    break;
    case 5:
    staotac=pOtacky();
    client.publish("iot-2/evt/otacky/fmt/json", staotac);
    break;
    case 6:
    starychl=pRychlost();
    client.publish("iot-2/evt/rychlost/fmt/json", starychl);
    break;
    case 7:
    staVIN=pVIN();
    client.publish("iot-2/evt/VIN/fmt/json", staVIN);
    break;
    case 8:
    Serial.println("Restart");
    break;
    case 9:
    statepmot=pTeplotum();
    client.publish("iot-2/evt/teplotam/fmt/json", statepmot);
    delay(2000);
    stanapat=pNapatie();
    client.publish("iot-2/evt/napatie/fmt/json", stanapat);
    delay(2000);
    stazta=pZatazm();
    client.publish("iot-2/evt/zatazm/fmt/json", stazta);
    delay(2000);
    stateplosan=pTeplotasania();
    client.publish("iot-2/evt/teplotasania/fmt/json", stateplosan);
    delay(2000);
    staotac=pOtacky();
    client.publish("iot-2/evt/otacky/fmt/json", staotac);
    delay(2000);
    starychl=pRychlost();
    client.publish("iot-2/evt/rychlost/fmt/json", starychl);
    delay(2000);
    staVIN=pVIN();
    client.publish("iot-2/evt/VIN/fmt/json", staVIN);
    delay(2000);
    break;
    case 10:
    awq=1;
    break;
    case 11:
    awq=2;
    break;
    case 12:
    awq=3;
    break;
    case 13:
    awq=4;
    break;
    case 14:
    awq=5;
    break;
    case 15:
    awq=6;
    break;
    case 16:
    awq=7;
    break;
    case 17:
    awq=8;
    break;
    case 18:
    awq=9;
    break;
    case 19:
    awq=10;
    break;
    case 20:
    awq=11;
    break;
    case 21:
    awq=12;
    break;
    case 22:
    awq=13;
    break;
    case 23:
    awq=14;
    break;
  }

}


/*****************************************/
/*        ARDUINO SETUP                  */
/*****************************************/

void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial1.begin(38400);   //SPUSTENIE RX TX PRE ELM327
  Serial1.println("atl1\r");   // ABY SLI ODPOVEDE NA NEW LINE
  delay(1000);
  Serial1.println("0105");
  delay(1000);
  pinPeripheral(1, PIO_SERCOM); 
  pinPeripheral(0, PIO_SERCOM);
  Serial2.begin(9600);
  
/*****************************************/
/*        Pripojenie k WiFi              */
/*****************************************/
  //Pokial nieje pripojeny k wifi, vypise nazov siete siete ku ktorej sa pripaja:
  while (status != WL_CONNECTED) {
    Serial.println("\nPripajam sa k wifi s nazvom: ");
    Serial.println(ssid);

   //WiFi.begin sluzi na pripojenie k sieti, pricom do premennej status priradi stav pripojenia (zmena pre zamzdzenie opakovania podmienky)
    status = WiFi.begin(ssid, pass);
   
    //Pockaj 10 sekund na pripojenie:
    if (status != WL_CONNECTED) {
      delay(10000);
    }
  }

/*****************************************/
/*        Pripojenie k MQTT brokeru      */
/*****************************************/
    //Pripojenie Arduina do IBM Cloudu pomocou kniznice MQTTClient.h
    client.begin(ibm_hostname, 1883, net);
    connect_mqtt();    
    client.onMessage(messageReceived);
}


/*****************************************/
/*        ARDUINO LOOP                   */
/*****************************************/
void loop() {

  client.loop(); // Spustenie MQTT publish/subscribe v slucke - jednoducho spracuva odosielane/prijate spravy
  delay(10);

  // Znova overenie ci sme pripojeny k AP a IBM Cloudu:
  
  if(!client.connected()) {
    
    connect_mqtt();
  }



  while (Serial2.available() > 0){
  gps.encode(Serial2.read());
  if (gps.location.isUpdated()){
    for(millis(); (millis() - cas) > 5000;){
    cas = millis();
      latitude=(gps.location.lat());
      longitude=(gps.location.lng());
  }
 }
}

if(awq==1){
  client.publish("iot-2/evt/VIN/fmt/json", String(longitude, 6));
  delay(1000);
  }
  else if(awq==2){
  client.publish("iot-2/evt/VIN/fmt/json", String(latitude, 6));
  delay(1000);
  }
  else if(awq==3){
  awq=0;
  }
  else if(awq==4){
  statepmot=pTeplotum();
  client.publish("iot-2/evt/dteplotam/fmt/json", statepmot);
  delay(2000);
  }
  else if(awq==5){
  stanapat=pNapatie();
  client.publish("iot-2/evt/dnapatie/fmt/json", stanapat);
  delay(2000);
  }
  else if(awq==6){
  starychl=pRychlost();
  client.publish("iot-2/evt/drychlost/fmt/json", starychl);
  delay(2000);  
  }
  else if(awq==7){
  staotac=pOtacky();
  client.publish("iot-2/evt/dotacky/fmt/json", staotac);
  delay(2000);  
  }
  else if(awq==8){
  stazta=pZatazm();
  client.publish("iot-2/evt/dzatazm/fmt/json", stazta);
  delay(2000);  
  }
  else if(awq==9){
  stateplosan=pTeplotasania();
  client.publish("iot-2/evt/dteplotasania/fmt/json", stateplosan);
  delay(2000);  
  }
  else if(awq==10){
  client.publish("iot-2/evt/suradnice/fmt/json",  pGPS());
  delay(2000);  
  }
  else if(awq==11){
  inba=GPSmotora();
  client.publish("iot-2/evt/suradnicemotor/fmt/json",  inba);
  delay(2000);  
  }
  else if(awq==12){
  inbc=pGPSnapatie();
  client.publish("iot-2/evt/suradnicenap/fmt/json",  inbc);
  delay(2000);  
  }
  else if(awq==13){
  inbd=pGPSRychl();
  client.publish("iot-2/evt/surarychl/fmt/json",  inbd);
  delay(2000);  
  }
  else if(awq==14){
  inbf=pGPSotacky();
  client.publish("iot-2/evt/suraotac/fmt/json",  inbf);
  delay(2000);  
  }


  
}

Header file premenne.h

Arduino
MQTTClient client(1024);  // Vytvorime MQTT klienta - 256 bytov urcuje velkost buffera (defaultne je 128 bytov)
float latitude=40.5;
float longitude=18.5;

String statepmot;
String engine_temp;  //1
String suengine_temp; 
int vengine_temp;

String stanapat;
String napatie;  //2
String snapatie;
int vnapatie;

String stazta;
String zatazm; //4
String szatazm;
int vzatazm;

String stateplosan;
String teplotasania;  //5
String steplotasania;
int vteplotasania;

String staotac;
String otackyA;  //6
String sotackyA;
int votackyA;
String otackyB;  //6
String sotackyB;
int votackyB;

String starychl;
String rychlost;  //7
String srychlost;
int vrychlost;

String staVIN;

String inba;
String inbc;
String inbd;
String inbf;

////////////////PREMENNE PRE VIN CISLO
String vincislo;
String podvincislo;
String vinpole[33];
String vinpole2[33];
String ziskanevin;
int vina=0;



////////////////////FUNKCIE

String pTeplotum(){
  Serial1.println("0105");
  engine_temp = Serial1.readString();
  suengine_temp=engine_temp.substring(12,14);
  vengine_temp = (strtol(suengine_temp.c_str(),NULL,16))-40; 
 
  
  String pengine_temp = "{\"TeplotaMotora\":";
  pengine_temp += vengine_temp;
  pengine_temp += "}";
  return pengine_temp;
}


String pNapatie(){
  Serial1.println("atrv");
  napatie = Serial1.readString();
  snapatie=napatie.substring(6,15);
  vnapatie=snapatie.toInt();
  Serial.println("PRVY RIADOK");
  Serial.println(napatie);
  Serial.println("DRUHY RIADOK");
  Serial.println(vnapatie);
  
  String p_napatie = "{\"Napatie\":";
  p_napatie += vnapatie;
  p_napatie += "}";
  return p_napatie;
}

String pZatazm(){
  Serial1.println("0104");
  zatazm = Serial1.readString();
  szatazm=zatazm.substring(12,14);
  vzatazm = (strtol(szatazm.c_str(),NULL,16))/2.55; 
  Serial.println(vzatazm);
  
  String p_zataz = "{\"ZatazMotora\":";
  p_zataz += vzatazm;
  p_zataz += "}";
  return p_zataz;
}

String pTeplotasania(){
  Serial1.println("010F");
  teplotasania = Serial1.readString();
  steplotasania=teplotasania.substring(12,14);
  vteplotasania = (strtol(steplotasania.c_str(),NULL,16))-40; 
  Serial.println(vteplotasania);
  
  String p_tesania = "{\"TeplotaSania\":";
  p_tesania += vteplotasania;
  p_tesania += "}";
  return p_tesania;
}

//////////*********
String pOtacky(){
  Serial1.println("010C");
  otackyA = Serial1.readString();
  sotackyA=otackyA.substring(12,14);
  sotackyB=otackyA.substring(15,17);
  votackyA = ((256*(strtol(sotackyA.c_str(),NULL,16)))+(strtol(sotackyB.c_str(),NULL,16)))/4; 
  Serial.println(votackyA);
  
  
  String p_otacky = "{\"Otacky\":";
  p_otacky += votackyA;
  p_otacky += "}";
  return p_otacky;
}


String pRychlost(){
  Serial1.println("010D");
  rychlost = Serial1.readString();
  srychlost=rychlost.substring(12,14);
  vrychlost = (strtol(srychlost.c_str(),NULL,16)); 
  Serial.println(vrychlost);
  
  String pcar_speed = "{\"Rychlost\":";
  pcar_speed += vrychlost;
  pcar_speed += "}";
  return pcar_speed;
}



String pGPSRychl(){
  Serial1.println("010D");
  rychlost = Serial1.readString();
  srychlost=rychlost.substring(12,14);
  vrychlost = (strtol(srychlost.c_str(),NULL,16)); 
  Serial.println(vrychlost);
  
  String pcar_speed = "{\"Longituda\":";
  pcar_speed += String(longitude, 6);
  pcar_speed += ",\"Latituda\":";
  pcar_speed += String(latitude, 6);
  pcar_speed += ",\"Rychlost\":";
  pcar_speed += vrychlost;
  pcar_speed += "}";
  return pcar_speed;
}

String pGPS(){
  String navka = "{\"Longituda\":";
  navka += String(longitude, 6);
  navka += ",\"Latituda\":";
  navka += String(latitude, 6);
  navka += "}";
  return navka;
}

String GPSmotora(){
  Serial1.println("0105");
  engine_temp = Serial1.readString();
  suengine_temp=engine_temp.substring(12,14);
  vengine_temp = (strtol(suengine_temp.c_str(),NULL,16))-40; 
 
  String pengine_temp = "{\"Longituda\":";
  pengine_temp += String(longitude, 6);
  pengine_temp += ",\"Latituda\":";
  pengine_temp += String(latitude, 6);
  pengine_temp += ",\"Teplota\":";
  pengine_temp += vengine_temp;
  pengine_temp += "}";
  return pengine_temp;
}


String pGPSnapatie(){
  Serial1.println("atrv");
  napatie = Serial1.readString();
  snapatie=napatie.substring(6,15);
  vnapatie=snapatie.toInt();
  
  String p_napatie = "{\"Longituda\":";
  p_napatie += String(longitude, 6);
  p_napatie += ",\"Latituda\":";
  p_napatie += String(latitude, 6);
  p_napatie += ",\"Napatie\":";
  p_napatie += vnapatie;
  p_napatie += "}";
  return p_napatie;
}



String pGPSotacky(){
  Serial1.println("010C");
  otackyA = Serial1.readString();
  sotackyA=otackyA.substring(12,14);
  sotackyB=otackyA.substring(15,17);
  votackyA = ((256*(strtol(sotackyA.c_str(),NULL,16)))+(strtol(sotackyB.c_str(),NULL,16)))/4; 
  Serial.println(votackyA);
  
  String p_otacky = "{\"Longituda\":";
  p_otacky += String(longitude, 6);
  p_otacky += ",\"Latituda\":";
  p_otacky += String(latitude, 6);
  p_otacky += ",\"Otacky\":";
  p_otacky += votackyA;
  p_otacky += "}";
  return p_otacky;
}

String pVIN(){
  Serial1.println("0902");
  vincislo = Serial1.readString();
  vincislo.replace("\n","");
  vincislo.replace(" ","");
  vincislo.replace(":","");
   podvincislo=vincislo.substring(15,21)+vincislo.substring(22,36)+vincislo.substring(37,51);
  for (int i=0; i<33; i++){
    if (i%2 == 0){
    vinpole[i]="0x"+(podvincislo.substring(i,i+2));
    vinpole2[i]=(char)(strtol((vinpole[i]).c_str(),NULL,16));
    }
  }
  while (vina<33){
   ziskanevin+=vinpole2[vina];
   vina+=2;
  }
  
  String pVIN = "{\"VIN\":\"";
  pVIN += ziskanevin;
  pVIN += "\"}";
  return pVIN;
}

Node-RED flow

JSON
[
    {
        "id": "5c322bcd.0d7e24",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "fe020458.d37fb8",
        "type": "ibmiot in",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "inputType": "evt",
        "logicalInterface": "",
        "ruleId": "",
        "deviceId": "IDkontroler",
        "applicationId": "",
        "deviceType": "Mikrokontroler",
        "eventType": "+",
        "commandType": "",
        "format": "json",
        "name": "IBM IoT",
        "service": "registered",
        "allDevices": "",
        "allApplications": "",
        "allDeviceTypes": false,
        "allLogicalInterfaces": "",
        "allEvents": true,
        "allCommands": "",
        "allFormats": false,
        "qos": 0,
        "x": 70,
        "y": 80,
        "wires": [
            [
                "82d427c1.5f1e38",
                "43f37536.a7fcec",
                "1435a819.13f948",
                "6388de69.38c86",
                "7b79441a.0c9a0c",
                "34e21a58.f23676",
                "4f372508.eed40c",
                "ffca5f60.a2836",
                "1d98f4df.46248b",
                "a0a16110.3d97d",
                "9cbffc43.6fae4",
                "804e7a.3d19e188",
                "c95b86aa.ff9988",
                "e2afa857.055908",
                "f050f736.555a78",
                "2887474f.3903a8",
                "c334c204.254a9",
                "a11eb45f.d38ef8",
                "9d5ef054.3aeed"
            ]
        ]
    },
    {
        "id": "c2fcb0e4.9df3c",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "IDkontroler",
        "deviceType": "Mikrokontroler",
        "eventCommandType": "spojka",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 840,
        "y": 620,
        "wires": []
    },
    {
        "id": "4f20b8e8.6d0368",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "b15ee046.8c935",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Engine temp",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"1\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 110,
        "y": 460,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "aec1cc46.8c43a",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "f7606a4e.234618",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Engine load",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"3\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 110,
        "y": 540,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "180233f4.ae6cdc",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "f943ae3.4d5b75",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Intake air temp",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"4\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 120,
        "y": 580,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "3da42317.916b5c",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "b3c559b3.3e97d8",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Battery voltage",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"2\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 120,
        "y": 500,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "29d384f.73d7a7c",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "34ec3061.6e984",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "RPM",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"5\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 90,
        "y": 620,
        "wires": [
            [
                "c2fcb0e4.9df3c",
                "91e819d.952aee8"
            ]
        ]
    },
    {
        "id": "93e16f5a.1cf5c",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "3fc295fe.9f49ca",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Velocity",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"6\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 100,
        "y": 660,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "f14580c0.81f91",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "3621392d.b91016",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "VIN",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"7\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 90,
        "y": 700,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "82d427c1.5f1e38",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/teplotam/fmt/json\":\n        return {payload:msg.payload.TeplotaMotora};\n        break;\n        \n     case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/teplotao/fmt/json\":\n        return {payload:msg.payload.TeplotaOleja};\n        break;\n        \n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/rychlost/fmt/json\":\n        return {payload:msg.payload.Rychlost};\n        break;\n    \n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/otacky/fmt/json\":\n        return {payload:msg.payload.Otacky};\n        break;\n    \n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/benzin/fmt/json\":\n        return {payload:msg.payload.Benzin};\n        break;\n    \n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/teplotav/fmt/json\":\n        return {payload:msg.payload.TeplotaVzduchu};\n        break;\n    \n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/dtcs/fmt/json\":\n        return {payload:msg.payload.DTCs};\n        break;\n        \n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/vycisti/fmt/json\":\n        return {payload:msg.payload.Vycisti};\n        break;     \n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 80,
        "wires": [
            [
                "5bd2c651.2adea8"
            ]
        ]
    },
    {
        "id": "5bd2c651.2adea8",
        "type": "debug",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 490,
        "y": 80,
        "wires": []
    },
    {
        "id": "43f37536.a7fcec",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/teplotam/fmt/json\":\n        return {payload:msg.payload.TeplotaMotora};\n}\n\n\n\n\n\n",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 120,
        "wires": [
            [
                "fe99fbd4.9109b8",
                "f2ad5cb4.ababd"
            ]
        ]
    },
    {
        "id": "1435a819.13f948",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/napatie/fmt/json\":\n        return {payload:msg.payload.Napatie};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 160,
        "wires": [
            [
                "e7e764ae.4ca5e8"
            ]
        ]
    },
    {
        "id": "6388de69.38c86",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/zatazm/fmt/json\":\n        return {payload:msg.payload.ZatazMotora};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 200,
        "wires": [
            [
                "7eadc7ad.7cf6e8"
            ]
        ]
    },
    {
        "id": "7b79441a.0c9a0c",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/teplotasania/fmt/json\":\n        return {payload:msg.payload.TeplotaSania};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 240,
        "wires": [
            [
                "45872dba.55fcd4"
            ]
        ]
    },
    {
        "id": "34e21a58.f23676",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/otacky/fmt/json\":\n        return {payload:msg.payload.Otacky};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 280,
        "wires": [
            [
                "2a0f2623.21943a"
            ]
        ]
    },
    {
        "id": "ffca5f60.a2836",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/VIN/fmt/json\":\n        return {payload:msg.payload.VIN};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 360,
        "wires": [
            [
                "f5ad1b10.a28e28"
            ]
        ]
    },
    {
        "id": "4f372508.eed40c",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/rychlost/fmt/json\":\n        return {payload:msg.payload.Rychlost};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 250,
        "y": 320,
        "wires": [
            [
                "57ee1e71.74562"
            ]
        ]
    },
    {
        "id": "e7e764ae.4ca5e8",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "napatieS",
        "group": "b3c559b3.3e97d8",
        "order": 2,
        "width": "6",
        "height": "4",
        "gtype": "wave",
        "title": "",
        "label": "V",
        "format": "{{value}}",
        "min": "0",
        "max": "15",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 480,
        "y": 160,
        "wires": []
    },
    {
        "id": "7eadc7ad.7cf6e8",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "f7606a4e.234618",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "%",
        "format": "{{value}}",
        "min": "0",
        "max": "100",
        "colors": [
            "#fee849",
            "#e39a02",
            "#d21515"
        ],
        "seg1": "",
        "seg2": "",
        "x": 470,
        "y": 200,
        "wires": []
    },
    {
        "id": "45872dba.55fcd4",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "f943ae3.4d5b75",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "° C",
        "format": "{{value}}",
        "min": "-40",
        "max": "40",
        "colors": [
            "#00ff00",
            "#ffff00",
            "#e60000"
        ],
        "seg1": "",
        "seg2": "",
        "x": 470,
        "y": 240,
        "wires": []
    },
    {
        "id": "2a0f2623.21943a",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "34ec3061.6e984",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "RPM",
        "format": "{{value}}",
        "min": 0,
        "max": "8000",
        "colors": [
            "#ffffff",
            "#00e611",
            "#000000"
        ],
        "seg1": "",
        "seg2": "",
        "x": 470,
        "y": 280,
        "wires": []
    },
    {
        "id": "57ee1e71.74562",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "3fc295fe.9f49ca",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "kmh",
        "format": "{{value}}",
        "min": "0",
        "max": "250",
        "colors": [
            "#0000c6",
            "#caceff",
            "#ec1e00"
        ],
        "seg1": "",
        "seg2": "",
        "x": 470,
        "y": 320,
        "wires": []
    },
    {
        "id": "f5ad1b10.a28e28",
        "type": "ui_text",
        "z": "5c322bcd.0d7e24",
        "group": "3621392d.b91016",
        "order": 2,
        "width": 6,
        "height": 4,
        "name": "",
        "label": "",
        "format": "{{msg.payload}}",
        "layout": "col-center",
        "x": 470,
        "y": 360,
        "wires": []
    },
    {
        "id": "7ed3d7b9.a233a8",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": " return {payload:\"\"};",
        "outputs": 1,
        "noerr": 0,
        "x": 310,
        "y": 420,
        "wires": [
            [
                "e7e764ae.4ca5e8",
                "7eadc7ad.7cf6e8",
                "45872dba.55fcd4",
                "2a0f2623.21943a",
                "57ee1e71.74562",
                "f5ad1b10.a28e28",
                "f2ad5cb4.ababd"
            ]
        ]
    },
    {
        "id": "f2ad5cb4.ababd",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "motorS",
        "group": "b15ee046.8c935",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "° C",
        "format": "{{value}}",
        "min": 0,
        "max": "90",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 480,
        "y": 120,
        "wires": []
    },
    {
        "id": "fde36889.95bd38",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "7b6ef1b8.16383",
        "order": 1,
        "width": "6",
        "height": "1",
        "passthru": false,
        "label": "Read all",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"9\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 100,
        "y": 740,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "907051c2.7f0d6",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "6f469820.86dbc8",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Engine temp",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"13\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 650,
        "y": 460,
        "wires": [
            [
                "c2fcb0e4.9df3c",
                "6d5bcc4c.efd854"
            ]
        ]
    },
    {
        "id": "92f1767a.688ed8",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "c5be57a5.510478",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Battery voltage",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"14\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 660,
        "y": 500,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "885fc116.356fd",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "5030d833.9eefd8",
        "order": 1,
        "width": "0",
        "height": "0",
        "passthru": false,
        "label": "Velocity",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"15\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 640,
        "y": 540,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "d51c239f.9016e",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "be34be57.b6c16",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "RPM",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"16\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 610,
        "y": 700,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "82b1f1c0.61c95",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "9e83fd0.ce74c",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Engine load",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"17\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 630,
        "y": 740,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "fc2fd3d3.92929",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "2c1d9538.5680ea",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Intake air temp",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"18\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 640,
        "y": 780,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "5e6ca779.597a68",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "a006a90c.461b58",
        "order": 0,
        "width": "6",
        "height": "5",
        "passthru": false,
        "label": "RESTART",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"12\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 650,
        "y": 420,
        "wires": [
            [
                "c2fcb0e4.9df3c",
                "89ddbf44.c92b3"
            ]
        ]
    },
    {
        "id": "e26b8480.6ed6a8",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "6f469820.86dbc8",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "° C",
        "format": "{{value}}",
        "min": 0,
        "max": "90",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 890,
        "y": 80,
        "wires": []
    },
    {
        "id": "25282f33.397db",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "c5be57a5.510478",
        "order": 2,
        "width": "6",
        "height": "4",
        "gtype": "wave",
        "title": "",
        "label": "V",
        "format": "{{value}}",
        "min": 0,
        "max": "15",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 890,
        "y": 120,
        "wires": []
    },
    {
        "id": "9b7438b8.d46d08",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "zatazmD",
        "group": "9e83fd0.ce74c",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "%",
        "format": "{{value}}",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 900,
        "y": 160,
        "wires": []
    },
    {
        "id": "416cd75.90f5128",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "2c1d9538.5680ea",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "° C",
        "format": "{{value}}",
        "min": "-40",
        "max": "40",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 890,
        "y": 200,
        "wires": []
    },
    {
        "id": "487f89ae.f1e818",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "5030d833.9eefd8",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "kmh",
        "format": "{{value}}",
        "min": 0,
        "max": "250",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 890,
        "y": 280,
        "wires": []
    },
    {
        "id": "3ad69aee.451986",
        "type": "ui_gauge",
        "z": "5c322bcd.0d7e24",
        "name": "otackyD",
        "group": "be34be57.b6c16",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "",
        "label": "RPM",
        "format": "{{value}}",
        "min": 0,
        "max": "7000",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 900,
        "y": 240,
        "wires": []
    },
    {
        "id": "1d98f4df.46248b",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "dteplotam",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/dteplotam/fmt/json\":\n        return {payload:msg.payload.TeplotaMotora};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 680,
        "y": 80,
        "wires": [
            [
                "e26b8480.6ed6a8",
                "bb009985.60d978"
            ]
        ]
    },
    {
        "id": "a0a16110.3d97d",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "dnapatie",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/dnapatie/fmt/json\":\n        return {payload:msg.payload.Napatie};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 680,
        "y": 120,
        "wires": [
            [
                "25282f33.397db",
                "110734fb.37ff5b"
            ]
        ]
    },
    {
        "id": "9cbffc43.6fae4",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "dzatazm",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/dzatazm/fmt/json\":\n        return {payload:msg.payload.ZatazMotora};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 680,
        "y": 160,
        "wires": [
            [
                "9b7438b8.d46d08"
            ]
        ]
    },
    {
        "id": "804e7a.3d19e188",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "dteplotasania",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/dteplotasania/fmt/json\":\n        return {payload:msg.payload.TeplotaSania};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 690,
        "y": 200,
        "wires": [
            [
                "416cd75.90f5128"
            ]
        ]
    },
    {
        "id": "c95b86aa.ff9988",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "dotacky",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/dotacky/fmt/json\":\n        return {payload:msg.payload.Otacky};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 680,
        "y": 240,
        "wires": [
            [
                "3ad69aee.451986",
                "3206e8b5.b2df78"
            ]
        ]
    },
    {
        "id": "e2afa857.055908",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "drychlost",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/drychlost/fmt/json\":\n        return {payload:msg.payload.Rychlost};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 680,
        "y": 280,
        "wires": [
            [
                "487f89ae.f1e818",
                "79739b5d.19d3a4"
            ]
        ]
    },
    {
        "id": "89ddbf44.c92b3",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": " return {payload:\"\"};",
        "outputs": 1,
        "noerr": 0,
        "x": 670,
        "y": 340,
        "wires": [
            [
                "e26b8480.6ed6a8",
                "25282f33.397db",
                "9b7438b8.d46d08",
                "416cd75.90f5128",
                "3ad69aee.451986",
                "487f89ae.f1e818"
            ]
        ]
    },
    {
        "id": "f050f736.555a78",
        "type": "debug",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 260,
        "y": 20,
        "wires": []
    },
    {
        "id": "bb009985.60d978",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "teplota",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1140,
        "y": 80,
        "wires": []
    },
    {
        "id": "110734fb.37ff5b",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "napatie",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1140,
        "y": 120,
        "wires": []
    },
    {
        "id": "79739b5d.19d3a4",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "rychlost",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1140,
        "y": 280,
        "wires": []
    },
    {
        "id": "3206e8b5.b2df78",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "otacky",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1140,
        "y": 240,
        "wires": []
    },
    {
        "id": "6d5bcc4c.efd854",
        "type": "debug",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 870,
        "y": 480,
        "wires": []
    },
    {
        "id": "26a88bb.6c9d574",
        "type": "ibmiot in",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "inputType": "evt",
        "logicalInterface": "",
        "ruleId": "",
        "deviceId": "ios_i",
        "applicationId": "",
        "deviceType": "ios_t",
        "eventType": "+",
        "commandType": "spojka",
        "format": "json",
        "name": "IBM IoT",
        "service": "registered",
        "allDevices": "",
        "allApplications": "",
        "allDeviceTypes": "",
        "allLogicalInterfaces": "",
        "allEvents": true,
        "allCommands": "",
        "allFormats": true,
        "qos": 0,
        "x": 830,
        "y": 360,
        "wires": [
            [
                "63392018.ad6dc"
            ]
        ]
    },
    {
        "id": "63392018.ad6dc",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "func": "switch (msg.topic){\n    case \"iot-2/type/ios_t/id/ios_i/evt/ahoj/fmt/json\":\n        return {payload:msg.payload.RJpay};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 870,
        "y": 420,
        "wires": [
            [
                "6d5bcc4c.efd854",
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "4652684e.bd8e48",
        "type": "inject",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "topic": "spojka",
        "payload": "\"20\"",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 420,
        "y": 800,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "875485b.33b0078",
        "type": "inject",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "topic": "spojka",
        "payload": "\"21\"",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 420,
        "y": 760,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "87c28d94.43529",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "suradnicemotor",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1320,
        "y": 180,
        "wires": []
    },
    {
        "id": "2887474f.3903a8",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "suradnicemotor",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/suradnicemotor/fmt/json\":\n        return {payload:msg.payload};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 1120,
        "y": 180,
        "wires": [
            [
                "3c596726.fd9b38",
                "87c28d94.43529"
            ]
        ]
    },
    {
        "id": "3c596726.fd9b38",
        "type": "debug",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 1210,
        "y": 520,
        "wires": []
    },
    {
        "id": "fe99fbd4.9109b8",
        "type": "debug",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 660,
        "y": 40,
        "wires": []
    },
    {
        "id": "c334c204.254a9",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "suradnicenap",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/suradnicenap/fmt/json\":\n        return {payload:msg.payload};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 1100,
        "y": 20,
        "wires": [
            [
                "9b089d4d.b06c5"
            ]
        ]
    },
    {
        "id": "9b089d4d.b06c5",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "suradnicenap",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1320,
        "y": 80,
        "wires": []
    },
    {
        "id": "15ac389c.0aeb97",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "surarychl",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1320,
        "y": 340,
        "wires": []
    },
    {
        "id": "a11eb45f.d38ef8",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "surarychl",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/surarychl/fmt/json\":\n        return {payload:msg.payload};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 1120,
        "y": 340,
        "wires": [
            [
                "15ac389c.0aeb97"
            ]
        ]
    },
    {
        "id": "9d5ef054.3aeed",
        "type": "function",
        "z": "5c322bcd.0d7e24",
        "name": "suraotac",
        "func": "switch (msg.topic){\n    case \"iot-2/type/Mikrokontroler/id/IDkontroler/evt/suraotac/fmt/json\":\n        return {payload:msg.payload};\n}",
        "outputs": 1,
        "noerr": 0,
        "x": 1120,
        "y": 400,
        "wires": [
            [
                "5a0f36cd.44ca48"
            ]
        ]
    },
    {
        "id": "5a0f36cd.44ca48",
        "type": "ibmiot out",
        "z": "5c322bcd.0d7e24",
        "authentication": "boundService",
        "apiKey": "",
        "outputType": "cmd",
        "deviceId": "ios_i",
        "deviceType": "ios_t",
        "eventCommandType": "suraotac",
        "format": "json",
        "data": "{}",
        "qos": 0,
        "name": "IBM IoT",
        "service": "registered",
        "x": 1320,
        "y": 400,
        "wires": []
    },
    {
        "id": "91e819d.952aee8",
        "type": "debug",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 200,
        "y": 820,
        "wires": []
    },
    {
        "id": "4bf77032.81e66",
        "type": "ui_button",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "group": "7b6ef1b8.16383",
        "order": 2,
        "width": "6",
        "height": "4",
        "passthru": false,
        "label": "RESTART",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "\"8\"",
        "payloadType": "json",
        "topic": "spojka",
        "x": 110,
        "y": 420,
        "wires": [
            [
                "7ed3d7b9.a233a8",
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "67f5864a.d0b778",
        "type": "inject",
        "z": "5c322bcd.0d7e24",
        "name": "",
        "topic": "spojka",
        "payload": "\"19\"",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 660,
        "y": 840,
        "wires": [
            [
                "c2fcb0e4.9df3c"
            ]
        ]
    },
    {
        "id": "b15ee046.8c935",
        "type": "ui_group",
        "z": "",
        "name": "1",
        "tab": "92efbb56.641408",
        "order": 1,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "f7606a4e.234618",
        "type": "ui_group",
        "z": "",
        "name": "3",
        "tab": "92efbb56.641408",
        "order": 5,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "f943ae3.4d5b75",
        "type": "ui_group",
        "z": "",
        "name": "4",
        "tab": "92efbb56.641408",
        "order": 6,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "b3c559b3.3e97d8",
        "type": "ui_group",
        "z": "",
        "name": "2",
        "tab": "92efbb56.641408",
        "order": 2,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "34ec3061.6e984",
        "type": "ui_group",
        "z": "",
        "name": "5",
        "tab": "92efbb56.641408",
        "order": 4,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "3fc295fe.9f49ca",
        "type": "ui_group",
        "z": "",
        "name": "6",
        "tab": "92efbb56.641408",
        "order": 3,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "3621392d.b91016",
        "type": "ui_group",
        "z": "",
        "name": "7",
        "tab": "92efbb56.641408",
        "order": 7,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "7b6ef1b8.16383",
        "type": "ui_group",
        "z": "",
        "name": "8",
        "tab": "92efbb56.641408",
        "order": 8,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "6f469820.86dbc8",
        "type": "ui_group",
        "z": "",
        "name": "Group 1",
        "tab": "95159b00.fda818",
        "order": 1,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "c5be57a5.510478",
        "type": "ui_group",
        "z": "",
        "name": "Group 2",
        "tab": "95159b00.fda818",
        "order": 2,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "5030d833.9eefd8",
        "type": "ui_group",
        "z": "",
        "name": "Group 3",
        "tab": "95159b00.fda818",
        "order": 3,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "be34be57.b6c16",
        "type": "ui_group",
        "z": "",
        "name": "Group 4",
        "tab": "95159b00.fda818",
        "order": 4,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "9e83fd0.ce74c",
        "type": "ui_group",
        "z": "",
        "name": "Group 5",
        "tab": "95159b00.fda818",
        "order": 5,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "2c1d9538.5680ea",
        "type": "ui_group",
        "z": "",
        "name": "Group 6",
        "tab": "95159b00.fda818",
        "order": 6,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "a006a90c.461b58",
        "type": "ui_group",
        "z": "",
        "name": "Group 7",
        "tab": "95159b00.fda818",
        "order": 7,
        "disp": false,
        "width": "6",
        "collapse": false
    },
    {
        "id": "92efbb56.641408",
        "type": "ui_tab",
        "z": "",
        "name": "STATICKE TESTY",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "95159b00.fda818",
        "type": "ui_tab",
        "z": "",
        "name": "DYNAMICKE TESTY",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    }
]

ContentView - main Swift code

Swift
For iOS application
//
//  ContentView.swift
//  RingViewRPM
//
//  Created by Kardan on 01/04/2020.
//  Copyright © 2020 Kardan. All rights reserved.
//

import SwiftUI
import CocoaMQTT


public struct DarkView<Content> : View where Content : View {
    var darkContent: Content
    var on: Bool
    public init(_ on: Bool, @ViewBuilder content: () -> Content) {
        self.darkContent = content()
        self.on = on
    }

    public var body: some View {
        ZStack {
            if on {
                Spacer()
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                    .background(Color.black)
                    .edgesIgnoringSafeArea(.all)
                darkContent.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity).background(Color.black).colorScheme(.dark)
            } else {
                darkContent
            }
        }
    }
}

extension View {
    public func darkModeFix(_ on: Bool = true) -> DarkView<Self> {
        DarkView(on) {
            self
        }
    }
}

struct ContentView: View {
    
    
    
    
    let mqttClient = CocoaMQTT(clientID:"d:ORGID:ios_t:ios_i",host:"ORGID.messaging.internetofthings.ibmcloud.com",port: 1883)
    var hodnota10:String="{\"properta\":10}"
    var hodnota8:String="{\"properta\":8}"
    var hodnota7:String="{\"properta\":7}"
    
    
    
    @State var starahodnota:Double=5.55
    @State var nazvik="Vozidlo"
    @State var counter=""
    @State var nrdlzka:Double = 40.9{
        didSet{
            starahodnota=oldValue
        }
    }
    @State var nrsirka:Double = 15.5890
    @State var cgCislo:CGFloat = 0
    @State var cNapatie:CGFloat = 0
    @State var cRychlost:CGFloat = 0
    @State var cOtacky:CGFloat = 0
    @State var cZataz:CGFloat = 0
    @State var cSanie:CGFloat = 0
    var body: some View {
       
        ZStack {
            VStack {
                HStack {
                    Button(action: {
                        self.mqttClient.username="use-token-auth"
                        self.mqttClient.password="ios_token"
                        self.mqttClient.connect()
                        self.counter="Pripojene"
                    }) {
                        Image(systemName: "person.circle")
                        .font(Font.system(.largeTitle).bold())
                    }
                    .padding()
                    Spacer()
                    Button(action: {
                        self.mqttClient.publish("iot-2/evt/ahoj/fmt/json", withString: "{\"RJpay\":\"20\"}")
                        self.mqttClient.subscribe("iot-2/cmd/suradnicemotor/fmt/json")
                        self.mqttClient.didReceiveMessage = { mqtt, message, id in
                            print("Message received in topic \(message.topic) with payload \(message.string!)")
                            if (message.topic=="iot-2/cmd/suradnicemotor/fmt/json"){
                            let dorucene:String=message.string!
                            let sevas=dorucene.data(using: .utf8)!
                            let dekodovac = JSONDecoder()
                            let osobka = try! dekodovac.decode(Hodnota.self, from: sevas)
                            let prevteplota=String(osobka.Teplota)
                            self.nrdlzka=osobka.Latituda
                            self.nrsirka=osobka.Longituda
                            self.cgCislo = CGFloat((prevteplota as NSString).doubleValue)
                            }
                        }
                    }) {
                        Image(systemName: "thermometer")
                        .font(Font.system(.largeTitle).bold())
                    }
                    .padding()
                    Spacer()
                    Button(action: {
                        self.mqttClient.publish("iot-2/evt/ahoj/fmt/json", withString: "{\"RJpay\":\"21\"}")
                        self.mqttClient.subscribe("iot-2/cmd/suradnicenap/fmt/json")
                        self.mqttClient.didReceiveMessage = { mqtt, message, id in
                        print("Message received in topic \(message.topic) with payload \(message.string!)")
                            if (message.topic=="iot-2/cmd/suradnicenap/fmt/json"){
                            let dorucene:String=message.string!
                            let sevas=dorucene.data(using: .utf8)!
                            let dekodovac = JSONDecoder()
                            let osobka = try! dekodovac.decode(Hodnota3.self, from: sevas)
                            let prevteplota=String(osobka.Napatie)
                            self.nrdlzka=osobka.Latituda
                            self.nrsirka=osobka.Longituda
                            self.cNapatie = CGFloat((prevteplota as NSString).doubleValue)
                            }
                            }
                    }) {
                        Image(systemName: "battery.100")
                        .font(Font.system(.largeTitle).bold())
                    }
                    .padding()
                    
                    Spacer()
                    Button(action: {
                        self.mqttClient.publish("iot-2/evt/ahoj/fmt/json", withString: "{\"RJpay\":\"22\"}")
                        self.mqttClient.subscribe("iot-2/cmd/surarychl/fmt/json")
                        self.mqttClient.didReceiveMessage = { mqtt, message, id in
                        print("Message received in topic \(message.topic) with payload \(message.string!)")
                            if (message.topic=="iot-2/cmd/surarychl/fmt/json"){
                            let dorucene:String=message.string!
                            let sevas=dorucene.data(using: .utf8)!
                            let dekodovac = JSONDecoder()
                            let osobka = try! dekodovac.decode(Hodnota1.self, from: sevas)
                            let prevteplota=String(osobka.Rychlost)
                            self.nrdlzka=osobka.Latituda
                            self.nrsirka=osobka.Longituda
                            self.cRychlost = CGFloat((prevteplota as NSString).doubleValue)
                            }
                            }
                        
                    }) {
                        Image(systemName: "speedometer")
                        .font(Font.system(.largeTitle).bold())
                    }
                    .padding()
                    
                    Spacer()
                    Button(action: {
                        self.mqttClient.publish("iot-2/evt/ahoj/fmt/json", withString: "{\"RJpay\":\"23\"}")
                        self.mqttClient.subscribe("iot-2/cmd/suraotac/fmt/json")
                        self.mqttClient.didReceiveMessage = { mqtt, message, id in
                            print("Message received in topic \(message.topic) with payload \(message.string!)")
                            if (message.topic=="iot-2/cmd/suraotac/fmt/json"){
                            let dorucene:String=message.string!
                            let sevas=dorucene.data(using: .utf8)!
                            let dekodovac = JSONDecoder()
                            let osobka = try! dekodovac.decode(Hodnota2.self, from: sevas)
                            let prevteplota=String(osobka.Otacky)
                            self.nrdlzka=osobka.Latituda
                            self.nrsirka=osobka.Longituda
                            self.cOtacky = CGFloat((prevteplota as NSString).doubleValue)
                            }
                        }
                    }) {
                        Image(systemName: "arrow.2.circlepath.circle")
                        .font(Font.system(.largeTitle).bold())
                    }
                    .padding()
                }
                Spacer()
            }
            VStack {
                MapView(predtym: starahodnota, nazov: nazvik, dlzka: nrdlzka, sirka: nrsirka)
                    .cornerRadius(25)
                    .frame(height:300)
                    .padding(.top,50)
                    .padding()
                    
                    
                Spacer()
                    
                ZStack{
                    
                        //Teplota(hodnotka: cgCislo)
                        ScrollView(.horizontal, showsIndicators: false){
                            HStack(spacing:5){
                            Teplota(hodnotka: cgCislo)
                            Napatie(napaticko: cNapatie)
                            Rychlost(rychlostka: cRychlost)
                            Otacky(otacocky: cOtacky)
                            Zataz(zatazka: cZataz)
                            Sanie(sanicko: cSanie)
                        }
                    }
                        
                }
            }
            
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
        .darkModeFix()
            //.environment(\.colorScheme, .dark)
    
    }
}

struct Hodnota: Decodable{
    var Longituda:Double
    var Latituda:Double
    var Teplota:Int
}

struct Hodnota1: Decodable{
    var Longituda:Double
    var Latituda:Double
    var Rychlost:Int
}

struct Hodnota2: Decodable{
    var Longituda:Double
    var Latituda:Double
    var Otacky:Int
}

struct Hodnota3: Decodable{
    var Longituda:Double
    var Latituda:Double
    var Napatie:Int
}

MapView - Map with annotation mark Swift code

Swift
For iOS application
//
//  MapView.swift
//  RingViewRPM
//
//  Created by Kardan on 01/04/2020.
//  Copyright © 2020 Kardan. All rights reserved.
//

import SwiftUI
import MapKit


struct MapView: UIViewRepresentable {
    var predtym:Double
    var nazov:String="sevas"
    var dlzka = 34.011286
    var sirka = -116.166868
    @State var prava:Bool=true
    
    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }
    
    func updateUIView(_ uiView: MKMapView, context: Context) {
        
    
        let coordinate = CLLocationCoordinate2D(
            latitude: dlzka, longitude: sirka)
        let sponka=MKPointAnnotation()
        sponka.coordinate=coordinate
        sponka.title=nazov
        let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        uiView.setRegion(region, animated: true)
        let annotations = uiView.annotations
        uiView.removeAnnotations(annotations)
        uiView.addAnnotation(sponka)
        
        
}
    
    
    
}

Temperature Gauge - Swift code

Swift
For iOS application
//
//  Teplota.swift
//  RingViewRPM
//
//  Created by Kardan on 19/04/2020.
//  Copyright © 2020 Kardan. All rights reserved.
//

import SwiftUI

struct Teplota: View {
    @State var rozhodni=0
    var hodnotka:CGFloat = 0
    var body: some View {
        ZStack{
                Text("Teplota motora")
                .font(.largeTitle)
                .fontWeight(.semibold)
                .foregroundColor(Color.yellow)
                .multilineTextAlignment(.center)
                .padding(.top,200)
            Circle()
                .trim(from: 0.0, to: 0.5)
                .stroke(Color.blue, style: StrokeStyle(lineWidth: 12.0, dash: [8]))
                .frame(width: 400, height: 300)
                .rotationEffect(Angle(degrees: -180))
            
            Circle()
                .trim(from: 0.0, to: hodnotka/200)
                .stroke(Color.blue, lineWidth: 12.0)
                .frame(width: 400, height: 300)
                .rotationEffect(Angle(degrees: -180))
                .animation(.easeOut(duration: 0.5))
            Text("\(Int(hodnotka)) °")
                .font(.largeTitle)
                .fontWeight(.semibold)
                .multilineTextAlignment(.center)
                .padding()
                .transition(.opacity)
            
            
    }
        .padding(.top)
    }
}

Battery voltage gauge - Swift code

Swift
For iOS application
//
//  Napatie.swift
//  RingViewRPM
//
//  Created by Kardan on 19/04/2020.
//  Copyright © 2020 Kardan. All rights reserved.
//

import SwiftUI

struct Napatie: View {
    var napaticko:CGFloat = 0
    var body: some View {
        ZStack{
            Text("Napatie baterie")
                .font(.largeTitle)
                .fontWeight(.semibold)
                .foregroundColor(Color.yellow)
                .multilineTextAlignment(.center)
                .padding(.top,200)
            Circle()
                .trim(from: 0.0, to: 0.5)
                .stroke(Color.blue, style: StrokeStyle(lineWidth: 12.0, dash: [8]))
                .frame(width: 400, height: 300)
                .rotationEffect(Angle(degrees: -180))
            
            Circle()
                .trim(from: 0.0, to: napaticko/30)
                .stroke(Color.blue, lineWidth: 12.0)
                .frame(width: 400, height: 300)
                .rotationEffect(Angle(degrees: -180))
                .animation(.easeOut(duration: 0.5))
            Text("\(Int(napaticko)) V")
                .font(.largeTitle)
                .fontWeight(.semibold)
                .multilineTextAlignment(.center)
                .padding()
                .transition(.opacity)
            
            
    }
        .padding(.top)
    }
}

Velocity gauge - Swift code

Swift
For iOS application
//
//  Rychlost.swift
//  RingViewRPM
//
//  Created by Kardan on 19/04/2020.
//  Copyright © 2020 Kardan. All rights reserved.
//

import SwiftUI

struct Rychlost: View {
    var rychlostka:CGFloat = 0
        var body: some View {
            ZStack{
                Text("Rychlost")
                    .font(.largeTitle)
                    .fontWeight(.semibold)
                    .foregroundColor(Color.yellow)
                    .multilineTextAlignment(.center)
                    .padding(.top,200)
                Circle()
                    .trim(from: 0.0, to: 0.5)
                    .stroke(Color.blue, style: StrokeStyle(lineWidth: 12.0, dash: [8]))
                    .frame(width: 400, height: 300)
                    .rotationEffect(Angle(degrees: -180))
                
                Circle()
                    .trim(from: 0.0, to: rychlostka/500)
                    .stroke(Color.blue, lineWidth: 12.0)
                    .frame(width: 400, height: 300)
                    .rotationEffect(Angle(degrees: -180))
                    .animation(.easeOut(duration: 0.5))
                Text("\(Int(rychlostka)) km/h")
                    .font(.largeTitle)
                    .fontWeight(.semibold)
                    .multilineTextAlignment(.center)
                    .padding()
                    .transition(.opacity)
                
                
        }
            .padding(.top)
        }
    }

RPM gauge - Swift code

Swift
For iOS application
//
//  Otacky.swift
//  RingViewRPM
//
//  Created by Kardan on 19/04/2020.
//  Copyright © 2020 Kardan. All rights reserved.
//

import SwiftUI

struct Otacky: View {
    var otacocky:CGFloat = 0
        var body: some View {
            ZStack{
                Text("Otacky")
                    .font(.largeTitle)
                    .fontWeight(.semibold)
                    .foregroundColor(Color.yellow)
                    .multilineTextAlignment(.center)
                    .padding(.top,200)
                Circle()
                    .trim(from: 0.0, to: 0.5)
                    .stroke(Color.blue, style: StrokeStyle(lineWidth: 12.0, dash: [8]))
                    .frame(width: 400, height: 300)
                    .rotationEffect(Angle(degrees: -180))
                
                Circle()
                    .trim(from: 0.0, to: otacocky/16000)
                    .stroke(Color.blue, lineWidth: 12.0)
                    .frame(width: 400, height: 300)
                    .rotationEffect(Angle(degrees: -180))
                    .animation(.easeOut(duration: 0.5))
                Text("\(Int(otacocky)) RPM")
                    .font(.largeTitle)
                    .fontWeight(.semibold)
                    .multilineTextAlignment(.center)
                    .padding()
                    .transition(.opacity)
                
                
        }
            .padding(.top)
        }
    }

Credits

jassak

jassak

2 projects • 6 followers
UNi Student

Comments