Compare commits
1 Commits
feat/GRBL-
...
feat/lcd_c
Author | SHA1 | Date | |
---|---|---|---|
6e63ccb61d |
@ -1,4 +0,0 @@
|
||||
TIME_ZONE='Europe/Paris'
|
||||
DOLI_URL='http://0.0.0.0'
|
||||
DB_NAME="dolibarr"
|
||||
DB_PASS="password"
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,8 +7,7 @@
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
.idea/
|
||||
|
||||
# Aptatio/Platformio specifics
|
||||
secrets.ini
|
||||
.env
|
||||
.idea
|
12
config.ini
12
config.ini
@ -13,13 +13,7 @@ build_flags =
|
||||
; DO NOT TOUCH --- START
|
||||
-D MONITOR_SPEED=${config.monitor_speed}
|
||||
; DO NOT TOUCH --- END
|
||||
-D WAITING_WIFI_DELAY=1000
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; stepper config ;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
-D STEPMOTOR_I2C_ADDR=0x70
|
||||
-D STEPER_ACC=200
|
||||
;-D STEPER_PAS=755.906 ; = 65mm
|
||||
-D STEPER_PAS=58 ; = 5mm
|
||||
-D STEPER_SPEED=1000 ; 12000
|
||||
-D EXAMPLE_NUMBER=69
|
||||
|
||||
-D EXAMPLE_STRING=\"Pouet\"
|
||||
|
@ -1,10 +0,0 @@
|
||||
[config_api]
|
||||
build_flags =
|
||||
-D API_LOGIN_URL=\"/users/info\"
|
||||
-D API_LIST_PRODUCT_URL=\"/products/\"
|
||||
-D API_GET_PRODUCT_URL=\"/products/{id}/\"
|
||||
-D API_GET_PRODUCT_STOCK_URL=\"/products/{id}/stock/\"
|
||||
-D API_LIST_WAREHOUSE_URL=\"/warehouses/\"
|
||||
-D API_LIST_STOCKS_MOVEMENTS_URL=\"/stockmovements/?sortfield=t.rowid\"
|
||||
-D API_CREATE_STOCKS_MOVEMENTS_URL=\"/stockmovements/\"
|
||||
-D API_MAX_JSON_SIZE=4096
|
@ -1,27 +0,0 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:latest
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_PASS}
|
||||
MYSQL_DATABASE: ${DB_NAME}
|
||||
volumes:
|
||||
- database:/var/lib/mysql
|
||||
restart: always
|
||||
web:
|
||||
image: tuxgasy/dolibarr
|
||||
environment:
|
||||
DOLI_DB_HOST: mariadb
|
||||
DOLI_DB_USER: root
|
||||
DOLI_DB_PASSWORD: ${DB_PASS}
|
||||
DOLI_DB_NAME: ${DB_NAME}
|
||||
DOLI_URL_ROOT: ${DOLI_URL}
|
||||
PHP_INI_DATE_TIMEZONE: ${TIME_ZONE}
|
||||
restart: always
|
||||
# ports:
|
||||
# - "80:80"
|
||||
depends_on:
|
||||
- mariadb
|
||||
volumes:
|
||||
database:
|
@ -1,64 +0,0 @@
|
||||
# CRM Dolibarr
|
||||
|
||||
## Docker Image tuxgasy/dolibarr
|
||||
|
||||
### Description du composant
|
||||
|
||||
Dolibarr est le CRM utilisé pour gérer les stocks, les transactions et l'inventaire présents dans les entrepôts. Il est le pilier central du projet et nous servira d'interface pour gérer les transactions.
|
||||
|
||||
### Spécifications techniques
|
||||
|
||||
- **Image Docker**: [tuxgasy/dolibarr](https://hub.docker.com/r/tuxgasy/dolibarr/)
|
||||
- **Plugins utilisés**: Stock, API REST
|
||||
- **Utilisateur technique créé**: Technical User IoT
|
||||
|
||||
### Fonctionnalités principales
|
||||
|
||||
- Créer / Lister les différents entrepôts
|
||||
- Créer / Lister les produits disponibles dans un entrepôt
|
||||
- Créer un mouvement dans les stocks des produits disponibles dans chaque entrepôt
|
||||
- Exposer différents webservices pour automatiser certaines tâches
|
||||
|
||||
### Guide d'utilisation
|
||||
|
||||
#### Créer une instance de développement
|
||||
|
||||
Pour créer une instance de développement, nous allons utiliser l'image Docker de Dolibarr: [tuxgasy/dolibarr](https://hub.docker.com/r/tuxgasy/dolibarr/)
|
||||
|
||||
Pour simplifier l'installation, un fichier docker-compose est disponible à la racine du projet: `./docker-compose-dolibarr.yml`
|
||||
|
||||
Pour lancer Dolibarr, exécutez la commande suivante :
|
||||
```bash
|
||||
$ docker compose -f docker-compose-dolibarr.yml up
|
||||
```
|
||||
|
||||
#### Ensuite, il faut se rendre sur [http://0.0.0.0/](http://0.0.0.0/) puis se connecter avec les identifiants par défaut (admin, admin).
|
||||
|
||||
### Appel des différents webservices de Dolibarr
|
||||
|
||||
L'URL de base pour toutes nos requêtes HTTP (avec l'image Docker) est : `http://0.0.0.0/api/index.php`
|
||||
|
||||
Pour commencer, récupérez l'API token d'un utilisateur pour pouvoir effectuer des requêtes API. Assurez-vous que l'utilisateur dispose des autorisations nécessaires.
|
||||
|
||||
Ensuite, utilisez ce token pour chaque route API en l'ajoutant dans les en-têtes : `DOLAPIKEY = {{votre_api_token}}` de votre prochaine requête.
|
||||
|
||||
Pour récupérer le warehouse de base et vérifier son existence :
|
||||
- **Méthode**: GET
|
||||
- **URL**: `warehouses/{id}`
|
||||
|
||||
Pour récupérer les produits disponibles :
|
||||
- **Méthode**: GET
|
||||
- **URL**: `products?sortfield=t.ref&sortorder=ASC&limit=10000`
|
||||
|
||||
Pour créer un mouvement de stock :
|
||||
- **Méthode**: POST
|
||||
- **URL**: `stockmovements?sortfield=t.rowid&sortorder=ASC&limit=100`
|
||||
- **Body (JSON)**:
|
||||
```json
|
||||
{
|
||||
"product_id": "1", // string, - ID du produit à déplacer
|
||||
"warehouse_id": "1", // string - ID de l'entrepôt
|
||||
"qty": 60, // int - quantité à déplacer (1 pour positif ou -1 pour enlever un article)
|
||||
"movementcode": "S-1", // string - code du mouvement
|
||||
"movementlabel": "Abc" // string - libellé du mouvement
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
@startuml class
|
||||
|
||||
hide empty members
|
||||
|
||||
|
||||
class Dolibarr {
|
||||
+ String getDestination(String tagID)
|
||||
+ String createStockMovement(String tagID, String warehouseId)
|
||||
}
|
||||
|
||||
package "Managers" {
|
||||
abstract AManager {
|
||||
# ILCDScreen lcd
|
||||
# IServoMotor servo
|
||||
# IGRBL grbl
|
||||
# INFCReader nfc
|
||||
}
|
||||
|
||||
class WarehouseManager
|
||||
|
||||
WarehouseManager .|> AManager
|
||||
}
|
||||
|
||||
package "Components" {
|
||||
package "NFCReader" {
|
||||
interface INFCReader {
|
||||
{abstract} char* read()
|
||||
{abstract} bool hasTag()
|
||||
}
|
||||
class RC522
|
||||
RC522 .|> INFCReader
|
||||
}
|
||||
|
||||
package "LCDScreen" {
|
||||
interface ILCDScreen {
|
||||
{abstract} void clearScreen()
|
||||
{abstract} void draw(int x, int y, int h, int w)
|
||||
{abstract} void drawRect(int x, int y, int h, int w)
|
||||
}
|
||||
class M5LCD
|
||||
M5LCD .|> ILCDScreen
|
||||
}
|
||||
|
||||
package "GRBL" {
|
||||
interface IGRBL {
|
||||
{abstract} drive(int x, int y, int z, int step)
|
||||
{abstract} step(int s)
|
||||
}
|
||||
class M5GRBL
|
||||
M5GRBL .|> IGRBL
|
||||
}
|
||||
|
||||
package "ServoMotor" {
|
||||
interface IServoMotor {
|
||||
{abstract} goLeft()
|
||||
{abstract} goRight()
|
||||
{abstract} goMiddle()
|
||||
}
|
||||
class ServoMotor
|
||||
ServoMotor .|> IServoMotor
|
||||
}
|
||||
}
|
||||
|
||||
class Program {
|
||||
+ Program()
|
||||
+ void loop
|
||||
}
|
||||
|
||||
AManager <-- IServoMotor
|
||||
AManager <-- IGRBL
|
||||
AManager <-- ILCDScreen
|
||||
AManager <-- INFCReader
|
||||
|
||||
Program <-- WarehouseManager
|
||||
Program <-- Dolibarr
|
||||
|
||||
@enduml
|
@ -1,22 +0,0 @@
|
||||
@startuml hard wiring
|
||||
|
||||
cloud {
|
||||
[Dolibarr]
|
||||
}
|
||||
|
||||
package "Convoyeur"{
|
||||
[M5 Core]
|
||||
[Lecteur NFC] as nfc
|
||||
[Servo Moteur] as servo
|
||||
[GRBL]
|
||||
[Stepper Moteur] as Stepper
|
||||
}
|
||||
|
||||
|
||||
[Dolibarr] <-- [M5 Core] : API
|
||||
[M5 Core] --> servo : IO
|
||||
[M5 Core] <-- nfc : IC2
|
||||
[M5 Core] --> [GRBL] : SPI
|
||||
[GRBL] --> Stepper
|
||||
|
||||
@enduml
|
@ -2,8 +2,6 @@
|
||||
#define PROGRAM_H
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "DolibarrClient.h"
|
||||
#include <M5Stack.h>
|
||||
|
||||
class Program {
|
||||
public:
|
||||
@ -13,11 +11,9 @@ public:
|
||||
Program();
|
||||
|
||||
/**
|
||||
* Program WarehouseGUI loop
|
||||
* Program main loop
|
||||
*/
|
||||
void loop();
|
||||
private:
|
||||
DolibarrClient *client;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,151 +0,0 @@
|
||||
#include "DolibarrClient.h"
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <iostream>
|
||||
|
||||
DolibarrClient::DolibarrClient(struct DolibarrConfig dolibarr_config) : dolibarr(dolibarr_config) {
|
||||
#if defined(DEBUG)
|
||||
Serial.println(" --- Dolibarr configuration --- ");
|
||||
Serial.println((std::string("Base URL: ") + std::string(dolibarr_config.url)).c_str());
|
||||
Serial.println((std::string("Token: ") + std::string(dolibarr_config.api_key)).c_str());
|
||||
#endif
|
||||
this->initialize_http_client();
|
||||
}
|
||||
|
||||
HTTPClient *DolibarrClient::build_url(const String& url) const {
|
||||
auto *client = new HTTPClient();
|
||||
String clientUrl = this->dolibarr.url + url;
|
||||
client->begin(clientUrl);
|
||||
client->addHeader("Content-Type", "application/json");
|
||||
client->addHeader("DOLAPIKEY", this->dolibarr.api_key);
|
||||
#if defined(DEBUG)
|
||||
Serial.println("URL Request: " + clientUrl);
|
||||
#endif
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
int DolibarrClient::login() const {
|
||||
HTTPClient *client = this->build_url(API_LOGIN_URL);
|
||||
int httpResponseCode = client->GET();
|
||||
if (httpResponseCode > 0) {
|
||||
StaticJsonDocument<API_MAX_JSON_SIZE> doc;
|
||||
DeserializationError error = deserializeJson(doc, client->getString().c_str());
|
||||
if (error) {
|
||||
delete client;
|
||||
return -1;
|
||||
}
|
||||
delete client;
|
||||
return 0;
|
||||
}
|
||||
delete client;
|
||||
return -1;
|
||||
}
|
||||
|
||||
String replace_id(const char *str, const char *id) {
|
||||
String url(str);
|
||||
url.replace("{id}", id);
|
||||
return url;
|
||||
}
|
||||
|
||||
std::vector<models::Product> *DolibarrClient::list_products() const {
|
||||
HTTPClient *client = this->build_url(API_LIST_PRODUCT_URL);
|
||||
if (client->GET() == HTTP_CODE_OK) {
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
models::Product *DolibarrClient::get_product_by_id(const char* id_product) const {
|
||||
HTTPClient *client = this->build_url(replace_id(API_GET_PRODUCT_URL, id_product).c_str());
|
||||
if (client->GET() == HTTP_CODE_OK) {
|
||||
StaticJsonDocument<API_MAX_JSON_SIZE> doc;
|
||||
DeserializationError error = deserializeJson(doc, client->getString().c_str());
|
||||
if (error) {
|
||||
Serial.println("ERROR: ");
|
||||
Serial.println(error.c_str());
|
||||
delete client;
|
||||
return nullptr;
|
||||
}
|
||||
auto *product = new models::Product();
|
||||
product->date_creation = doc["date_creation"];
|
||||
product->id = doc["id"];
|
||||
product->entity = doc["entity"];
|
||||
product->stock_reel = doc["stock_reel"];
|
||||
product->label = doc["label"];
|
||||
delete client;
|
||||
return product;
|
||||
}
|
||||
delete client;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<models::Warehouse> *DolibarrClient::list_warehouse() const {
|
||||
HTTPClient *client = this->build_url(API_LIST_WAREHOUSE_URL);
|
||||
if (client->GET() == HTTP_CODE_OK) {
|
||||
StaticJsonDocument<API_MAX_JSON_SIZE> doc;
|
||||
DeserializationError error = deserializeJson(doc, client->getString().c_str());
|
||||
if (error) {
|
||||
Serial.println("ERROR: ");
|
||||
Serial.println(error.c_str());
|
||||
delete client;
|
||||
return nullptr;
|
||||
}
|
||||
auto *warehouses = new std::vector<models::Warehouse>();
|
||||
for (auto obj : doc.as<JsonArray>()) {
|
||||
models::Warehouse warehouse = {};
|
||||
warehouse.id = obj["id"];
|
||||
warehouses->push_back(warehouse);
|
||||
}
|
||||
delete client;
|
||||
return warehouses;
|
||||
}
|
||||
delete client;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int DolibarrClient::create_movement(models::CreateProductStock &stock) const {
|
||||
HTTPClient *client = this->build_url("API_CREATE_STOCKS_MOVEMENTS_URL");
|
||||
StaticJsonDocument<API_MAX_JSON_SIZE> doc;
|
||||
std::string result;
|
||||
doc["product_id"] = stock.product_id;
|
||||
doc["warehouse_id"] = stock.warehouse_id;
|
||||
doc["qty"] = stock.qty;
|
||||
serializeJson(doc, result);
|
||||
Serial.println(result.c_str());
|
||||
if (client->POST(result.c_str()) == HTTP_CODE_OK) {
|
||||
delete client;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DolibarrClient::initialize_http_client() {
|
||||
this->httpClient = new HTTPClient();
|
||||
if (this->login() == 0) {
|
||||
auto* product = this->get_product_by_id("1");
|
||||
if (product == nullptr) {
|
||||
Serial.println("Product is nullptr !");
|
||||
return -1;
|
||||
}
|
||||
Serial.println("Product label: ");
|
||||
Serial.println(product->label);
|
||||
auto* warehouses = this->list_warehouse();
|
||||
if (warehouses == nullptr) {
|
||||
delete product;
|
||||
Serial.println("Warehouse is nullptr !");
|
||||
return -1;
|
||||
}
|
||||
Serial.println("Warehouses: ");
|
||||
models::CreateProductStock product_stock = {product->id, warehouses->at(0).id, "1"};
|
||||
this->create_movement(product_stock);
|
||||
for (auto warehouse : *warehouses) {
|
||||
Serial.println(warehouse.id);
|
||||
}
|
||||
delete product;
|
||||
delete warehouses;
|
||||
} else {
|
||||
Serial.println("An Error has occurred while trying to login");
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
#ifndef DOLIBARR_CLIENT_H
|
||||
#define DOLIBARR_CLIENT_H
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <vector>
|
||||
#include "DolibarrModels.h"
|
||||
|
||||
struct WifiConfig {
|
||||
const char* ssid;
|
||||
const char* password;
|
||||
};
|
||||
|
||||
struct DolibarrConfig {
|
||||
const char* url;
|
||||
const char* api_key;
|
||||
};
|
||||
|
||||
class DolibarrClient {
|
||||
public:
|
||||
DolibarrClient(DolibarrConfig dolibarr_config);
|
||||
~DolibarrClient() = default;
|
||||
int login() const;
|
||||
std::vector<models::Warehouse> *list_warehouse() const;
|
||||
std::vector<models::Product> *list_products() const;
|
||||
models::Product *get_product_by_id(const char* id_product) const;
|
||||
int create_movement(models::CreateProductStock &stock) const;
|
||||
private:
|
||||
HTTPClient* httpClient{};
|
||||
struct DolibarrConfig dolibarr;
|
||||
int initialize_http_client();
|
||||
HTTPClient *build_url(const String& url) const;
|
||||
};
|
||||
|
||||
#endif //DOLIBARR_CLIENT_H
|
@ -1,40 +0,0 @@
|
||||
#ifndef T_IOT_901_CONVOYOR_DOLIBARRMODELS_H
|
||||
#define T_IOT_901_CONVOYOR_DOLIBARRMODELS_H
|
||||
|
||||
namespace models {
|
||||
|
||||
struct Product {
|
||||
const char* id;
|
||||
const char* entity;
|
||||
const char* ref;
|
||||
const char* status;
|
||||
const char* date_creation;
|
||||
const char* date_modification;
|
||||
const char* label;
|
||||
const char* description;
|
||||
const char* type;
|
||||
const char* price;
|
||||
const char* stock_reel;
|
||||
const char* seuil_stock_alerte;
|
||||
const char* desiredstock;
|
||||
};
|
||||
|
||||
struct ProductStock {
|
||||
const char* id;
|
||||
const char* product_id;
|
||||
const char* quantity;
|
||||
};
|
||||
|
||||
struct CreateProductStock {
|
||||
const char* product_id;
|
||||
const char* warehouse_id;
|
||||
const char* qty;
|
||||
};
|
||||
|
||||
struct Warehouse {
|
||||
const char* id;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //T_IOT_901_CONVOYOR_DOLIBARRMODELS_H
|
@ -1,22 +0,0 @@
|
||||
#ifndef GRBL_H
|
||||
#define GRBL_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "Module_GRBL_13.2.h"
|
||||
|
||||
class iGRBL{
|
||||
public:
|
||||
virtual void init(int speed, double pas, int accel, String mode = "distance") = 0;
|
||||
virtual void mouveForward(int mm) = 0;
|
||||
};
|
||||
|
||||
class GRBL : public iGRBL{
|
||||
public:
|
||||
GRBL(int grblAddr);
|
||||
void init(int speed, double pas, int accel, String mode = "distance") override;
|
||||
void mouveForward(int mm = 5) override;
|
||||
private:
|
||||
Module_GRBL* grbl;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
#include "../include/GRBL.h"
|
||||
|
||||
GRBL::GRBL(int grblAddr){
|
||||
this->grbl = new Module_GRBL(grblAddr);
|
||||
}
|
||||
|
||||
void GRBL::init(int speed, double pas, int accel, String mode){
|
||||
char s[1024];
|
||||
|
||||
this->grbl->Init(&Wire);
|
||||
this->grbl->setMode(mode);
|
||||
|
||||
sprintf(s,"$0=%f", pas); // step/mm
|
||||
this->grbl->sendGcode(s);
|
||||
Serial.println(s);
|
||||
|
||||
sprintf(s,"$4=%d", speed); // speed
|
||||
this->grbl->sendGcode(s);
|
||||
Serial.println(s);
|
||||
|
||||
sprintf(s,"$8=%d", accel); // acceleration, mm/sec^2
|
||||
this->grbl->sendGcode(s);
|
||||
Serial.println(s);
|
||||
|
||||
sprintf(s,"$3=%d", 500); // puse/µsec
|
||||
this->grbl->sendGcode(s);
|
||||
Serial.println(s);
|
||||
}
|
||||
|
||||
void GRBL::mouveForward(int mm){
|
||||
char s[1024];
|
||||
sprintf(s, "G1 X%d", mm);
|
||||
this->grbl->sendGcode(s);
|
||||
}
|
56
lib/WarehouseGUI/src/GUIScreen.cpp
Normal file
56
lib/WarehouseGUI/src/GUIScreen.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include "GUIScreen.h"
|
||||
|
||||
// Abstract AGuiScreen definition
|
||||
|
||||
gui::AGUIScreen::AGUIScreen() {
|
||||
std::cout << "Hello form AGUIScreen" << "\n";
|
||||
this->widgets = std::vector<AGUIWidget*>();
|
||||
}
|
||||
|
||||
int gui::AGUIScreen::update() {
|
||||
std::sort(widgets.begin(), widgets.end(), [](AGUIWidget* aWidget, AGUIWidget* bWidget) {
|
||||
return aWidget->getLayer() < bWidget->getLayer();
|
||||
});
|
||||
for (auto *widget: widgets) {
|
||||
widget->update();
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int gui::AGUIScreen::addWidget(gui::AGUIWidget *widget) {
|
||||
this->widgets.push_back(widget);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui::AGUIScreen::removeWidget(gui::AGUIWidget *_widget) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui::AGUIScreen::removeWidget(int _index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gui::AGUIScreen::removeWidget(const char *_name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<gui::AGUIWidget*> gui::AGUIScreen::getWidgets() const {
|
||||
return this->widgets;
|
||||
}
|
||||
|
||||
|
||||
// DefaultGuiScreen definition
|
||||
|
||||
gui::DefaultGuiScreen::DefaultGuiScreen() {
|
||||
std::cout << "Hello form DefaultGuiScreen" << "\n";
|
||||
}
|
||||
|
||||
int gui::DefaultGuiScreen::setup() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *gui::DefaultGuiScreen::getName() const {
|
||||
return "DefaultGuiScreen";
|
||||
}
|
35
lib/WarehouseGUI/src/GUIScreen.h
Normal file
35
lib/WarehouseGUI/src/GUIScreen.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef T_IOT_901_CONVOYOR_GUICONTAINER_H
|
||||
#define T_IOT_901_CONVOYOR_GUICONTAINER_H
|
||||
|
||||
#include <vector>
|
||||
#include "GUIWidget.h"
|
||||
|
||||
namespace gui {
|
||||
|
||||
class AGUIScreen {
|
||||
public:
|
||||
AGUIScreen();
|
||||
~AGUIScreen() = default;
|
||||
virtual const char* getName() const = 0;
|
||||
virtual int setup() = 0;
|
||||
int update();
|
||||
int addWidget(AGUIWidget* widget);
|
||||
int removeWidget(AGUIWidget* widget);
|
||||
int removeWidget(int index);
|
||||
int removeWidget(const char* name);
|
||||
std::vector<AGUIWidget*> getWidgets() const;
|
||||
protected:
|
||||
std::vector<AGUIWidget*> widgets;
|
||||
};
|
||||
|
||||
class DefaultGuiScreen : public AGUIScreen {
|
||||
public:
|
||||
DefaultGuiScreen();
|
||||
~DefaultGuiScreen() = default;
|
||||
const char* getName() const override;
|
||||
int setup() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //T_IOT_901_CONVOYOR_GUICONTAINER_H
|
33
lib/WarehouseGUI/src/GUIWidget.cpp
Normal file
33
lib/WarehouseGUI/src/GUIWidget.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "GUIWidget.h"
|
||||
|
||||
gui::AGUIWidget::AGUIWidget(int x, int y, int width, int height, int layer) : layer(layer) {
|
||||
this->position.x = x;
|
||||
this->position.y = y;
|
||||
this->size.width = width;
|
||||
this->size.height = height;
|
||||
}
|
||||
|
||||
int gui::AGUIWidget::getLayer() const {
|
||||
return this->layer;
|
||||
}
|
||||
|
||||
void gui::AGUIWidget::setLayer(int newLayer) {
|
||||
this->layer = newLayer;
|
||||
}
|
||||
|
||||
GuiWidgetPosition gui::AGUIWidget::getPosition() const {
|
||||
return this->position;
|
||||
}
|
||||
|
||||
void gui::AGUIWidget::setPosition(GuiWidgetPosition pos) {
|
||||
this->position = pos;
|
||||
}
|
||||
|
||||
GuiWidgetSize gui::AGUIWidget::getSize() const {
|
||||
return this->size;
|
||||
}
|
||||
|
||||
void gui::AGUIWidget::setSize(GuiWidgetSize newSize) {
|
||||
this->size = newSize;
|
||||
}
|
||||
|
35
lib/WarehouseGUI/src/GUIWidget.h
Normal file
35
lib/WarehouseGUI/src/GUIWidget.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef T_IOT_901_CONVOYOR_GUIWIDGET_H
|
||||
#define T_IOT_901_CONVOYOR_GUIWIDGET_H
|
||||
|
||||
struct GuiWidgetPosition {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct GuiWidgetSize {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
namespace gui {
|
||||
class AGUIWidget {
|
||||
public:
|
||||
AGUIWidget(int x, int y, int width, int height, int layer = 0);
|
||||
~AGUIWidget() = default;
|
||||
virtual const char* getName() const = 0;
|
||||
virtual void setup() = 0;
|
||||
virtual void update() = 0;
|
||||
int getLayer() const;
|
||||
void setLayer(int layer);
|
||||
GuiWidgetPosition getPosition() const;
|
||||
void setPosition(GuiWidgetPosition position);
|
||||
GuiWidgetSize getSize() const;
|
||||
void setSize(GuiWidgetSize size);
|
||||
private:
|
||||
GuiWidgetPosition position{};
|
||||
GuiWidgetSize size{};
|
||||
int layer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //T_IOT_901_CONVOYOR_GUIWIDGET_H
|
82
lib/WarehouseGUI/src/WarehouseGUI.cpp
Normal file
82
lib/WarehouseGUI/src/WarehouseGUI.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "WarehouseGUI.h"
|
||||
#include "M5Stack.h"
|
||||
|
||||
using namespace gui;
|
||||
|
||||
WarehouseGUI::WarehouseGUI() {
|
||||
this->screens = std::vector<AGUIScreen*>();
|
||||
}
|
||||
|
||||
WarehouseGUI::~WarehouseGUI() = default;
|
||||
|
||||
int WarehouseGUI::addScreens(gui::AGUIScreen *screen) {
|
||||
this->screens.push_back(screen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WarehouseGUI::removeScreens(gui::AGUIScreen *screen) {
|
||||
for (int i = 0; i < this->screens.size(); ++i) {
|
||||
if (this->screens[i] == screen) {
|
||||
this->screens.erase(this->screens.begin() + i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int WarehouseGUI::removeScreens(int index) {
|
||||
if (index < 0 || index >= this->screens.size()) {
|
||||
return -1;
|
||||
}
|
||||
this->screens.erase(this->screens.begin() + index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WarehouseGUI::removeScreens(const char *name) {
|
||||
for (int i = 0; i < this->screens.size(); ++i) {
|
||||
if (this->screens[i]->getName() == name) {
|
||||
this->screens.erase(this->screens.begin() + i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int WarehouseGUI::update() {
|
||||
return this->current_screen->update();
|
||||
}
|
||||
|
||||
int WarehouseGUI::setup() {
|
||||
if (this->current_screen == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
return this->current_screen->setup();
|
||||
}
|
||||
|
||||
int WarehouseGUI::changeCurrentScreen(const char *name) {
|
||||
for (auto *screen : this->screens) {
|
||||
if (screen->getName() == name) {
|
||||
this->current_screen = screen;
|
||||
this->current_screen->setup();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int WarehouseGUI::changeCurrentScreen(int index) {
|
||||
if (index < 0 || index >= this->screens.size()) {
|
||||
return -1;
|
||||
}
|
||||
this->current_screen = this->screens[index];
|
||||
this->current_screen->setup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<AGUIScreen *> gui::WarehouseGUI::getAllScreens() {
|
||||
return this->screens;
|
||||
}
|
||||
|
||||
AGUIScreen *gui::WarehouseGUI::getCurrentScreen() {
|
||||
return this->current_screen;
|
||||
}
|
29
lib/WarehouseGUI/src/WarehouseGUI.h
Normal file
29
lib/WarehouseGUI/src/WarehouseGUI.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef T_IOT_901_CONVOYOR_WAREHOUSEGUI_H
|
||||
#define T_IOT_901_CONVOYOR_WAREHOUSEGUI_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include "GUIScreen.h"
|
||||
|
||||
namespace gui {
|
||||
class WarehouseGUI {
|
||||
public:
|
||||
WarehouseGUI();
|
||||
~WarehouseGUI();
|
||||
int addScreens(AGUIScreen* screen);
|
||||
int removeScreens(AGUIScreen* screen);
|
||||
int removeScreens(int index);
|
||||
int removeScreens(const char *name);
|
||||
int changeCurrentScreen(const char* name);
|
||||
int changeCurrentScreen(int index);
|
||||
std::vector<AGUIScreen*> getAllScreens();
|
||||
AGUIScreen* getCurrentScreen();
|
||||
int setup();
|
||||
int update();
|
||||
private:
|
||||
std::vector<AGUIScreen*> screens;
|
||||
AGUIScreen *current_screen{nullptr};
|
||||
};
|
||||
} // namespace gui
|
||||
|
||||
#endif //T_IOT_901_CONVOYOR_WAREHOUSEGUI_H
|
@ -17,14 +17,13 @@ extra_configs =
|
||||
secrets.ini
|
||||
config.ini
|
||||
envs.ini
|
||||
config_api.ini
|
||||
|
||||
; Cache folder
|
||||
build_cache_dir = ./.pio/cache
|
||||
|
||||
[env]
|
||||
; build Envs
|
||||
build_flags = ${config.build_flags} ${secrets.build_flags} ${config_api.build_flags}
|
||||
build_flags = ${config.build_flags} ${secrets.build_flags}
|
||||
|
||||
; Add scripts for more functionnalities
|
||||
; see individual scripts for more informations
|
||||
@ -51,10 +50,6 @@ upload_speed = 921600
|
||||
|
||||
; librairies (make sure to fix versions where possible!)
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson@^6.21.3 ; JSON serializer et deserializer
|
||||
m5stack/M5Stack@^0.4.5 ; M5 Lib
|
||||
m5stack/M5GFX@^0.1.9 ; M5 Lib pour le LCD
|
||||
m5stack/Module_GRBL_13.2@^0.0.3 ; M5 Lib pour Stepper (GRBL)
|
||||
; example:
|
||||
; erropix/ESP32 AnalogWrite@0.2
|
||||
|
||||
|
@ -4,8 +4,3 @@
|
||||
|
||||
[secrets]
|
||||
build_flags =
|
||||
-D WIFI_SSID=\"test\"
|
||||
-D WIFI_PASSWORD=\"abcd1234\"
|
||||
-D DOLIBARR_API_TOKEN=\"monapitokendedolibarr\"
|
||||
-D DOLIBARR_URL=\"http://0.0.0.0/api/index.php\"
|
||||
-D DEBUG=true
|
@ -1,29 +1,10 @@
|
||||
#include "Program.h"
|
||||
#include "Arduino.h"
|
||||
#include "DolibarrClient.h"
|
||||
|
||||
int initialize_wifi(WifiConfig wifi) {
|
||||
WiFiClass::mode(WIFI_STA); //Optional
|
||||
WiFi.setSleep(false);
|
||||
WiFi.begin(wifi.ssid, wifi.password);
|
||||
Serial.print("Connecting ");
|
||||
while(WiFiClass::status() != WL_CONNECTED){
|
||||
delay(WAITING_WIFI_DELAY);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("Connected to the WiFi network");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Program::Program() {
|
||||
// Startup
|
||||
Serial.begin(MONITOR_SPEED);
|
||||
struct WifiConfig wifi_c = {WIFI_SSID, WIFI_PASSWORD};
|
||||
struct DolibarrConfig dolibarr = {DOLIBARR_URL, DOLIBARR_API_TOKEN};
|
||||
initialize_wifi(wifi_c);
|
||||
this->client = new DolibarrClient(dolibarr);
|
||||
}
|
||||
|
||||
void Program::loop() {
|
||||
// Loop
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "Program.h"
|
||||
|
||||
Program* program;
|
||||
|
||||
void setup() {
|
||||
|
@ -1,10 +0,0 @@
|
||||
#include <unity.h>
|
||||
#include "DolibarrClient.h"
|
||||
|
||||
void test_construct_dolibarr_client() {
|
||||
return;
|
||||
}
|
||||
|
||||
void test_destroy_basic_state() {
|
||||
return;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
#include <M5Stack.h>
|
||||
#include <unity.h>
|
||||
#include "test.h"
|
||||
|
||||
void setUp(void) {
|
||||
// set stuff up here
|
||||
}
|
||||
|
||||
void tearDown(void) {
|
||||
// clean stuff up here
|
||||
}
|
||||
|
||||
int runUnityTests(void) {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_construct_dolibarr_client);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
return runUnityTests();
|
||||
}
|
||||
|
||||
// For Arduino framework
|
||||
void setup() {
|
||||
// Wait ~2 seconds before the Unity test runner
|
||||
// establishes connection with a board Serial interface
|
||||
runUnityTests();
|
||||
}
|
||||
|
||||
// For Arduino framework
|
||||
void loop() {}
|
||||
|
||||
// For ESP-IDF framework
|
||||
void app_main() {
|
||||
runUnityTests();
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef T_IOT_901_CONVOYOR_TEST_H
|
||||
#define T_IOT_901_CONVOYOR_TEST_H
|
||||
|
||||
void test_construct_dolibarr_client();
|
||||
|
||||
#endif //T_IOT_901_CONVOYOR_TEST_H
|
Reference in New Issue
Block a user