Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Chahine TALEBNicolas DAILLYMathis Andréfcaron
Published

PetGPS

A LoRa connected harness equipped with various sensors to improve your pet's life

IntermediateWork in progress817
PetGPS

Things used in this project

Hardware components

Arduino MKR WAN 1310
Arduino MKR WAN 1310
×1
Arduino Leonardo
Arduino Leonardo
×1
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
Ks0012 keyestudio ADXL345 Three Axis Acceleration Module
×1
Antenna, GPS
Antenna, GPS
×1

Software apps and online services

Android Studio
Android Studio
Node-RED
Node-RED
Arduino IDE
Arduino IDE
The Things Stack
The Things Industries The Things Stack

Story

Read more

Code

Maps Activity XML

XML
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapsActivity" ></fragment>

Maps Activity Java

Java
package com.chahine.projetiot;

import androidx.fragment.app.FragmentActivity;

import android.location.Location;
import android.os.Bundle;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.chahine.projetiot.databinding.ActivityMapsBinding;

import java.util.List;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    List<Location> savedLocation;
    private ActivityMapsBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMapsBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        MyApplication myApplication = (MyApplication)getApplicationContext();
        savedLocation = myApplication.getMyLocations();
    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
       // mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        //mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

        for (Location location: savedLocation
        ) {
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(latLng);
            markerOptions.title("Lat:" + location.getLatitude() +"Lon:" + location.getLongitude());
            mMap.addMarker(markerOptions);
        }
    }
}

Main Activity (Interface Connexion) JAVA

Java
package com.chahine.projetiot;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.chahine.projetiot.databinding.ActivityMainBinding;
import com.google.android.material.textfield.TextInputLayout;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

    public class MainActivity extends AppCompatActivity {
        private DatabaseManager databaseManager;


        //private AppBarConfiguration mAppBarConfiguration;
        private ActivityMainBinding binding;

        private TextView errorCreateAccountTextView;
        private EditText usernameEditText;
        private EditText passwordEditText;

        private Button connectBtn;
        private TextView createAccountBtn;

        private String username;
        private String password;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // Initialize views
            initViews();

            // Setup listeners
            setupListeners();
        }



        private void initViews() {
            // Correctement récupérer les TextInputEditText à partir des TextInputLayout
            TextInputLayout usernameTextInputLayout = findViewById(R.id.usernameTextInputLayout); // Assurez-vous que l'ID est correct
            TextInputLayout passwordTextInputLayout = findViewById(R.id.passwordTextInputLayout); // Assurez-vous que l'ID est correct

            // Initialiser les EditText en récupérant les TextInputEditText à l'intérieur des TextInputLayout
            usernameEditText = usernameTextInputLayout.getEditText();
            passwordEditText = passwordTextInputLayout.getEditText();

            connectBtn = findViewById(R.id.connectBtn);
            createAccountBtn = findViewById(R.id.createAccountBtn);

            databaseManager = new DatabaseManager(getApplicationContext());
        }


        private void setupListeners() {
            connectBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    username = usernameEditText.getText().toString();
                    password = passwordEditText.getText().toString();
                   connectUser();
                }
            });

            createAccountBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startActivity(new Intent(getApplicationContext(), RegisterActivity.class));
                    finish();
                }
            });

        }

        private void connectUser() {
            String url = "http://192.168.1.141/api/actions/connectUser.php";

            Map<String, String> params = new HashMap<>();
            params.put("username", username);
            params.put("password", password);
            JSONObject parameters = new JSONObject(params);

            JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, parameters, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    onApiResponse(response);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
                }
            });

            databaseManager.queue.add(jsonObjectRequest);
        }

        public void onApiResponse(JSONObject response) {
            try {
                if (response.getBoolean("success")) {
                    startActivity(new Intent(getApplicationContext(), intergps.class).putExtra("username", username));
                    finish();
                } else {
                    String error = response.getString("error");
                    errorCreateAccountTextView.setVisibility(View.VISIBLE);
                    errorCreateAccountTextView.setText(error);
                }
            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
            }
        }
    }

Main Activity (Interface Connexion) XML

XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_color"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="10dp">



            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="Connexion"
                android:textColor="@color/white"
                android:fontFamily="@font/dm_medium"
                android:textSize="22sp" ></TextView>
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="80dp"
            android:fontFamily="@font/dancing_bold"
            android:gravity="center"
            android:padding="5dp"
            android:text="PetGPS"
            android:drawableEnd="@mipmap/petgpsa_foreground"
            android:drawablePadding="10dp"
            android:textColor="@color/white"
            android:textSize="45sp"

            ></TextView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="110dp"
            android:orientation="vertical"
            android:background="@drawable/round_border">

            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:id="@+id/usernameTextInputLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:hint="Nom d'utilisateur"
                app:boxCornerRadiusBottomEnd="8dp"
                app:boxCornerRadiusBottomStart="8dp"
                app:boxStrokeColor="@color/icon_color"
                app:boxCornerRadiusTopEnd="8dp"
                app:boxCornerRadiusTopStart="8dp"
                app:hintTextColor="@color/black">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:drawableStart="@drawable/baseline_account_circle_24"
                    android:drawablePadding="10dp"
                    android:drawableTint="@color/app_color"
                    android:inputType="text" ></com>
            </com.google.android.material.textfield.TextInputLayout>


            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:id="@+id/passwordTextInputLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:hint="Mot de passe"
                app:boxStrokeColor="@color/icon_color"
                app:boxCornerRadiusBottomEnd="8dp"
                app:boxCornerRadiusBottomStart="8dp"
                app:boxCornerRadiusTopEnd="8dp"
                app:boxCornerRadiusTopStart="8dp"
                app:passwordToggleEnabled="true"
                app:hintTextColor="@color/black">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:drawableStart="@drawable/baseline_adb_24"
                    android:drawablePadding="10dp"
                    android:drawableTint="@color/app_color"
                    android:inputType="textPassword" ></com>
            </com.google.android.material.textfield.TextInputLayout>

            <Button
                android:layout_width="match_parent"
                android:id="@+id/connectBtn"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                app:backgroundTint="@color/button_color"
                android:padding="20dp"
                android:text="SE CONNECTER"
                android:onClick="intergps"
                android:textColor="@color/black"
                android:textSize="18dp"
                android:fontFamily="@font/dm_medium">
            </Button>

            <TextView
                android:id="@+id/createAccountBtn"
                android:layout_width="wrap_content"
                android:layout_height="89dp"
                android:layout_gravity="center"
                android:fontFamily="@font/dm_medium"
                android:onClick="register"
                android:padding="5dp"
                android:text="Pas de compte ? Inscris-toi ici  "
                android:textColor="@color/app_color"
                android:textSize="20sp" ></TextView>


        </LinearLayout>


    </LinearLayout>

</RelativeLayout>

Interface GPS/Sensors XML

XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".intergps">

    <TextView
        android:id="@+id/tv_labellat"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="Lat:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" ></TextView>

    <TextView
        android:id="@+id/tv_lat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="0.00"
        app:layout_constraintStart_toEndOf="@+id/tv_labellat"
        app:layout_constraintTop_toTopOf="parent" ></TextView>

    <TextView
        android:id="@+id/tv_labellon"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="lon:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_labellat" ></TextView>

    <TextView
        android:id="@+id/tv_lon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="0.00"
        app:layout_constraintStart_toEndOf="@+id/tv_labellon"
        app:layout_constraintTop_toBottomOf="@+id/tv_lat" ></TextView>

    <TextView
        android:id="@+id/tv_labelaltitude"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Altitude:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_labellon" ></TextView>

    <TextView
        android:id="@+id/tv_altitude"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0.00"
        app:layout_constraintStart_toEndOf="@+id/tv_labelaltitude"
        app:layout_constraintTop_toTopOf="@+id/tv_labelaltitude" ></TextView>

    <TextView
        android:id="@+id/tv_labelaccuracy"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Accuracy:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_labelaltitude" ></TextView>

    <TextView
        android:id="@+id/tv_accuracy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0.00"
        app:layout_constraintStart_toEndOf="@+id/tv_labelaccuracy"
        app:layout_constraintTop_toTopOf="@+id/tv_labelaccuracy" ></TextView>

    <TextView
        android:id="@+id/tv_labelspeed"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Speed:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_labelaccuracy" ></TextView>

    <TextView
        android:id="@+id/tv_speed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0.00"
        app:layout_constraintStart_toEndOf="@+id/tv_labelspeed"
        app:layout_constraintTop_toTopOf="@+id/tv_labelspeed" ></TextView>

    <TextView
        android:id="@+id/tv_labelsensor"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Sensor:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/sw_gps" ></TextView>

    <TextView
        android:id="@+id/tv_sensor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cell Tower + Wifi"
        app:layout_constraintStart_toEndOf="@+id/tv_labelsensor"
        app:layout_constraintTop_toTopOf="@+id/tv_labelsensor" ></TextView>

    <TextView
        android:id="@+id/tv_labelupdates"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Updates:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/sw_locationsupdates" ></TextView>

    <TextView
        android:id="@+id/tv_updates"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Off"
        app:layout_constraintStart_toEndOf="@+id/tv_labelupdates"
        app:layout_constraintTop_toTopOf="@+id/tv_labelupdates" ></TextView>

    <Switch
        android:id="@+id/sw_locationsupdates"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:checked="true"
        android:text="Location Updates"
        android:minHeight="48dp"
        android:minWidth="48dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/divider" ></Switch>

    <Switch
        android:id="@+id/sw_gps"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:minHeight="48dp"
        android:minWidth="48dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:text="GPS/SavePower"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_labelupdates" ></Switch>

    <TextView
        android:id="@+id/tv_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toEndOf="@+id/tv_lbladdress"
        app:layout_constraintTop_toTopOf="@+id/tv_lbladdress" ></TextView>

    <TextView
        android:id="@+id/tv_lbladdress"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Address:"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_labelspeed" ></TextView>

    <View
        android:id="@+id/divider"
        android:layout_width="0dp"
    android:layout_height="1dp"
    android:layout_marginTop="32dp"
    android:background="?android:attr/listDivider"
    app:layout_constraintTop_toBottomOf="@+id/tv_address"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    tools:layout_editor_absoluteX="1dp" ></View>

    <TextView
        android:id="@+id/tv_labelCrumbCounter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="WayPoints:"
        app:layout_constraintTop_toBottomOf="@+id/tv_labelsensor"
        app:layout_constraintStart_toStartOf="parent" ></TextView>

    <TextView
        android:id="@+id/tv_countOfCrumbs"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        app:layout_constraintTop_toTopOf="@+id/tv_labelCrumbCounter"
        app:layout_constraintStart_toEndOf="@+id/tv_labelCrumbCounter" ></TextView>




    <Button

            android:id="@+id/btn_newWayPoint"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Button"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tv_labelCrumbCounter" ></Button>




        <Button
            android:id="@+id/btn_showWayPointList"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Show waypoint list"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_newWayPoint" ></Button>

    <TextView
        android:id="@+id/tv_sensorData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="temperature"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toTopOf="@+id/btn_showMap"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" ></TextView>

    <Button
        android:id="@+id/btn_showMap"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="MAP"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" ></Button>








</androidx.constraintlayout.widget.ConstraintLayout>

Interface GPS/Sensors Java

Java
package com.chahine.projetiot;

import static android.os.Build.VERSION.SDK_INT;

import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Button;


import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

public class intergps extends AppCompatActivity {


    private static final int PERMISSION_FINE_LOCATION = 59;
    TextView tv_lat, tv_lon, tv_altitude,tv_accuracy, tv_sensor, tv_updates, tv_address, tv_WayPointCounts,tv_sensorData;
    Button btn_newWayPoint, btn_showWayPointList, btn_showMap;

Switch sw_locationupdates, sw_gps;


//variable pour voir si on voit la loction ou pas

    boolean updateOn = false;

    //la loc en live
Location currentLocation;
    //liste des loc enregistrer
    List<Location> savedLocations;

//relateed fused location provider client
    LocationRequest locationRequest;


    LocationCallback locationCallBack;

//classe peremttant d'utiliser l'API google
FusedLocationProviderClient fusedLocationProviderClient;








    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_intergps);

        //Données valeur variable UI

        tv_lat = findViewById(R.id.tv_lat);
        tv_lon = findViewById(R.id.tv_lon);
        tv_altitude = findViewById(R.id.tv_altitude);
        tv_accuracy = findViewById(R.id.tv_accuracy);
        tv_sensor = findViewById(R.id.tv_sensor);
        tv_updates = findViewById(R.id.tv_updates);
        tv_address = findViewById(R.id.tv_address);
        sw_gps = findViewById(R.id.sw_gps);
        sw_locationupdates = findViewById(R.id.sw_locationsupdates);
        btn_newWayPoint = findViewById(R.id.btn_newWayPoint);
        btn_showWayPointList = findViewById(R.id.btn_showWayPointList);
        tv_WayPointCounts = findViewById(R.id.tv_countOfCrumbs);
        btn_showMap = findViewById(R.id.btn_showMap);
        tv_sensorData = findViewById(R.id.tv_sensorData);




        //confin de location requeste

        locationRequest = new LocationRequest();

        //delais entre lees check de loc
        locationRequest.setInterval(1000 * 30);

        //le max possible
        locationRequest.setFastestInterval(1000 * 50);

        locationRequest.setPriority(locationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
 //erveve
        locationCallBack = new LocationCallback() {

            @Override
            public void onLocationResult(@NonNull LocationResult locationResult) {
                super.onLocationResult(locationResult);

                //save the loc
                updateUIValues(locationResult.getLastLocation());
            }
        };


        btn_newWayPoint.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //prend la loc du gps
                //ajouter la nouvelle loc ala liste
                MyApplication myApplication = (MyApplication) getApplicationContext();
                savedLocations = myApplication.getMyLocations();
                savedLocations.add(currentLocation);
            }
        });

        btn_showWayPointList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(intergps.this, ShowSavedLocationsList.class);
                startActivity(i);}});


        btn_showMap.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(intergps.this, MapsActivity.class);
                startActivity(i);
            }
        });






                sw_gps.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                            if(sw_gps.isChecked()){
                                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                                tv_sensor.setText("Using GPS sensor");

                            }
                            else{
                                locationRequest.setPriority(locationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
                            tv_sensor.setText("Using Towers + WIFI");
                    }
                }});

                sw_locationupdates.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (sw_locationupdates.isChecked()){
                            //active trackage
                            startLocationUpdates();
                        }
                        else{
                            //dezactive trakage
                            stopLocationUpdates();
                    }
                }
                });



    updateGPS();
    fetchTemperature();

    }

    //fin de la methode

    private void fetchTemperature() {

        String url = "http://192.168.1.141/api/actions/getTemperature.php";

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            boolean success = response.getBoolean("success");
                            if (success) {
                                String temperature = response.getString("temperature");
                                String accel_x = response.getString("accel_x");
                                String accel_y= response.getString("accel_y");
                                String accel_z = response.getString("accel_z");
                                String timestamp = response.getString("timestamp");
                                tv_sensorData.setText("Température : "+temperature + "°C\n" +  "Accélération : \n"+accel_x+ "\n" +accel_z +"\n"+accel_y+"\n"+timestamp);
                                // Traitez ici la température comme vous le souhaitez
                            } else {
                                tv_sensorData.setText("N/A");
                                Toast.makeText(intergps.this, "Erreur ou absence de données", Toast.LENGTH_SHORT).show();
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                            Toast.makeText(intergps.this, "Erreur lors de l'analyse de la réponse: " + e.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                tv_sensorData.setText("Erreur");
                Toast.makeText(intergps.this, "Erreur de requête: " + error.toString(), Toast.LENGTH_LONG).show();
            }
        });

        Volley.newRequestQueue(this).add(jsonObjectRequest);
    }

    private void startLocationUpdates() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            tv_updates.setText("Loc est enregistrer");
            fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallBack, null);
            updateGPS();
        } else {
            // Demander la permission ACCESS_FINE_LOCATION à l'utilisateur
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_FINE_LOCATION);
        }
    }

    private void stopLocationUpdates() {
        tv_updates.setText("Loc n'sts plus enregistrer");
        tv_lat.setText("Loc n'sts plus enregistrer");
        tv_lon.setText("Loc n'sts plus enregistrer");
        tv_address.setText("Loc n'sts plus enregistrer");
        tv_accuracy.setText("Loc n'sts plus enregistrer");
        tv_altitude.setText("Loc n'sts plus enregistrer");
        tv_sensor.setText("Loc n'sts plus enregistrer");

        fusedLocationProviderClient.removeLocationUpdates(locationCallBack);

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case PERMISSION_FINE_LOCATION:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                updateGPS();
            }
            else {
                Toast.makeText(this, "le prgramme nessecite des permeission pour s'executer", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    private void updateGPS(){



        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(intergps.this);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    //met les valeurs de loc dans UI component
                    updateUIValues(location);
                    currentLocation = location;


                }
            });


        } else {
            //pas encore de permissioon
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_FINE_LOCATION);
            }


        }
    }

    private void updateUIValues(Location location) {
        //update toute les vleur dans les texte viexw

        tv_lat.setText(String.valueOf(location.getLatitude()));
        tv_lon.setText(String.valueOf(location.getLongitude()));
        tv_accuracy.setText(String.valueOf(location.getAccuracy()));

        if (location.hasAltitude()){
            tv_altitude.setText(String.valueOf(location.getAltitude()));

        }

        else {
            tv_altitude.setText("pas de valeur");
        }

        MyApplication myApplication = (MyApplication)getApplicationContext();
        savedLocations = myApplication.getMyLocations();

        //montre les way points sauvegarder

        tv_WayPointCounts.setText(Integer.toString(savedLocations.size()));




    }

}

Database Manager JAVA

Java
package com.chahine.projetiot;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.content.Context;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class DatabaseManager {

    private Context context;

    public RequestQueue queue;

    public DatabaseManager(Context context){
        this.context =  context;
        this.queue = Volley.newRequestQueue(context);

    }


}

Register Activity JAVA

Java
package com.chahine.projetiot;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.android.material.textfield.TextInputLayout;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class RegisterActivity extends AppCompatActivity {
    private TextView alreadyHasAccountBtn;
    private TextView errorCreateAccountTextView;
    private Button createAccountBtn;

    private EditText usernameEditText;
    private EditText passwordEditText;

    private String username;
    private String password;

    private DatabaseManager databaseManager;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_register);

            alreadyHasAccountBtn = findViewById(R.id.alreadyHasAccountBtn);
            createAccountBtn = findViewById(R.id.createAccountBtn);

            TextInputLayout usernameTextInputLayout = findViewById(R.id.usernameTextInputLayout); // Assurez-vous que l'ID est correct
            TextInputLayout passwordTextInputLayout = findViewById(R.id.passwordTextInputLayout); // Assurez-vous que l'ID est correct

            // Initialiser les EditText en récupérant les TextInputEditText à l'intérieur des TextInputLayout
            usernameEditText = usernameTextInputLayout.getEditText();
            passwordEditText = passwordTextInputLayout.getEditText();


            databaseManager = new DatabaseManager(getApplicationContext());

            createAccountBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    username = usernameEditText.getText().toString();
                    password = passwordEditText.getText().toString();

                    createAccount();
                    // requete pour user to bdd
                }
            });

            alreadyHasAccountBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent createAccountActivity = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(createAccountActivity);


                }
            });
        }


        public void onApiResponse(JSONObject response){
            try {
                boolean success = response.getBoolean("success"); // Utilisez la bonne clé ici

                if (success){
                    Intent interfaceActivity = new Intent(getApplicationContext(), intergps.class);
                    interfaceActivity.putExtra("username", username);
                    startActivity(interfaceActivity);
                    finish();
                } else {
                    String error = response.optString("error"); // Utilisez optString pour éviter JSONException
                    errorCreateAccountTextView.setVisibility(View.VISIBLE);
                    errorCreateAccountTextView.setText(error);
                }
            }catch (JSONException e){
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "Erreur lors de l'analyse de la réponse : " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }

        public void createAccount(){

            String url = "http://192.168.1.141/api/actions/createAccount.php";

            Map<String, String> params = new HashMap<>();
            params.put("username",username);
            params.put("password",password);
            JSONObject parameters = new JSONObject((params));

            JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, parameters, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {

                    onApiResponse(response);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    String errorMessage = error.getMessage();
                    if (errorMessage == null) {
                        errorMessage = "Une erreur inconnue est survenue"; // Message d'erreur par défaut
                    }
                    Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
                }

            });


            databaseManager.queue.add(jsonObjectRequest);
        }







    }

Register Activity XML

XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_color"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="10dp">


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:text="Inscription"
                android:textColor="@color/white"
                android:fontFamily="@font/dm_medium"
                android:textSize="22sp" ></TextView>
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="80dp"
            android:fontFamily="@font/dancing_bold"
            android:gravity="center"
            android:padding="5dp"
            android:text="PetGPS"
            android:drawableEnd="@mipmap/petgpsa_foreground"
            android:drawablePadding="10dp"
            android:textColor="@color/white"
            android:textSize="45sp"

            ></TextView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="140dp"
            android:orientation="vertical"
            android:background="@drawable/round_border">

            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:id="@+id/usernameTextInputLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:hint="Définis ton nom d'utilisateur"
                app:boxCornerRadiusBottomEnd="8dp"
                app:boxCornerRadiusBottomStart="8dp"
                app:boxStrokeColor="@color/icon_color"
                app:boxCornerRadiusTopEnd="8dp"
                app:boxCornerRadiusTopStart="8dp"
                app:hintTextColor="@color/black">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:drawableStart="@drawable/baseline_account_circle_24"
                    android:drawablePadding="10dp"
                    android:drawableTint="@color/app_color"
                    android:inputType="text" ></com>
            </com.google.android.material.textfield.TextInputLayout>




            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:id="@+id/passwordTextInputLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:hint="Définis ton mot de passe"
                app:boxStrokeColor="@color/icon_color"
                app:boxCornerRadiusBottomEnd="8dp"
                app:boxCornerRadiusBottomStart="8dp"
                app:boxCornerRadiusTopEnd="8dp"
                app:boxCornerRadiusTopStart="8dp"
                app:passwordToggleEnabled="true"
                app:hintTextColor="@color/black">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:drawableStart="@drawable/baseline_adb_24"
                    android:drawablePadding="10dp"
                    android:drawableTint="@color/app_color"
                    android:inputType="textPassword" ></com>
            </com.google.android.material.textfield.TextInputLayout>

            <Button
                android:id="@+id/createAccountBtn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                app:backgroundTint="@color/button_color2"
                android:padding="20dp"
                android:text="S'INSCRIRE"
                android:textColor="@color/black"
                android:textSize="18dp"
                android:fontFamily="@font/dm_medium">
            </Button>

            <TextView
                android:id="@+id/alreadyHasAccountBtn"
                android:layout_width="wrap_content"
                android:layout_height="89dp"
                android:layout_gravity="center"
                android:fontFamily="@font/dm_medium"
                android:onClick="login"
                android:padding="5dp"
                android:text="Dejà un compte? Connecte-toi ici  "
                android:textColor="@color/app_color"
                android:textSize="20sp" ></TextView>


        </LinearLayout>


    </LinearLayout>

</RelativeLayout>

Code MKR1310

Arduino
#include <Wire.h>
#include <MKRWAN.h>
#include "DHT.h"

// Registers and address for ADXL345
#define ADXL345_ADDRESS (0x53)  // Use the 7-bit address directly
#define ADXL345_REGISTER_XLSB (0x32)

// DHT Sensor setup
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// LoRa Modem setup
LoRaModem modem;
String appEui = "0511200119111998";
String appKey = "4F40A0A396B61B163459561DEA46A7CB";

int accelerometer_data[3];

void setup() {
  Wire.begin(); // Start I2C
  Serial1.begin(115200);
  while (!Serial);

  Serial.println("test avant connexion");
  if (!modem.begin(EU868)) {
    Serial.println("Failed to start module");
    while (1);
  }

  int connected = modem.joinOTAA(appEui, appKey);
  if (!connected) {
    Serial.println("Something went wrong; are you indoor? Move near a window and retry");
    while (1) {}
  }
  Serial.println("test apres connexion");

  dht.begin(); // Start DHT sensor
  init_adxl345(); // Initialize ADXL345 sensor
  modem.minPollInterval(60); // Set poll interval to 60 secs.
}

void loop() {
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();
  read_adxl345(); // Update accelerometer data
  
  // Print sensor readings
  Serial.print("Humidité: ");
  Serial.print(humidity);
  Serial.print("%, Température : ");
  Serial.print(temperature);
  Serial.println("C");
  
  Serial.print("ACCEL: ");
  Serial.print(float(accelerometer_data[0]) * 3.9 / 1000, 2);
  Serial.print(", ");
  Serial.print(float(accelerometer_data[1]) * 3.9 / 1000, 2);
  Serial.print(", ");
  Serial.println(float(accelerometer_data[2]) * 3.9 / 1000, 2);

  // Preparing the data for sending
  byte data[8]; // Adjust t
  he array size for your data
  data[0] = (byte)humidity;
  data[1] = (byte)temperature;
  
  // Convert accelerometer data to bytes and add to array
  data[2] = (accelerometer_data[0] >> 8) & 0xFF;
  data[3] = accelerometer_data[0] & 0xFF;
  data[4] = (accelerometer_data[1] >> 8) & 0xFF;
  data[5] = accelerometer_data[1] & 0xFF;
  data[6] = (accelerometer_data[2] >> 8) & 0xFF;
  data[7] = accelerometer_data[2] & 0xFF;

  // Sending data via LoRa
  modem.beginPacket();
  modem.write(data, sizeof(data));
  int err = modem.endPacket(true);
  if (err > 0) {
    Serial.println("Message sent correctly!");
  } else {
    Serial.println("Error sending message :(");
  }

  delay(10000); // Wait for 10 seconds before next read
}

// Functions to initialize and read from ADXL345
void init_adxl345() {
  Wire.beginTransmission(ADXL345_ADDRESS);
  Wire.write(0x2D);  // Power control register
  Wire.write(0x08);  // Set the measure bit to enable measurement mode
  Wire.endTransmission();

  Wire.beginTransmission(ADXL345_ADDRESS);
  Wire.write(0x31);  // Data format register
  Wire.write(0x01);  // Set to +/- 4g
  Wire.endTransmission();
}

void read_adxl345() {
  Wire.beginTransmission(ADXL345_ADDRESS);
  Wire.write(ADXL345_REGISTER_XLSB);
  Wire.endTransmission(false); // Restart condition
  Wire.requestFrom(ADXL345_ADDRESS, 6); // Request 6 bytes from the ADXL345
  
  if (Wire.available() == 6) {
    accelerometer_data[0] = (int16_t)(Wire.read() | Wire.read() << 8); // X-axis data
    accelerometer_data[1] = (int16_t)(Wire.read() | Wire.read() << 8); // Y-axis data
    accelerometer_data[2] = (int16_t)(Wire.read() | Wire.read() << 8); // Z-axis data
  }
}

Code Leonardo GPS Shield

Arduino
#include <TinyGPS++.h>  // Utilisez TinyGPS++ ici
#include <SoftwareSerial.h>

// La vitesse de transmission du GPS
static const int RXPin = 11, TXPin = 12;
static const uint32_t GPSBaud = 9600;

typedef union {
  float floatingPoint;
  uint32_t as_int;
} binaryFloatConversion;

typedef union {
  float floatingPoint;
  byte binary[4];
} binaryFloat;

// L'objet TinyGPS++
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(115200);  // Démarrez la communication série avec l'ordinateur
  Serial1.begin(GPSBaud);  // Démarrez la communication série avec le GPS

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

int counter = 0;

void loop()
{
  // Affiche les informations à chaque fois qu'une nouvelle phrase est correctement encodée.
  while (Serial1.available() > 0)
    if (gps.encode(Serial1.read()))
      displayInfo();

  // Si aucune donnée n'est reçue après un certain temps, affichez un message d'erreur.
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);  // Utilisez avec prudence, cela va bloquer toute autre opération
  }
}
void displayInfo()
{
  binaryFloatConversion arg;
  binaryFloat lng,lat;
   delay(100);
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
    // get access to the float as a byte-array:
    arg.floatingPoint = gps.location.lng();
    lng.floatingPoint =  gps.location.lng();
    lat.floatingPoint =  gps.location.lat();
    Serial.print(" Binary : ");
    Serial.print(arg.as_int, HEX);
    Serial.print("Counter : ");
    Serial.print(counter);

  // write the data to the serial
    if(counter == 200){
    ss.write(lat.binary,4);
    ss.write(lng.binary,4);
    counter = 0;
    }
    else counter ++;
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

Network Security Config

XML
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">192.168.1.141</domain>
    </domain-config>



</network-security-config>

function recup Node-RED

JavaScript
// Fonction pour extraire les données du decoded_payload
var humidity = msg.payload.uplink_message.decoded_payload.humidity;
var temperature = msg.payload.uplink_message.decoded_payload.temperature;
var acceleration = msg.payload.uplink_message.decoded_payload.acceleration;

// Préparation de l'objet à insérer dans la BDD
msg.payload = {
    humidity: humidity,
    temperature: temperature,
    accelerationX: acceleration.x,
    accelerationY: acceleration.y,
    accelerationZ: acceleration.z
};

return msg;

function insert Node-RED

JavaScript
// Créez la chaîne de requête SQL à envoyer au nœud MySQL
var sql = "INSERT INTO pet_tracking (humidity, temperature, accel_x, accel_y, accel_z) VALUES (";
sql += msg.payload.humidity + ", ";
sql += msg.payload.temperature + ", ";
sql += msg.payload.accelerationX + ", ";
sql += msg.payload.accelerationY + ", ";
sql += msg.payload.accelerationZ + ");";

// Préparez le message pour le nœud MySQL
msg.topic = sql;
return msg;

GetTemperature

PHP
<?php
header('Content-Type: application/json');
include_once '../config/Database.php';

$result = array("success" => false);

// Requête pour obtenir la dernière température enregistrée
$query = $bdd->query('SELECT temperature,humidity,accel_x,accel_y,accel_z,timestamp  FROM pet_tracking ORDER BY timestamp DESC LIMIT 1');

if ($data = $query->fetch()) {
    $result["success"] = true;
    $result["temperature"] = $data["temperature"];
    $result["accel_x"] = $data["accel_x"];
    $result["accel_y"] = $data["accel_y"];
    $result["accel_z"] = $data["accel_z"];
    $result["timestamp"] = $data["timestamp"];
} else {
    $result["error"] = "Aucune donnée disponible";
}

echo json_encode($result);
?>

database

PHP
<?php
header('Content-type: application/json; charset=utf-8');

// Paramètres de connexion à la base de données
$host ='localhost';
$dbname ='db_petgps';
$user = 'root';
$password = '';

try {
    $bdd = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8;port=3307", $user, $password);
    // Pour afficher les erreurs SQL dans les exceptions
    $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo 'Erreur de connexion : ' . $e->getMessage();
    exit;
}
?>

ConnectUser

PHP
<?php
header('Content-Type: application/json');
include_once '../config/database.php';
$json = json_decode(file_get_contents('php://input'), true);

//$result = array("success" => false, "error" => "Erreur inconnue"); // Initialisation de la réponse

if (isset($json['username']) && isset($json['password'])) {
    $username = htmlspecialchars($json['username']);
    $password = htmlspecialchars($json['password']);

    $getUser = $bdd->prepare("SELECT userPassword FROM users WHERE username = ?");
    $getUser->execute(array($username));

    if ($getUser->rowCount() > 0) {
        $user = $getUser->fetch();

        if (password_verify($password, $user['userPassword'])) {
            $result["success"] = true;
            unset($result["error"]); // Suppression de l'erreur
        } else {
            $result["error"] = "Mot de passe incorrect";
        }
    } else {
        $result["error"] = "Ce nom d'utilisateur n'existe pas";
    }
} else {
    $result["error"] = "Champs non remplis";
}

echo json_encode($result);
?>

Credits

Chahine TALEB

Chahine TALEB

1 project • 0 followers
Nicolas DAILLY

Nicolas DAILLY

29 projects • 17 followers
Associated Professor at UniLaSalle - Amiens / Head of the Computer Network Department / Teach Computer and Telecommunication Networks
Mathis André

Mathis André

0 projects • 0 followers
fcaron

fcaron

12 projects • 1 follower

Comments