Petfind
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ![](https://hackmd.io/_uploads/By690nJB2.jpg) ------------------- # PETFIND DOCUMENTACIÓ Volem crear un sistema de control per a les mascotes, la intenció és fer un GPS i desenvolupar diverses funcions com per exemple poder delimitar una zona de seguretat, i si la mascota surt d'aquella zona, rebre una notificació al telèfon mitjançant alguna app (geofencing). Mitjançant una raspberry Pi zero, un mòdul GPS, una bateria i una carcassa, crearem un aparell per poder rastrejar les nostres mascotes, això ho veurem representat a una pàgina web. La intenció també és incorporar algun sensor a l'aparell per poder crear alguna estadística del comportament de l'animal, com per exemple les hores de descans, la velocitat de l'animal e.t.c. Això ho volem dur a terme mitjançant una Raspberry Pi que es comuniqui amb una app instal·lada al nostre mòbil. ![](https://hackmd.io/_uploads/ByyN01r8h.png) ## Raspberry Pi Perquè hem escollit fer aquest projecte amb una Raspberry Pi? 1. Capacitat de processament: La Raspberry Pi té un processador més potent i major capacitat de memòria en comparació amb la majoria de les plaques Arduino. Si el teu projecte de dispositiu GPS requereix processament de dades complexes, càlculs intensius o l'execució de múltiples tasques simultàniament, la Raspberry Pi pot gestionar aquestes tasques de manera més eficient. 2. Sistema operatiu complet: La Raspberry Pi és un ordinador de ple dret que admet sistemes operatius complets, com ara Raspbian (basat en Linux). Això t'ofereix la flexibilitat d'executar aplicacions més complexes i aprofitar l'ampli ventall de programari i llibreries disponibles per a Linux. 3. Connectivitat: La Raspberry Pi té diversos ports USB i Ethernet integrats, el que facilita la connexió i comunicació amb altres dispositius i serveis externs. Això pot ser útil si vols enviar les dades de GPS a través de la xarxa, emmagatzemar-les en una base de dades remota o integrar el dispositiu GPS amb altres sistemes. 4. Interfícies gràfiques i visualització: Si vols mostrar informació visual, mapes o interfícies gràfiques d'usuari, la Raspberry Pi pot oferir-te més opcions. Amb la seva capacitat de sortida de vídeo i suport per a pantalles, pots desenvolupar una interfície gràfica d'usuari per interactuar amb el dispositiu GPS o mostrar informació en temps real. 5. Flexibilitat i escalabilitat: La Raspberry Pi és altament flexible i escalable, el que significa que pots afegir components addicionals, com ara càmeres, sensors o mòduls de comunicació, per ampliar les capacitats del teu dispositiu GPS. A més, la Raspberry Pi té una comunitat activa de desenvolupadors i un ampli ventall de recursos disponibles en línia. ## Funcionament ![](https://hackmd.io/_uploads/B1fA0kBL3.jpg) ## Mòdul GPS ![](https://i.imgur.com/1yRxB8N.jpg) Hem escollit el mòdul GY-GPS6MV2 NEO-6M, el que ens interessa d'aquest mòdul és la seva dimensió reduïda, i que consta d'una antena de ceràmica, que comporta un consum més baix de bateria. El GPS NEO-6M té un temps d'encesa d'uns 27 segons en fred i 1 segon en calent i la freqüència màxima de mesuratge és de 5Hz. Aquests valors ens encaixen amb el que busquem per al nostre prototip de PETFIND. datasheet: https://datasheethub.com/gy-neo6mv2-flight-control-gps-module/ ### Connexió mòdul GPS - Raspberry El GPS neo 6 disposa d'interfícies de comunicació UART, SPI, DDC(I2C) i USB. També suporta els protocols NMEA, UBX binary i RTCM. La intensitat de corrent necessari és d'uns 37mA en mode de mesurament continu i la tensió d'alimentació és de 2.7 a 3.6V. En el nostre cas hem hagut de soldar els pins al mòdul GPS, ja que no venien soldats. ![](https://hackmd.io/_uploads/r16nhztN2.png) El següent pas ha estat instal·lar el sistema a la targeta SD, per fer la configuració amb SSH des de l'ordinador a la raspberry. Això ho hem fet amb l'eina [Raspberry Pi Imager](https://www.raspberrypi.com/software/) Per programar la raspberry des de l'ordinador, hem baixat el git a la raspberry i l'hem lligat amb el de l'ordinador. Un cop fet aquest pas, ja podem pujar el codi fet a l'ordinador a la raspberry. ``` $ ssh-keygen -t rsa -C "my@mail.com" ``` ![](https://hackmd.io/_uploads/rkJiuQYEn.png) ![](https://hackmd.io/_uploads/S1JxtXFN2.png) ![](https://hackmd.io/_uploads/SkZdt7YE3.png) També hem ajuntat l'arxiu main.py amb el de la raspberry. El següent pas és connectar el mòdul GPS amb la raspberry, per fer-ho seguim l'esquema indicat a la imatge, el GND del mòdul hi connectem el GND de la raspberry, el Vcc és per on alimentem el sensor, i ho connectem al pin 5v de la raspberry. Finalment, necessitem activar els pins UART de la raspberry, utilitzarem el PL011, ja que és més estable i efectiu. Aquests ports són 3.3v així que si ho volem connectar amb algun aparell amb 5v hauríem d'emprar un adaptador. ![](https://hackmd.io/_uploads/HJ8mjmYEh.png) #### Configuració ports UART (PL011) Hem de configurar aquests ports, ja que per defecte la raspberry utilitza aquest port com a consola serial, per fer-ho ens connectem a la raspberry i seguim els següents passos: 1. Entrar a raspi-config: `$ sudo raspi config` 2. Seleccionar opció: 3 - Interface Options. 3. Seleccionar opció: P6 - Serial Port. 4. Quan surt *Would you like a login shell to be accessible over serial?* Contestem *No* 5. Quan surt *Would you like the serial port hardware to be enabled?* Contestem *Yes* 6. Sortim de la configuracio i reiniciem la Pi perque els canvis tinguin efecte `$ sudo reboot` Ara per desconnectar el mòdul bluetooth seguim els següents passos: 1. Posem la comanda `$ sudo nano /boot/config.txt` 2. Afegim segons el model de raspberry el següent text al final de l'arxiu: `dtoverlay = disable-bt` o `dtoverlay=pi3-miniuart-bt` 3. Finalment fem un `$ sudo reboot` per actualitzar els canvis. Un altre pas que podem dur a terme per desactivar el servei que inicialitza el mòdem i evitar així que es connecti al UART, utilitzem la comanda: `$ sudo systemctl diable hciuart` Per comprovar que tot estigui correcte introduïm la comanda; `$ ls -l /dev/serial*`, i hauríem de veure el següent: ![](https://hackmd.io/_uploads/Bki5uBFV2.png) Si ho hem fet correctament, ens hauria de sortir que el serial0 va lligat amb el ttyAMA0 i el serial1 amb el ttyS0. Per comprovar si rebem dades posem la comanda `$ sudo cat/dev/serial0` seguidament començarem a rebre informació. Posarem l'atenció en la sentència que comenci per ($GPRMC). #### Fer el 'fix' amb el GPS En pic tenim el GPS i la raspberry connectats, necessitem fer fix amb el GPS. Fer "fix" amb el teu GPS significa obtenir una ubicació precisa i estable. El terme "fix" s'utilitza comunament en referència al procés en què el receptor GPS determina amb precisió la teva ubicació en funció dels senyals dels satèl·lits. Per aconseguir un "fix" fàcilment, és recomanable usar el GPS a l'aire lliure o en àrees amb una visibilitat clara del cel. Els edificis, arbres i altres obstacles poden afectar la qualitat del senyal i dificultar l'obtenció d'un "fix" més precís. Aquesta és la taula del primer fix del nostre model de GPS: ![](https://hackmd.io/_uploads/H1Zr9RJr2.png) Segons la taula amb una 'cold start' hauria de tardar 27 segons a fer el fix, però després de diverses proves hem comprovat que aquest temps pot allargar-se un parell de minuts. ##### Sequència GPRMS En pic hem fet el fix del GPS, a l'introduir la comanda `$ sudo cat/dev/serial0` començarem a rebre informació. La seqüència que ens interessa és la GPRMS, aquesta es compon de la següent manera; ``` $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a\*hh ``` | x | Significat | |:---------:| ------------------------------------ | | hhmmss.ss | Hora UTC | | A | Estat receptor (A = OK, V = warning) | | llll.ll,a | Latitud (a = N o S) | | yyyy.yy,a | Longitud (a = E o W) | | x.x | Velocitat en nusos | | x.x | Curs en graus | | ddmmyy | Data UT | | x.x,a |Variació magnètica en graus (a = E o W)| | *hh | Checksum | Per saber que hem fet el fix correctament haurem de tenir una 'A' en el estat receptor, això ens indicarà que rebem les dades correctament. ## Script Pi Petfind Per a recollir les dades del GPS i de la bateria i guardar-les a la BBDD fem un petit programa amb Python Instal·lem la llibreria [MYSQL-Connector-Pyhton](https://https://pypi.org/project/mysql-connector-python/) per a connectar-nos a la BBDD remota i poder fer queries ``` $ pip install mysql-connector-python ``` Creem un fitxer python nou. ``` $ sudo nano petfind.py ``` Introduïm el següent codi. https://github.com/pablocarol/petfind-script ``` import smbus import time import serial import mysql.connector import time from datetime import datetime # BUS VOLTAGE REGISTER (R) _REG_BUSVOLTAGE = 0x02 # CALIBRATION REGISTER (R/W) _REG_CALIBRATION = 0x05 db = mysql.connector.connect( host="bbdd-connection-url", user="bbdd-user", port="bbdd-port", password="bbdd-password", database="bbdd-name" ) ``` En aquest primer apartat importem les diferents llibreries necessàries per al funcionament del codi, després declarem 2 constants que ens ajudaran a llegir i calibrar els registres de memòria on tenim les lectures del voltatge. En acabat inicialitzem una variable db amb la informació de connexió per la base de dades remota. ``` def parse_gprmc(gprmc_sentence): fields = gprmc_sentence.split(',') if fields[2] != 'A': return (None, None, None) lat = float(fields[3][:2]) + float(fields[3][2:]) / 60 lon = -1 * (float(fields[5][:3]) + float(fields[5][3:]) / 60) speed = float(fields[7]) * 1.852 if fields[4] == 'S': lat = -1 * lat if fields[6] == 'E': lon = -1 * lon return (lat, lon, speed) ``` La funció *parse_gprmc* rep per paràmetre la cadena GPRMC i ens la converteix en dades de longitud, latitud i velocitat. Primer comprova que contingui la A, això vol dir que la cadena es valida. Després fa la conversió de longitud, latitud i velocitat. Més tard depenent en l'hemisferi que ens trobem inverteix la longitud i la latitud. ``` class INA219: def __init__(self, i2c_bus=1, addr=0x40): self.bus = smbus.SMBus(i2c_bus); self.addr = addr self._cal_value = 0 self._current_lsb = 0 self._power_lsb = 0 self.set_calibration_16V_5A() def read(self,address): data = self.bus.read_i2c_block_data(self.addr, address, 2) return ((data[0] * 256 ) + data[1]) def write(self,address,data): temp = [0,0] temp[1] = data & 0xFF temp[0] =(data & 0xFF00) >> 8 self.bus.write_i2c_block_data(self.addr,address,temp) def set_calibration_16V_5A(self): self._cal_value = 26868 def getBusVoltage_V(self): self.write(_REG_CALIBRATION,self._cal_value) self.read(_REG_BUSVOLTAGE) return (self.read(_REG_BUSVOLTAGE) >> 3) * 0.004 ``` La classe *INA219* ens ajuda a fer lectures de voltatge per saber l'estat actual de la bateria a través del port I2C. Tenim diferents funcions per llegir, escriure i calibrar. ``` ina219 = INA219(addr=0x43) cursor = db.cursor() ser = serial.Serial('/dev/serial0', baudrate=9600, timeout=1) counter = 0 ``` Declarem 3 variables, *ina219* per llegir el estat de la bateria, *cursor* per fer crides a la BBDD i *ser* per llegir el port serial ``` while True: line = ser.readline().decode('ISO-8859-1').rstrip() bus_voltage = ina219.getBusVoltage_V() p = (bus_voltage - 3)/1.2*100 if(p > 100):p = 100 if(p < 0):p = 0 print(f"Percent: {int(p)}%") print("") sql = "UPDATE petfind.battery_status t SET t.percent_charged = (%s) WHERE t.battery_id = 3" cursor.execute(sql, (int(p),)) db.commit() if line.startswith('$GPRMC'): lat, lon, speed = parse_gprmc(line) if lat is None: continue print(f'Latitud: {lat}, Longitud: {lon}, Velocitat: {speed} knots') if(counter == 30): print("Inserting into database last coordinates") sql = "INSERT INTO coordinate_log (lat, lon, speed, time_stamp) VALUES (%s, %s, %s, %s)" cursor.execute(sql, (lat, lon, speed, datetime.now())) db.commit() counter = 0 else: counter++ ``` Aquí tenim el bucle principal del script on llegirem el port serial i el bus de voltatge, després farem els càlculs pertinents per determinar el tant percentatge de bateria. Mostrem el percentatge de bateria per consola i farem un update a la taula de *battery_status*. Cada 30 lectures, la comanda *db.commit()* aplicarà els canvis a la BBDD remota. Un cop acabat comprovem que la cadena comenci per GPRMC que és on està la informació que ens interessa. Cridem a la funció *parse_gprmc* que ens retornarà la latitud, longitud i velocitat actuals. Mostrarem aquesta informació per consola i seguidament la introduirem dins la BBDD a la taula de *coordinate_log* on també li afegirem el timestamp actual. ## Backend Per a construir el backend remot de forma gratuïta fem servir [Digital Ocean](https://https://www.digitalocean.com/) on tenim credits gratuits amb Github Educational. Amb aquesta eina podem fer deploys de màquines en el cloud en qüestió de minuts de manera gratuïta. Tenim disponibles ja màquines especials per a fer de bbdd MySQL i de Linux. ### Base de dades La BBDD mysql es troba en un servidor remot *db-mysql-nyc1-51434-do-user-7374472-0.b.db.ondigitalocean.com* anomenada petfind. ![](https://hackmd.io/_uploads/BkXQL1erh.png) La base de dades consta de 2 taules **coordinate_log** ![](https://hackmd.io/_uploads/HkYy1Jlr2.png) En aquesta taula guardem juntament amb una id generada automàticament, la latitud, longitud, velocitat i hora. **battery_status** ![](https://hackmd.io/_uploads/SyP2RRJBn.png) En aquesta taula simplement guardem el percentatge de bateria restant per així poder-lo mostrar a l'usuari. #### Script per la seva creació: ``` DROP TABLE IF EXISTS coordinate_log CASCADE; CREATE TABLE coordinate_log ( coordinate_id INT NOT NULL AUTO_INCREMENT, lat FLOAT NULL, lon FLOAT NULL, speed FLOAT NULL, time_stamp TIMESTAMP NULL, PRIMARY KEY (coordinate_id) ); DROP TABLE IF EXISTS battery_status CASCADE; CREATE TABLE battery_status ( battery_id INT NOT NULL AUTO_INCREMENT, percent_charged INT NOT NULL, PRIMARY KEY (battery_id) ); ``` ### Api L'API està funcionant en una màquina Linux en un servidor remot en la IP pública *165.232.73.173* ![](https://hackmd.io/_uploads/H1JPsVWS2.png) Instal·lem node.js i npm ``` $ sudo apt-get update $ curl -sL https://deb.nodesource.com/setup_11.x | bash - $ sudo apt-get install -y nodejs ``` Comprovem l'instal·lació correcta ``` $ node -v $ npm -v ``` Fem servir la *pm2* per executar l'API com un procés i tenir-lo de background. A més si l'aplicació 'crasheja' la reiniciarà sola. Instalem pm2 ``` $ sudo npm install -g pm2 ``` Podem iniciar la nostra aplicacio node.js ``` $ pm2 start index.js ``` Amb la comanda `$ pm2 list` hauriem de veure tots els processos que s'estan executant amb pm2. ![](https://hackmd.io/_uploads/SJGPbWeBn.png) Fem us de *ufw* com a firewall per a la maquina linux. Instal·lem ufw ``` $ sudo apt-get install ufw ``` Habilitem el tràfic ssh i http ``` $ sudo ufw allow ssh $ sudo ufw allow http ``` Després activem el firewall ``` $ sudo ufw enable ``` Comprovem que funciona amb `$ sudo ufw status` ![](https://hackmd.io/_uploads/SkBft1lr3.png) Fem ús de *nginx* com a reverse proxi per a reenviar tot el tràfic del port 80 al 3000, que és on tenim l'API executant-se. D'aquesta manera podrem accedir als nostres enpoints des de l'URL *165.232.73.173/endpoint* en canvi, de *165.232.73.173:3000/endpoint* Instal·lem *nginx* ``` $ sudo apt update $ sudo apt install nginx ``` Editarem el fitxer de configuració de nginx ``` $ sudo nano /etc/nginx/sites-available/default ``` Esborrarem tot el que hi ha i introduirem el següent codi ``` server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } ``` Amb tot això configurat ja podem escriure el nostre codi de l'API L'API és un petit programa en Node.js que fa us de les llibreries * [Express](https://https://www.npmjs.com/package/express) * [Cors](https://https://www.npmjs.com/package/cors) * [Mysql2](https://https://www.npmjs.com/package/mysql2) * [Dotenv](https://https://www.npmjs.com/package/dotenv) Creem un projecte nou de node.js ``` $ npm init -y ``` Instal·lem les llibreries ``` $ npm i express cors dotenv mysql2 ``` L'API fa crides a la base de dades i les retorna en format json a través de diferents endpoints. Tenim 4 endpoints disponibles: * /getAllLocations * /getLastLocation * /getLocationsByDate * /getBattery Podem trobar el codi complet a: https://github.com/pablocarol/petfind-api Tenim 4 fitxers: .env Aqui tenim la informacio de connexió de la BBDD [index.js](https://github.com/pablocarol/petfind-api/blob/main/index.js) En aquest fitxer definim els 4 enpoints i cridem a una funció del controler per a cada endpoint. [controller.js](https://github.com/pablocarol/petfind-api/blob/main/controller.js) Tenim una funcio async per a cada endpoint on fem una crida a la base de dades i mapejem el resultat per a retornar-lo en format json en cada endpoint. A més l'endpoint de *getLocationsByDate* rep 2 paràmetres per query data d'inici i data de fi */getLocationsByDate?dateIni=<dateini>&dateEnd=<dateend>*. Un URL d'exemple seria: http://165.232.73.173/getLocationsByDate?dateIni=2023-04-12T16:45:45.000Z&dateEnd=2023-04-28T16:50:45.000Z [database.js](https://https://github.com/pablocarol/petfind-api/blob/main/database.js) En aquest fitxer tenim les queries per fer les diferents crides a la BBDD Podem comprovar el funcionament correcte de l'API accedint als diferents endpoints públics. /getAllLocations ![](https://hackmd.io/_uploads/SyyDXllH2.png) /getLastLocation ![](https://hackmd.io/_uploads/ryteaygr2.png) /getLocationsByDate ![](https://hackmd.io/_uploads/SJGJQelr3.png) /getBattery ![](https://hackmd.io/_uploads/rkGrXxxHh.png) ## Frontend En el frontend hem volgut mantenir-ho simple, veiem un mapa de MapBox, algunes dades bàsiques del nostre gos i el percentatge de bateria restant al dispositiu. Tenim dos botons, un per mostrar l'última ubicació on ha estat el dispositiu i l'altre botó podem seleccionar un interval de temps i ens mostrarà la ruta que ha fet la nostra mascota en aquest interval. Per a construir el frontend remot de forma gratuïta també hem fem servir [Digital Ocean](https://https://www.digitalocean.com/) El frontend està funcionant en una màquina Linux en un servidor remot on hem instalat apache en la IP pública *167.172.182.92* ![](https://hackmd.io/_uploads/Sknfi4Zrn.png) Per començar instalem apache ``` $ sudo apt update $ sudo apt install apache2 ``` Podem comprobar que esta correctament instalat navegant a la nostre ip publica ![](https://hackmd.io/_uploads/S1T_QNbHh.png) Per fer-ho simple entrarem en el seguent directori ``` $ cd var/www/html ``` I a dins editarem el fitxer index.html i afegirem els fitxers que facin falta El nostre frontend consta de 3 fitxers HTML, CSS i JS. https://github.com/pablocarol/petfind-front Utilitzem la llibreria MapBox GL JS, on ens haurem de crear un compte i generarnos una api key. [style.css](https://github.com/pablocarol/petfind-front/blob/main/style.css) Per a poder pujar la imatge a la maquina linux remota hem utilitzat el l'eina pscp de PuTTY. Amb la seguent comanda pujem el logo de la pagina a la maquina remota. ``` $ pscp C:\petfind.png root@<remote_ip>:/var/www/html/ ``` [index.html](https://github.com/pablocarol/petfind-front/blob/main/index.html) [main.js](https://github.com/pablocarol/petfind-front/blob/main/main.js) Definim el token de *mapboxgl* La funció *setBatteryValue()* fa una crida a l'endpoint de /getBattery on rebrà el percentatge de bateria i actualitzarà el label de battery percent. La funcio *loadMapLastLocation()* és async i fa una crida a l'endpoint /getLastLocation on rep una array de 2 posicions amb la latitud i longitud respectivament. Després creem una nova instància d'un mapa posant el centre en les coordenades rebudes i afegim un marcador de color vermell en la posició rebuda. Amb la funció *document.addEventListener("DOMContentLoaded", <myfunction>)* podem fer que cada cop que es recarregui la pàgina s'executi *<myfunction>*. Afegim el valor de la bateria i fem que cada 15 segons es torni a cridar la funció, d'aquesta manera tindrem l'estat de la bateria actualitzada cada 15 segons. Aquestes dos funcions ens indicaran quin sera el centre del mapa i quin sera el zoom perque tots els punts es vegin dins del rectangle on visualitzem el mapa La funcio *getInitialZoom(minLat, maxLat, minLng, maxLng)* ens calcula el zoom a partir de les latituds i longituds maximes i minimes. Amb aixo calcula les diferencies entre latituds i longituds. Ho mulitplica per la relacio entre ample de pantalla i 360 graus. Despres divideix l'ample de la pantalla entre aquestes diferencies. D'aquest resultat fa el log en base 2. Aixo ho fa per la longitud i la latitud, despres escull el vallor mes petit dels 2 (que sera el zoom mes alluyat). Explicacio de com hem arribat a la formula simplificada del codi: ![](https://hackmd.io/_uploads/BkTapX-Sn.png) La funcio *getInitialZoomAndCenter(data)* rep un set de coordenades, les separa en longituds i latituds i busca els valors minims i maxims. Despres busca el punt mig d'aquestes fent la suma i dividint entre 2. D'aquesta manera podem determinar el centre del mapa. Amb la funció *loadMapByDate()* generarem un mapa amb el recorregut de localitzacions entre 2 dates. Primer recollim les dates d'inici i fi amb *document.getElementById("date-ini").value* i *document.getElementById("date-end").value*. Despres cridem al endpoint /getLocationsByDate pasant per query la data d'inici i de fi. A continuacio convertim totes aquestes coordenades en punts GeoJSON amb una propietat, si es inici, fi o enmig. D'aquesta manera posteriorment podrem deifinir un color per cada tipus de punt. Despres amb les funcions *map.addLayer()* podem anar afegint capas al mapa. Primer afegim les lineas entre els punts, definint que el tipus de GeoJSON es LineString. Despres afegim els punts i li diem que el color vagi en funcio del *pointType* definit anteriorment. Verd per inici, blau mig i vermell final. ![](https://hackmd.io/_uploads/r12vdxeH2.jpg) ![](https://hackmd.io/_uploads/B1XdOegr2.jpg) ## Bateria Pel que fa a respecte a les bateries hem de calcular quin serà el consum mitjà de tot el nostre circuit per tal de poder aconseguir la bateria que més s'adeqüi al nostre projecte. Necessitem saber els consums dels nostres components i sumar-los; * Raspberry --> 100mA - 140mA * Mòdul GPS --> 45mA * ''Mòdul SIM --> 400mA - 800mA'' ![](https://hackmd.io/_uploads/HJIC4JO43.gif) Fent ús d'aquesta fórmula, trobem el consum mitjà per hora que ens dona 865 mAh. Mirant les diverses opcions vam decidir que una de les que més ens encaixaven eren les bateries LiPo pel fet que les bateries LiPo són molt eficients, també són lleugeres i compactes (alta densitat d'energia). Això permet que la Raspberry Pi Zero pugui funcionar durant més temps amb una sola càrrega de bateria. A més, les bateries LiPo també ofereixen una descàrrega plana, la qual cosa significa que la tensió de la bateria es manté relativament constant durant tot el període de descàrrega. Això és important perquè la Raspberry Pi Zero requereix una tensió d'alimentació constant per funcionar correctament. D'entre les diverses opcions dintre de les bateries LiPo, vam veure que l'opció de 6000~ mA era la millor opció ja que no té un pes gaire elevat i ens podria aguantar més de 6 hores d'autonomia. [![](https://hackmd.io/_uploads/rJlqMkeHh.png)](https://tienda.bricogeek.com/baterias-lipo/418-bateria-lipo-6000mah-37v.html) Per tal de poder implementar una bateria a la raspberry haurem d'utilitzar un mòdul per adaptar la bateria a la placa, com és el cas del SAI HAT, tant de bateries lipo com de bateries 18650. Aquests mòduls ens regulen la potència necessària per a fer funcionar la raspberry així com ens donen l'opció de treure les bateries per carregar-les de manera externa. Per a crear el prototip nosaltres hem usat un [HAT de 1000mAh](https://magpi.raspberrypi.com/articles/review-ups-hat-for-raspberry-pi-zero-wh) que ens aguanta més o menys una hora. ![](https://hackmd.io/_uploads/HyKIV1xB3.png) ## Carcassa La carcassa l'hem dissenyat a través de l'aplicació sharp3D. Una aplicació basada en el sistema CAD, amb aquest disseny volem aconseguir una fàcil comprensió per part de l'usuari i també que sigui còmode i agradable per l'animal que el porti. Al principi de tot vam començar amb la idea d'un disseny modular, però a mesura que hem anat incorporant més funcionalitats el disseny ha anat canviant el seu aspecte. Finalment, ens ha quedat un prototip una mica més gran però alhora més funcional i resistent. ![](https://hackmd.io/_uploads/B1ymwRJB3.jpg) ![](https://hackmd.io/_uploads/Byk7wC1Hh.jpg) ![](https://hackmd.io/_uploads/Sy4HI5jrn.jpg) ## NFC Per al módul NFC hem utilitzat un NFC NTAG 215 en format de moneda ja que era el format més adeqüat per les petites dimensions de la caixa. Per programar el módul NFC per tal de que al apropar un teléfon Android hi ensenyi l'informació més rellevant i necessaria del animal i el seu amo, hem utilitzat l'aplicació "NFC Tools" (Aplicació gratuita per Android) amb la qual pots programar diverses funcionalitats, entre elles, printar informació a la pantalla mitjançant una nota. ![](https://hackmd.io/_uploads/Hke0-79iBn.jpg) ![](https://hackmd.io/_uploads/r1ZAWm9sHh.jpg) ## Futures implementacions En el futur ens agradaria dur a terme algunes millores per a completar el projecte. * Geofencing Un punt que ens agradaria implementar és la funció del geofencing, això implica que l'usuari pugui determinar una zona des de la web/app on quan la mascota surti d'aquesta zona l'usuari rebi un avís. * Mòdul 'SIM' El nostre prototip actualment funciona compartint wifi des del mòbil, però el que tenim pensat és que funcioni a partir d'un mòdul SIM, on l'usuari pugui demanar un duplicat de la seva SIM i posar-la a l'aparell ,ja que el funcionament amb WIFI limita molt la funcionalitat. * Millora de la web Volem anar actualitzant i implementant noves funcions útils a la nostra web, també millorar la interfície i l'experiència de l'usuari. * App mòbil De moment el prototip funciona amb una web, però ens agradaria també crear una app mòbil per així millorar la comoditat. * Millorar la carcassa Una millora necessària seria reduir la mida i el pes de la nostra carcassa, també buscar altres materials o dissenys perquè la mascota tingui una comoditat més bona. ## Equip ``` Pablo Carol Jordi Dalmau Pol Buixadé Jaume Borràs Alex Roncal ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully