aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-06-07 08:52:03 +0200
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-06-07 08:52:03 +0200
commit7f399eadf216fbb3290bdf882d78180b6140c364 (patch)
treefdb47b272a8f5432c107b54dfcae0af777573c5b
parentb7608f63e6006a3404260fc3315a30f30d3af762 (diff)
Version de sauvegarde.
-rw-r--r--client/main.cpp10
-rw-r--r--daemon/internals.h127
-rw-r--r--daemon/ip/cfg.c5
-rw-r--r--daemon/ip/cgi.c3
-rw-r--r--daemon/server.c38
-rw-r--r--doc/CGI.rst2
-rw-r--r--doc/INTRO.rst2
-rw-r--r--include/libwesh.hpp (renamed from include/wesh.hpp)371
-rw-r--r--lib/helpers.cpp162
-rw-r--r--lib/interface.cpp263
-rw-r--r--lib/internals.hpp8
-rw-r--r--lib/meter.cpp (renamed from lib/wes/dummy_wes.cpp)56
-rw-r--r--lib/meter/clamp.cpp34
-rw-r--r--lib/meter/meter_base.cpp95
-rw-r--r--lib/meter/pulse_meter.cpp34
-rw-r--r--lib/sensor.cpp (renamed from lib/meter/teleinfo_meter.cpp)52
-rw-r--r--lib/wes.cpp (renamed from lib/wes/wes_base.cpp)194
-rw-r--r--lib/wes/wes.cpp171
-rw-r--r--weshd.x60
19 files changed, 1103 insertions, 584 deletions
diff --git a/client/main.cpp b/client/main.cpp
index d889838..c5a78b2 100644
--- a/client/main.cpp
+++ b/client/main.cpp
@@ -31,17 +31,13 @@
static void test_things(void)
{
- wesh::dummy_wes wes;
-
- wes.gather();
- std::cout << wes << std::endl;
+ wesh::interface iface;
+ wesh::dummy_wes wes = iface.get_dummy_wes();
wes.set_name("hello-world");
std::cout << wes << std::endl;
- wes.remove();
-
- return ;
+ iface.remove(wes);
}
/* ---
diff --git a/daemon/internals.h b/daemon/internals.h
index 0874ec4..184efd1 100644
--- a/daemon/internals.h
+++ b/daemon/internals.h
@@ -367,7 +367,7 @@ typedef enum wesplsmethod {
typedef unsigned long wesmeterflags_t;
-/* Configuration d'un compteur électrique branché par télé-informatique. */
+/* Configuration d'un compteur. */
# define cost_bbr_hcjb cost_tempo_hcjb
# define cost_bbr_hpjb cost_tempo_hpjb
@@ -400,6 +400,7 @@ typedef struct wesmetercfg {
int prorata;
/* Informations dépendant du type de compteur. */
+
union {
struct {
/* Propriétés relatives aux compteurs de types pinces
@@ -451,7 +452,7 @@ typedef struct wesmetercfg {
} wesmetercfg_t;
/* ---
- * Valeurs retournées pour une période.
+ * Valeurs retournées par un compteur pour une période.
* --- */
typedef struct wesmetervalues {
@@ -459,15 +460,12 @@ typedef struct wesmetervalues {
/* Valeurs de base.
* `type`: type du compteur (rappel).
- * `
- * `active`: le compteur a-t-il été actif (branché, envoyant des valeurs)
- * pour cette période ?
+ * `uptime`: uptime de 0 à 1000 pour cette période.
* `count`: nombre d'unités détectées pendant cette période.
* `unit`: unité de mesure pour la valeur précédente. */
wesmetertype_t type;
-
- int active;
+ int uptime;
double count;
wesmeterunit_t unit;
@@ -523,6 +521,95 @@ typedef struct wesmetervalues {
} wesmetervalues_t;
/* ---
+ * Configuration des capteurs (température, humidité, …).
+ * --- */
+
+/* Type de capteur.
+ * `NONE`: aucun, informations génériques uniquement.
+ * `1WIRE`: capteur branché via le bus 1-Wire. */
+
+typedef enum wessensortype {
+ WESSENSORTYPE_NONE,
+ WESSENSORTYPE_1WIRE
+} wessensortype_t;
+
+/* Grandeur mesurée par le capteur.
+ * `TEMPERATURE`: température.
+ * `HUMIDITY`: humidité. */
+
+typedef enum wessensorwhat {
+ WESSENSORWHAT_TEMPERATURE = 1,
+ WESSENSORWHAT_HUMIDITY
+} wessensorwhat_t;
+
+/* Unité utilisée pour les valeurs du capteur.
+ * `CELSIUS`: degrés Celsius (°C).
+ * `KELVIN`: degrés Kelvin (K).
+ * `FARENHEIT`: degrés Farenheit (°F). */
+
+typedef enum wessensorunit {
+ WESSENSORUNIT_CELSIUS = 1,
+ WESSENSORUNIT_KELVIN,
+ WESSENSORUNIT_FARENHEIT
+} wessensorunit_t;
+
+/* Drapeaux d'éléments de la structure à récupérer/définir. */
+
+# define WESSENSOR_NAME 1
+# define WESSENSOR_WHAT 8
+# define WESSENSOR_TYPE 16
+
+# define WESSENSOR_1WIREID 128
+
+typedef unsigned long wessensorflags_t;
+
+/* Configuration d'un capteur. */
+
+typedef struct wessensorcfg {
+ wesfreemem_t *free;
+
+ /* Propriétés de base.
+ * `name`: nom du capteur.
+ * `type`: type du capteur.
+ * `what`: grandeur mesurée. */
+
+ char *name;
+ wessensortype_t type;
+ wessensorwhat_t what;
+
+ union {
+ struct {
+ /* Propriétés relatives aux capteurs branchés via le bus 1-Wire.
+ * `id`: id 1-Wire du capteur. */
+
+ unsigned char id[8];
+ } onewire;
+ } more;
+} wessensorcfg_t;
+
+/* ---
+ * Valeurs retournées par un capteur pour une période.
+ * --- */
+
+typedef struct wessensorvalues {
+ wesfreemem_t *free;
+
+ /* Valeurs de base.
+ * `type`: type du compteur (rappel).
+ *
+ * `uptime`: uptime de 0 à 1000 pour cette période.
+ * `min`: minimum pour cette période.
+ * `avg`: moyenne pour cette période.
+ * `max`: maximum pour cette période.
+ * `unit`: unité de mesure pour les valeurs précédentes. */
+
+ wessensortype_t type;
+ int uptime;
+ double count;
+ wessensorunit_t unit;
+} wessensorvalues_t;
+
+/* ---
* Définition des interfaces.
* --- */
@@ -557,6 +644,17 @@ typedef int wesif_getmeternext_t (void *, int *, wesmetertype_t *type);
typedef int wesif_skipmeters_t (void *, int);
typedef void wesif_delmeteriter_t (void *);
+typedef int wesif_getsensor_t (wes_t *, int, wessensortype_t, wessensorflags_t,
+ wessensorcfg_t const *);
+typedef int wesif_setsensor_t (wes_t *, int, wessensorflags_t,
+ wessensorcfg_t const *);
+typedef int wesif_getsensorvalues_t (wes_t *wes, wessensorvalues_t **);
+
+typedef int wesif_getsensoriter_t (wes_t *wes, wessensortype_t type, void **);
+typedef int wesif_getsensornext_t (void *, int *, wessensortype_t *type);
+typedef int wesif_skipsensors_t (void *, int);
+typedef void wesif_delsensoriter_t (void *);
+
typedef struct wesif {
westype_t type;
wesif_free_t *free;
@@ -566,18 +664,27 @@ typedef struct wesif {
wesif_getcfg_t *getcfg;
wesif_setcfg_t *setcfg;
- /* Interact with the meters. */
+ /* Interact with and list the meters. */
wesif_getmeter_t *getmeter;
wesif_setmeter_t *setmeter;
wesif_getmetervalues_t *getmetervalues;
- /* List meters. */
-
wesif_getmeteriter_t *getmeteriter;
wesif_getmeternext_t *getmeternext;
wesif_skipmeters_t *skipmeters;
wesif_delmeteriter_t *delmeteriter;
+
+ /* Interact with and list the sensors. */
+
+ wesif_getsensor_t *getsensor;
+ wesif_setsensor_t *setsensor;
+ wesif_getsensorvalues_t *getsensorvalues;
+
+ wesif_getsensoriter_t *getsensoriter;
+ wesif_getsensornext_t *getsensornext;
+ wesif_skipsensors_t *skipsensors;
+ wesif_delsensoriter_t *delsensoriter;
} wesif_t;
/* ---
diff --git a/daemon/ip/cfg.c b/daemon/ip/cfg.c
index 231630a..7ea958b 100644
--- a/daemon/ip/cfg.c
+++ b/daemon/ip/cfg.c
@@ -28,6 +28,11 @@
* knowledge of the CeCILL license and that you accept its terms.
* ************************************************************************* */
#include "internals.h"
+
+/* FIXME: tout ça ne gère pas la partie "données" de certains fichiers
+ * de configuration gérées par le WES, dont notamment `S1WIRE.CFG`.
+ * Il s'agit de les inclure aussi un de ces jours. */
+
#define SECSIZE 10
#define KEYSIZE 50
#define VALSIZE 100
diff --git a/daemon/ip/cgi.c b/daemon/ip/cgi.c
index c998138..3103630 100644
--- a/daemon/ip/cgi.c
+++ b/daemon/ip/cgi.c
@@ -42,7 +42,7 @@
* --- */
#define UST_REQ 0 /* 'c <CMD ><FORMAT> */
-#define UST_END 1 /* '.<CRLF>' de fin */
+#define UST_END 1 /* '. <CRLF>' de fin */
#define UST_MAX 2
#define USR_CMD 0 /* 'c ' au début de la requête */
@@ -51,6 +51,7 @@
#define USR_SEP 3 /* CRLF, 't ' et séparateur de requête, CRLF */
#define USR_MAX 4
+#define USE_CMD 0 /* '. ' au début de la requête */
#define USE_MAX 1
struct ucookie {
diff --git a/daemon/server.c b/daemon/server.c
index f551265..169e8ed 100644
--- a/daemon/server.c
+++ b/daemon/server.c
@@ -91,11 +91,11 @@ void *weshd_null_1_svc(void *argp, struct svc_req *req)
(void)argp;
(void)req;
- return ((void*)&val);
+ return ((void *)&val);
}
/* ---
- * Gestion des ressources existentes.
+ * Gestion des ressources WES existantes.
* --- */
/* `gather_1_svc()`: Création de ressource, ou récupération de ressource
@@ -231,10 +231,6 @@ wespret_t *unregister_1_svc(wespid_t *id, struct svc_req *req)
return (&ret);
}
-/* ---
- * Récupération de la configuration du serveur WES.
- * --- */
-
/* `get_1_svc()`: Récupération de la configuration d'un serveur WES. */
wespret_with_wes_t *get_1_svc(wespid_with_wes_flags_t *args,
@@ -830,6 +826,36 @@ wespret_with_meter_list_t *query_meters_1_svc(wespid_with_meter_query_t *args,
}
/* ---
+ * Gestion des capteurs.
+ * --- */
+
+/* `get_sensor_1_svc()`: récupération de la configuration d'un capteur. */
+
+wespret_with_sensor_t *get_sensor_1_svc(wespid_with_sensor_id_t *args,
+ struct svc_req *req)
+{
+ static wespret_with_sensor_t resp;
+
+ /* TODO */
+
+ resp.ret = WESPRET_IMP;
+ return (&resp);
+}
+
+/* `set_sensor_1_svc()`: définition de la configuration d'un capteur. */
+
+wespret_t *set_sensor_1_svc(wespid_with_sensor_t *args,
+ struct svc_req *req)
+{
+ static wespret_t ret;
+
+ /* TODO */
+
+ resp.ret = WESPRET_IMP;
+ return (&resp);
+}
+
+/* ---
* Fonction de lancement du serveur, avec gestions de signaux.
* --- */
diff --git a/doc/CGI.rst b/doc/CGI.rst
index dfcb558..2e57a2d 100644
--- a/doc/CGI.rst
+++ b/doc/CGI.rst
@@ -29,7 +29,7 @@ précédemment. Les types d'instruction connus sont :
``t `` (U+0074 puis U+0020)
Texte.
- La ligne sera envoyée sans modification au client HTTP.
+ La ligne sera envoyée sans modification au client HTTP, suivie d'un CRLF.
``i `` (U+0069 puis U+0020)
Inclusion.
diff --git a/doc/INTRO.rst b/doc/INTRO.rst
index 40dcc98..2191e80 100644
--- a/doc/INTRO.rst
+++ b/doc/INTRO.rst
@@ -35,6 +35,8 @@ gamme possible d'éléments :
- exécution de scripts CGI (upload et suppression via FTP, exécution via
HTTP) pour récupérer la valeur de certaines variables (documenté
dans `CGI.rst <CGI.rst>`_) ;
+- exécution de commandes via le protocole machine à machine (documenté
+ dans `M2M.rst <M2M.rst>`_) ;
- récupération de fichiers XML avec l'extension ``CGX`` (documenté dans
`CGX.rst <CGX.rst>`_) ;
- récupération de fichiers CSV contenant l'historique des données dans
diff --git a/include/wesh.hpp b/include/libwesh.hpp
index 9c0ae24..c59cd01 100644
--- a/include/wesh.hpp
+++ b/include/libwesh.hpp
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * wesh.hpp -- bibliothèque d'interaction avec le WES Handling Daemon.
+ * libwesh.hpp -- bibliothèque d'interaction avec le WES Handling Daemon.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -27,11 +27,13 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
* ************************************************************************* */
-#ifndef WESH_HPP
-# define WESH_HPP 20180311
+#ifndef LIBWESH_HPP
+# define LIBWESH_HPP 20180311
# include <stdexcept>
# include <ostream>
# include <string>
+# include <list>
+# include <chrono>
# include <ctime>
# define BEGIN_NAMESPACE_WESH namespace wesh {
# define END_NAMESPACE_WESH }
@@ -40,6 +42,16 @@ BEGIN_NAMESPACE_WESH
class meter_base;
class wes_base;
+class interface;
+
+/* L'interface SunRPC n'est pas inclue publiquement, donc le type CLIENT
+ * n'est pas disponible en dehors des fichiers d'en-tête internes.
+ * Seulement, on en a besoin pour définir les classes, donc on dira que
+ * c'est un pointeur opaque à l'utilisateur. */
+
+# ifndef WESH_CLIENT_TYPE
+# define WESH_CLIENT_TYPE void
+# endif
/* ---
* Définition des exceptions utilisables par la classe WES.
@@ -53,19 +65,27 @@ class wes_base;
* - `already_exists_exception`: un objet correspondant aux données
* d'entrées existe déjà du côté du démon. */
-#if __cplusplus >= 201103L
-# define WESH_NOEXCEPT noexcept
-#else
-# define WESH_NOEXCEPT throw()
-#endif
+# if __cplusplus >= 201103L
+# define WESH_NOEXCEPT noexcept
+# else
+# define WESH_NOEXCEPT throw()
+# endif
-#define WESH_EXC(NAME, MSG) \
+# define WESH_WHAT_IS_REAL \
+ virtual char const *what() const WESH_NOEXCEPT = 0;
+# define WESH_WHAT(MSG) \
+ virtual char const *what() const WESH_NOEXCEPT { \
+ return (MSG); \
+ }
+
+# define WESH_EXC(NAME, MSG) \
class NAME: public std::exception { \
- virtual const char *what() const WESH_NOEXCEPT { \
- return MSG; \
- } \
+ WESH_WHAT(MSG) \
};
+WESH_EXC(invalid_argument,
+ "L'un des arguments fournis était invalide.")
+
WESH_EXC(connexion_exception,
"La connexion au démon a échoué.")
WESH_EXC(daemon_exception,
@@ -73,14 +93,12 @@ WESH_EXC(daemon_exception,
WESH_EXC(not_implemented_exception,
"L'appel correspondant n'est pas implémenté.")
-WESH_EXC(not_loaded_exception,
- "Cet objet n'a pas été chargé.")
-WESH_EXC(already_created_exception,
- "Cet objet a déjà été créé !")
+WESH_EXC(no_parent_exception,
+ "L'objet requiert un parent.")
-WESH_EXC(no_exists_exception,
+WESH_EXC(no_wes_exception,
"Il n'y a pas de serveur WES avec cet identifiant.")
-WESH_EXC(unavailable_exception,
+WESH_EXC(unavailable_wes_exception,
"Le serveur WES est injoignable.")
WESH_EXC(no_meter_exception,
@@ -88,10 +106,13 @@ WESH_EXC(no_meter_exception,
WESH_EXC(invalid_meter_type_exception,
"Le compteur distant n'est pas du bon type.")
-#undef WESH_EXC
+WESH_EXC(no_sensor_exception,
+ "Il n'y a pas de capteur avec cet identifiant.")
+
+# undef WESH_EXC
/* ---
- * Énumérations utiles pour ce qui concerne les compteurs.
+ * Définitions des compteurs.
* --- */
/* Mode de consommation/production d'un compteur.
@@ -130,6 +151,7 @@ enum meter_unit {
};
/* Type de tarif pour le protocole télé-informatique d'ERDF.
+ * `all`: tous forfaits.
* `base`: forfait Base (toutes heures), le prix du kWh ne varie pas en
* fonction de la période de consommation ;
* `hchp`: forfait Heures Pleines Heures Creuses, le prix du kWh varie
@@ -140,6 +162,7 @@ enum meter_unit {
* fonction de la journée. */
enum teleinfo_meter_subscription_type {
+ ticmst_all,
ticmst_base,
ticmst_hchp,
ticmst_ejp,
@@ -150,7 +173,7 @@ enum teleinfo_meter_subscription_type {
* La signification des valeurs dans cette énumération dépend du forfait
* souscrit pour ce compteur.
*
- * Forfait BASE :
+ * Tous forfaits ou forfait BASE :
* `th`: toutes heures.
*
* Forfait HCHP :
@@ -171,17 +194,17 @@ enum teleinfo_meter_subscription_type {
enum teleinfo_meter_subscription_period {
ticmsp_th = 0,
- ticmsp_hn = 0,
- ticmsp_hc = 1,
- ticmsp_hp = 2,
- ticmsp_pm = 3,
-
- ticmsp_hcjb = 1,
- ticmsp_hpjb = 2,
- ticmsp_hcjw = 5,
- ticmsp_hpjw = 6,
- ticmsp_hcjr = 9,
- ticmsp_hpjr = 10
+ ticmsp_hn = 1,
+ ticmsp_hc = 2,
+ ticmsp_hp = 3,
+ ticmsp_pm = 4,
+
+ ticmsp_hcjb = 2,
+ ticmsp_hpjb = 3,
+ ticmsp_hcjw = 10,
+ ticmsp_hpjw = 11,
+ ticmsp_hcjr = 18,
+ ticmsp_hpjr = 19
};
/* Structure concernant le forfait actuel d'un compteur électrique
@@ -201,32 +224,33 @@ enum pulse_meter_method {
pmm_elec
};
-# ifndef WESH_CLIENT_TYPE
-# define WESH_CLIENT_TYPE void
-# endif
-
-/* ---
- * Classes concernant un compteur.
- * --- */
+/* Classe de base pour un compteur.
+ * Les autres classes représentant des compteurs sont toutes héritées de
+ * celle-ci. */
class meter_base {
-private:
+protected:
wes_base *parent;
int id;
public:
meter_base(void);
meter_base(wes_base *parent, int num);
+ meter_base(meter_base const &original);
+ virtual ~meter_base(void);
- /* Récupération des données concernant le compteur. */
+ WESH_WHAT_IS_REAL
- void gather(wes_base *parent, int num);
- void gather(void);
+ void orphan(void);
/* Récupération de données depuis le démon. */
+ int get_id(void);
+ WESH_CLIENT_TYPE *get_clnt(void);
+
std::string get_name(void);
void set_name(std::string name);
+ void set_name(char const *name);
bool enabled(void);
void enable(void);
@@ -240,12 +264,21 @@ public:
double get_fixed_costs(void);
void set_fixed_costs(double cost);
+
+ /* Récupération de données générique. */
+
+ double get_count(int year, int month, int month_day);
};
+/* Compteur particulier : pince ampèremétrique. */
+
class clamp: public meter_base {
public:
clamp(void) : meter_base() {}
- clamp(wes_base *parent, int num) : meter_base(parent, num) {}
+ clamp(wes_base *parent, int id) : meter_base(parent, id) {}
+ clamp(clamp const &original) : meter_base(original) {}
+
+ WESH_WHAT("clamp")
int get_voltage(void);
void set_voltage(int voltage);
@@ -254,10 +287,15 @@ public:
void set_unit_cost(double cost);
};
+/* Compteur d'impulsions. */
+
class pulse_meter: public meter_base {
public:
pulse_meter(void) : meter_base() {}
- pulse_meter(wes_base *parent, int num) : meter_base(parent, num) {}
+ pulse_meter(wes_base *parent, int id) : meter_base(parent, id) {}
+ pulse_meter(pulse_meter const &original) : meter_base(original) {}
+
+ WESH_WHAT("pulse")
pulse_meter_method get_method(void);
void set_method(pulse_meter_method method);
@@ -267,12 +305,21 @@ public:
double get_unit_cost(void);
void set_unit_cost(double cost);
+
+ /* Récupération de données. */
+
+ double get_units(int year, int month, int mday);
};
+/* Compteur relié via téléinfo. */
+
class teleinfo_meter: public meter_base {
public:
teleinfo_meter(void) : meter_base() {}
- teleinfo_meter(wes_base *parent, int num) : meter_base(parent, num) {}
+ teleinfo_meter(wes_base *parent, int id) : meter_base(parent, id) {}
+ teleinfo_meter(teleinfo_meter const &original) : meter_base(original) {}
+
+ WESH_WHAT("teleinfo")
double get_unit_cost(teleinfo_meter_subscription sub);
void set_unit_cost(teleinfo_meter_subscription sub, double cost);
@@ -286,96 +333,232 @@ public:
std::pair<std::string, std::string> get_bdpv_ids(void);
void set_bdpv_ids(std::string username, std::string password);
+
+ /* Récupération de données. */
+
+ double get_kwh(int year, int month, int month_day,
+ teleinfo_meter_subscription_type sub_type,
+ teleinfo_meter_subscription_period sub_period);
};
/* ---
- * Définition des classes WES.
+ * Définition des ressources de type capteur.
+ * --- */
+
+/* Classe de base pour un capteur. */
+
+class sensor_base {
+protected:
+ wes_base *parent;
+ int id;
+
+public:
+ sensor_base(void);
+ sensor_base(wes_base *parent, int id);
+ sensor_base(sensor_base const &original);
+ virtual ~sensor_base(void);
+
+ WESH_WHAT_IS_REAL
+
+ void orphan(void);
+
+ /* Récupération de données depuis le démon. */
+
+ int get_id(void);
+ WESH_CLIENT_TYPE *get_clnt(void);
+
+ std::string get_name(void);
+ void set_name(std::string name);
+ void set_name(char const *name);
+
+ double get_min(int year, int month, int month_day);
+ double get_avg(int year, int month, int month_day);
+ double get_max(int year, int month, int month_day);
+};
+
+/* Classe représentant un capteur relié par le bus 1-Wire. */
+
+typedef unsigned char onewire_id_t[8];
+
+class onewire_sensor: public sensor_base {
+public:
+ onewire_sensor(void) : sensor_base() {}
+ onewire_sensor(wes_base *parent, int id) : sensor_base(parent, id) {}
+ onewire_sensor(onewire_sensor const &orig) : sensor_base(orig) {}
+
+ /* Récupération de données depuis le démon. */
+
+ onewire_id_t get_onewire_id(void);
+};
+
+/* ---
+ * Définition des ressources de type serveur WES.
* --- */
/* Classe de base, pour toutes les interfaces derrière. */
class wes_base {
protected:
+ interface *parent;
int id;
- WESH_CLIENT_TYPE *client;
+
+ std::set<meter_base *> meter_list;
+ std::set<sensor_base *> sensor_list;
public:
wes_base(void);
+ wes_base(interface *parent, int id);
+ wes_base(wes_base const &original);
virtual ~wes_base(void);
- /* Gestion de la ressource. */
+ WESH_WHAT_IS_REAL
- void use(int id);
- void remove(void);
+ /* Manage the resource list. */
- /* Gestion du nom. */
+ void add_meter_ref(meter_base *resource);
+ void del_meter_ref(meter_base *resource);
- std::string get_name(void);
+ void add_sensor_ref(sensor_base *resource);
+ void del_sensor_ref(sensor_base *resource);
- void set_name(std::string name);
- void set_name(const char *name);
+ void orphan(void);
- /* Gestion de l'heure. */
+ /* Getters et setters pour les propriétés communes. */
- struct tm get_date(void);
+ int get_id(void);
- /* Récupération de compteurs. */
+ std::string get_name(void);
+ void set_name(std::string name);
+ void set_name(char const *name);
+
+ int get_year(void);
+ int get_month(void);
+ int get_month_day(void);
+ int get_hour(void);
+ int get_min(void);
+ int get_sec(void);
+ int get_dow(void);
+ bool get_dst(void);
+
+ void set_year(int val);
+ void set_month(int val);
+ void set_month_day(int val);
+ void set_hour(int val);
+ void set_min(int val);
+ void set_sec(int val);
+ void set_dow(int val);
+ void set_dst(bool val);
+
+ /* Récupération de ressources.
+ * Le compteur peut être récupéré par son ID absolu ou le numéro des
+ * compteurs de ce type. */
clamp get_clamp(int id);
+ clamp get_clamp_no(int no);
pulse_meter get_pulse_meter(int id);
+ pulse_meter get_pulse_meter_no(int no);
teleinfo_meter get_teleinfo_meter(int id);
+ teleinfo_meter get_teleinfo_meter_no(int no);
- /* Destiné aux classes ayant ce serveur comme référent. */
+ onewire_sensor get_onewire_sensor(int id);
+ onewire_sensor get_onewire_sensor_no(int no);
- WESH_CLIENT_TYPE *get_clnt(void);
- int get_id(void);
+ /* Destiné aux classes ayant cette interface comme référent. */
- virtual const char *iface() {
- return "(unknown)";
- }
+ WESH_CLIENT_TYPE *get_clnt(void);
};
/* Classe fille pour le serveur WES de base connecté via IP. */
class wes: public wes_base {
public:
- /* Récupération du serveur WES. */
-
- void gather(const unsigned char ip[4]);
- void gather(const std::string ip);
- void gather(const char *ip);
- void gather(const unsigned char ip[4],
- std::string username, std::string password);
- void gather(const std::string ip,
- std::string username, std::string password);
- void gather(const char *ip,
- std::string username, std::string password);
- void gather(const unsigned char ip[4],
- std::string http_username, std::string http_password,
- std::string ftp_username, std::string ftp_password);
- void gather(const std::string ip,
- std::string http_username, std::string http_password,
- std::string ftp_username, std::string ftp_password);
- void gather(const char *ip,
- std::string http_username, std::string http_password,
- std::string ftp_username, std::string ftp_password);
-
- virtual const char *iface() {
- return "ip";
- }
+ wes(void) : wes_base() {}
+ wes(interface *parent, int id) : wes_base(parent, id) {}
+ wes(wes const &original) : wes_base(original) {}
+
+ WESH_WHAT("ip")
};
/* Classe fille pour le serveur WES factice. */
class dummy_wes: public wes_base {
public:
- /* Récupération du serveur WES. */
+ dummy_wes(void) : wes_base() {}
+ dummy_wes(interface *parent, int id) : wes_base(parent, id) {}
+ dummy_wes(dummy_wes const &original) : wes_base(original) {}
- void gather(void);
+ WESH_WHAT("dummy")
+};
- virtual const char *iface() {
- return "dummy";
- }
+/* ---
+ * Définition de l'interface.
+ * --- */
+
+class interface {
+private:
+ WESH_CLIENT_TYPE *client;
+ std::set<wes_base *> wes_list;
+
+public:
+ interface(void);
+ ~interface(void);
+
+ /* Manage the WES list. */
+
+ void add_wes_ref(wes_base *resource);
+ void del_wes_ref(wes_base *resource);
+
+ /* Récupérer un WES connecté par IP. */
+
+ wes get_wes(unsigned char const ip[4]);
+ wes get_wes(char const *ip);
+ wes get_wes(std::string const ip);
+
+ wes get_wes(unsigned char const ip[4],
+ char const *username, char const *password);
+ wes get_wes(unsigned char const ip[4],
+ std::string const username, std::string const password);
+ wes get_wes(char const *ip,
+ char const *username, char const *password);
+ wes get_wes(char const *ip,
+ std::string const username, std::string const password);
+ wes get_wes(std::string const ip,
+ char const *username, char const *password);
+ wes get_wes(std::string const ip,
+ std::string const username, std::string const password);
+
+ wes get_wes(unsigned char const ip[4],
+ char const *http_username, char const *http_password,
+ char const *ftp_username, char const *ftp_password);
+ wes get_wes(unsigned char const ip[4],
+ std::string const http_username, std::string const http_password,
+ std::string const ftp_username, std::string const ftp_password);
+ wes get_wes(char const *ip,
+ char const *http_username, char const *http_password,
+ char const *ftp_username, char const *ftp_password);
+ wes get_wes(char const *ip,
+ std::string const http_username, std::string const http_password,
+ std::string const ftp_username, std::string const ftp_password);
+ wes get_wes(std::string const ip,
+ char const *http_username, char const *http_password,
+ char const *ftp_username, char const *ftp_password);
+ wes get_wes(std::string const ip,
+ std::string const http_username, std::string const http_password,
+ std::string const ftp_username, std::string const ftp_password);
+
+ /* Récupérer un WES factice. */
+
+ dummy_wes get_dummy_wes(void);
+
+ /* Supprimer un WES. */
+
+ void remove(int id);
+ void remove(wes_base const &resource);
+ void remove(wes_base const *resource);
+
+ /* Destiné aux classes ayant cette interface comme référent. */
+
+ WESH_CLIENT_TYPE *get_clnt(void);
};
END_NAMESPACE_WESH
@@ -401,4 +584,4 @@ extern std::ostream& operator<<(std::ostream& os,
extern std::ostream& operator<<(std::ostream& os,
wesh::pulse_meter_method pl);
-#endif /* WESH_HPP */
+#endif /* LIBWESH_HPP */
diff --git a/lib/helpers.cpp b/lib/helpers.cpp
index a47a105..62847fc 100644
--- a/lib/helpers.cpp
+++ b/lib/helpers.cpp
@@ -32,6 +32,133 @@
using namespace wesh;
/* ---
+ * Utilitaires par rapport aux adresses IP.
+ * --- */
+
+/* `decode_ipv4()`: décodage d'une IPv4 à partir d'une chaîne de caractères,
+ * avec des extensions cool comme :
+ *
+ * - si on ne précise pas tous les champs, ça extrapole, e.g.
+ * 192.168.4 -> 192.168.0.4.
+ * - on peut utiliser `0` et `0o` pour préciser un numéro en octal,
+ * e.g. 192.0250.4 -> 192.168.0.4
+ * - on peut utiliser `0x` pour préciser un numéro en hexadécimal,
+ * e.g. 0xc0.0o250.4 -> 192.168.0.4. */
+
+int wesh::decode_ipv4(char const *s, unsigned char ip[4])
+{
+ /* mode: 10 pour décimal, 8 pour octal, 16 pour hexadécimal
+ * oct: si 'o' a déjà été lu dans le préfixe.
+ * started: si le décodage des données d'un nombre a commencé. */
+
+ int mode = 10;
+ int oct = 0;
+ int started = 0;
+ int i;
+
+ ip[0] = 0;
+ ip[1] = 0;
+ ip[2] = 0;
+ ip[3] = 0;
+
+ for (i = 0; *s; s++) switch (*s) {
+ case '0':
+ if (started)
+ ip[i] = static_cast<unsigned char>(ip[i] * mode);
+ else if (mode == 10)
+ mode = 8;
+ else
+ started = 1;
+ break;
+
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7':
+ ip[i] = static_cast<unsigned char>(ip[i] * mode + (*s - '0'));
+ started = 1;
+ break;
+
+ case '8': case '9':
+ if (mode == 8)
+ return (1);
+ ip[i] = static_cast<unsigned char>(ip[i] * mode + (*s - '0'));
+ started = 1;
+ break;
+
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ if (mode != 16)
+ return (1);
+ ip[i] = static_cast<unsigned char>(ip[i] * mode + (*s - 'A' + 10));
+ started = 1;
+ break;
+
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ if (mode != 16)
+ return (1);
+ ip[i] = static_cast<unsigned char>(ip[i] * mode + (*s - 'a' + 10));
+ started = 1;
+ break;
+
+ case 'o':
+ if (mode != 8 || started || oct)
+ return (1);
+ oct = 1;
+ break;
+
+ case 'x':
+ if (started || mode != 8)
+ return (1);
+ mode = 16;
+ break;
+
+ case '.':
+ if (++i >= 4)
+ return (1);
+ mode = 10;
+ started = 0;
+ oct = 0;
+ break;
+
+ default:
+ return (1);
+ }
+
+ if (i < 3) {
+ ip[3] = ip[i];
+ ip[i] = 0;
+ }
+
+ return (0);
+}
+
+/* ---
+ * Utilitaires concernant les exceptions.
+ * --- */
+
+/* `throw_exception_using_ret()`: utilisation du code de retour pour savoir
+ * quelle exception soulever. */
+
+void wesh::throw_exception_using_ret(wespret_t ret)
+{
+ switch (ret) {
+ case WESPRET_OK:
+ break;
+ case WESPRET_IMP:
+ throw not_implemented_exception();
+ case WESPRET_NOW:
+ throw no_exists_exception();
+ case WESPRET_CON:
+ throw unavailable_exception();
+ default:
+ throw daemon_exception();
+ }
+
+ throw std::exception();
+}
+
+/* ---
* Utilitaires d'affichage (mise sur un flux de sortie).
* --- */
@@ -39,7 +166,7 @@ std::ostream& operator<<(std::ostream& os, wes_base& wes)
{
os << "<wes"
<< " name=\"" << wes.get_name() << "\""
- << " iface=\"" << wes.iface() << "\""
+ << " iface=\"" << wes.what() << "\""
<< ">";
return (os);
@@ -112,6 +239,9 @@ std::ostream& operator<<(std::ostream& os,
teleinfo_meter_subscription_type st)
{
switch (st) {
+ case ticmst_all:
+ os << "TOUS";
+ break;
case ticmst_base:
os << "BASE";
break;
@@ -136,8 +266,11 @@ std::ostream& operator<<(std::ostream& os,
teleinfo_meter_subscription_period pd)
{
switch (pd) {
+ case ticmsp_th:
+ os << "TH";
+ break;
case ticmsp_hn:
- os << "HN/TH";
+ os << "HN";
break;
case ticmsp_hc:
os << "HC(JB)";
@@ -244,28 +377,3 @@ std::ostream& operator<<(std::ostream& os, pulse_meter_method pl)
return (os);
}
-
-/* ---
- * Utilitaires concernant les exceptions.
- * --- */
-
-/* `throw_exception_using_ret()`: utilisation du code de retour pour savoir
- * quelle exception soulever. */
-
-void throw_exception_using_ret(wespret_t ret)
-{
- switch (ret) {
- case WESPRET_OK:
- break;
- case WESPRET_IMP:
- throw not_implemented_exception();
- case WESPRET_NOW:
- throw no_exists_exception();
- case WESPRET_CON:
- throw unavailable_exception();
- default:
- throw daemon_exception();
- }
-
- throw std::exception();
-}
diff --git a/lib/interface.cpp b/lib/interface.cpp
new file mode 100644
index 0000000..2cb670c
--- /dev/null
+++ b/lib/interface.cpp
@@ -0,0 +1,263 @@
+/* ****************************************************************************
+ * interface.cpp -- interface principale de la libwesh.
+ * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
+ *
+ * This project is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the
+ * CeCILL license as circulated by CEA, CNRS and INRIA at the
+ * following URL: "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the project's author, the holder of the
+ * economic rights, and the successive licensors have only limited liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also therefore
+ * means that it is reserved for developers and experienced professionals
+ * having in-depth computer knowledge. Users are therefore encouraged to load
+ * and test the software's suitability as regards their requirements in
+ * conditions enabling the security of their systems and/or data to be
+ * ensured and, more generally, to use and operate it in the same conditions
+ * as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ * ************************************************************************* */
+#include "internals.hpp"
+
+using namespace wesh;
+
+/* ---
+ * Constructeur, destructeur et méthodes de base.
+ * --- */
+
+interface::interface(void)
+{
+ client = nullptr;
+}
+
+interface::~interface(void)
+{
+ if (client)
+ clnt_destroy(client);
+ for (wes_base *w : wes_list)
+ w->orphan();
+}
+
+CLIENT *interface::get_clnt(void)
+{
+ if (client)
+ return (client);
+
+ client = clnt_create("localhost", WESHD_PROG, WESHD_VERS1, "tcp");
+ if (!client)
+ throw connexion_exception();
+
+ return (client);
+}
+
+void add_wes_ref(wes_base *resource)
+{
+ wes_list.insert(resource);
+}
+
+void del_wes_ref(wes_base *resource)
+{
+ auto it = wes_list.find(resource);
+ if (resource != std::set::end)
+ wes_list.erase(resource);
+}
+
+/* ---
+ * Récupération d'un WES connecté par IP.
+ * --- */
+
+wes interface::get_wes(unsigned char const ip[4],
+ char const *http_username, char const *http_password,
+ char const *ftp_username, char const *ftp_password)
+{
+ wespoptions_t args;
+ wespret_with_id_t *resp;
+ wespret_t ret;
+
+ args.type = WESPTYPE_IP;
+ args.wespoptions_t_u.ip.addr.type = WESPIPTYPE_4;
+ args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[0] = ip[0];
+ args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[1] = ip[1];
+ args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[2] = ip[2];
+ args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[3] = ip[3];
+ args.wespoptions_t_u.ip.http_username = const_cast<char *>(http_username);
+ args.wespoptions_t_u.ip.http_password = const_cast<char *>(http_password);
+ args.wespoptions_t_u.ip.ftp_username = const_cast<char *>(ftp_username);
+ args.wespoptions_t_u.ip.ftp_password = const_cast<char *>(ftp_password);
+
+ resp = gather_1(&args, get_clnt());
+ if (!resp)
+ throw connexion_exception();
+
+ ret = resp->ret;
+ if (ret != WESPRET_OK)
+ throw_exception_using_ret(ret);
+
+ return (wes(this, static_cast<int>(resp->id)));
+}
+
+wes interface::get_wes(unsigned char const ip[4],
+ std::string const http_username, std::string const http_password,
+ std::string const ftp_username, std::string const ftp_password)
+{
+ return (get_wes(ip, http_username.c_str(), http_password.c_str(),
+ ftp_username.c_str(), ftp_password.c_str()));
+}
+
+wes interface::get_wes(char const *ip_string,
+ char const *http_username, char const *http_password,
+ char const *ftp_username, char const *ftp_password)
+{
+ unsigned char ip[4];
+
+ if (decode_ipv4(ip_string, ip))
+ throw invalid_argument();
+ return (get_wes(ip, http_username, http_password,
+ ftp_username, ftp_password));
+}
+
+wes interface::get_wes(char const *ip_string,
+ std::string const http_username, std::string const http_password,
+ std::string const ftp_username, std::string const ftp_password)
+{
+ return (get_wes(ip_string, http_username.c_str(), http_password.c_str(),
+ ftp_username.c_str(), ftp_password.c_str()));
+}
+
+wes interface::get_wes(std::string const ip,
+ char const *http_username, char const *http_password,
+ char const *ftp_username, char const *ftp_password)
+{
+ return (get_wes(ip.c_str(), http_username, http_password,
+ ftp_username, ftp_password));
+}
+
+wes interface::get_wes(std::string const ip,
+ std::string const http_username, std::string const http_password,
+ std::string const ftp_username, std::string const ftp_password)
+{
+ return (get_wes(ip, http_username.c_str(), http_password.c_str(),
+ ftp_username.c_str(), ftp_password.c_str()));
+}
+
+wes interface::get_wes(unsigned char const ip[4],
+ char const *username, char const *password)
+{
+ return (get_wes(ip, username, password, username, password));
+}
+
+wes interface::get_wes(unsigned char const ip[4],
+ std::string const username, std::string const password)
+{
+ return (get_wes(ip, username.c_str(), password.c_str()));
+}
+
+wes interface::get_wes(char const *ip_string,
+ char const *username, char const *password)
+{
+ unsigned char ip[4];
+
+ if (decode_ipv4(ip_string, ip))
+ throw invalid_argument();
+ return (get_wes(ip, username, password));
+}
+
+wes interface::get_wes(char const *ip_string,
+ std::string const username, std::string const password)
+{
+ return (get_wes(ip_string, username.c_str(), password.c_str()));
+}
+
+wes interface::get_wes(std::string const ip,
+ char const *username, char const *password)
+{
+ return (get_wes(ip.c_str(), username, password));
+}
+
+wes interface::get_wes(std::string const ip,
+ std::string const username, std::string const password)
+{
+ return (get_wes(ip, username.c_str(), password.c_str()));
+}
+
+wes interface::get_wes(unsigned char const ip[4])
+{
+ return (get_wes(ip, "admin", "wes", "adminftp", "wesftp"));
+}
+
+wes interface::get_wes(char const *ip_string)
+{
+ unsigned char ip[4];
+
+ if (decode_ipv4(ip_string, ip))
+ throw invalid_argument();
+ return (get_wes(ip));
+}
+
+wes interface::get_wes(std::string const ip)
+{
+ return (get_wes(ip.c_str()));
+}
+
+/* ---
+ * Récupération d'un WES factice.
+ * --- */
+
+dummy_wes interface::get_dummy_wes(void)
+{
+ wespoptions_t args;
+ wespret_with_id_t *resp;
+ wespret_t ret;
+
+ args.type = WESPTYPE_DUMMY;
+
+ resp = gather_1(&args, get_clnt());
+ if (!resp)
+ throw connexion_exception();
+
+ ret = resp->ret;
+ if (ret != WESPRET_OK)
+ throw_exception_using_ret(ret);
+
+ return (dummy_wes(this, static_cast<int>(resp->id)));
+}
+
+/* ---
+ * Suppression d'une ressource de type serveur WES.
+ * --- */
+
+void interface::remove(int given_id)
+{
+ wespid_t id;
+ wespret_t *ret;
+
+ id = static_cast<wespid_t>(given_id);
+ ret = unregister_1(&id, get_clnt());
+ if (!ret)
+ throw connexion_exception();
+
+ if (*ret != WESPRET_OK)
+ throw_exception_using_ret(*ret);
+}
+
+void interface::remove(wes_base const &resource)
+{
+ remove(resource.get_id());
+}
+
+void interface::remove(wes_base const *resource)
+{
+ if (!resource)
+ return ;
+ remove(resource->get_id());
+}
diff --git a/lib/internals.hpp b/lib/internals.hpp
index f610582..044e2a0 100644
--- a/lib/internals.hpp
+++ b/lib/internals.hpp
@@ -42,11 +42,13 @@ extern "C" {
# define WESH_CLIENT_TYPE CLIENT
# define WESH_GATHER_TYPE wespregopts_t
-# include <wesh.hpp>
-# define clnt(WES) ((WES)->get_clnt())
+# include <libwesh.hpp>
/* Utilitaires. */
+namespace wesh {
+extern int decode_ipv4(char const *s, unsigned char ip[4]);
[[noreturn]] extern void throw_exception_using_ret(wespret_t ret);
+}
-#endif /* INTERNALSPP_H */
+#endif /* INTERNALS_HPP */
diff --git a/lib/wes/dummy_wes.cpp b/lib/meter.cpp
index 6b36c4c..d8d1d0a 100644
--- a/lib/wes/dummy_wes.cpp
+++ b/lib/meter.cpp
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * wes/dummy_wes.cpp -- classe `dummy_wes` héritée de `wes_base`.
+ * meter.cpp -- méthodes de la classe `meter_base` et dérivées.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -27,32 +27,54 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
* ************************************************************************* */
-#include "../internals.hpp"
+#include "internals.hpp"
using namespace wesh;
/* ---
- * Récupération de la ressource.
+ * Constructeurs, destructeur, méthodes de base.
* --- */
-void dummy_wes::gather(void)
+meter_base::meter_base(wes_base *given_parent, int given_id)
{
- wespoptions_t args;
- wespret_with_id_t *resp;
- wespret_t ret;
+ if (given_id <= 0 || given_id > 32766 || !given_parent)
+ throw no_meter_exception();
- if (this->id != 0)
- throw already_created_exception();
+ given_parent->add_meter_ref(this);
- args.type = WESPTYPE_DUMMY;
+ parent = given_parent;
+ id = given_id;
+}
+
+meter_base::meter_base(meter_base const &original)
+{
+ /* Les données ont déjà été copiées. */
+
+ if (parent)
+ parent->add_meter_ref(this);
+}
+
+meter_base::~meter_base(void)
+{
+ if (parent)
+ parent->del_meter_ref(this);
+}
- resp = gather_1(&args, clnt(this));
- if (!resp)
- throw connexion_exception();
+void meter_base::orphan(void)
+{
+ parent = nullptr;
+}
- ret = resp->ret;
- if (ret != WESPRET_OK)
- throw_exception_using_ret(ret);
+int meter_base::get_id(void)
+{
+ return (id);
+}
- this->id = resp->id;
+CLIENT *meter_base::get_clnt(void)
+{
+ if (!parent)
+ throw no_parent_exception();
+ return (parent->get_clnt());
}
+
+/* TODO: getters, setters */
diff --git a/lib/meter/clamp.cpp b/lib/meter/clamp.cpp
deleted file mode 100644
index 54ceed5..0000000
--- a/lib/meter/clamp.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ****************************************************************************
- * meter/clamp.cpp -- méthodes de la classe `clamp`.
- * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
- *
- * This project is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the
- * CeCILL license as circulated by CEA, CNRS and INRIA at the
- * following URL: "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the project's author, the holder of the
- * economic rights, and the successive licensors have only limited liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also therefore
- * means that it is reserved for developers and experienced professionals
- * having in-depth computer knowledge. Users are therefore encouraged to load
- * and test the software's suitability as regards their requirements in
- * conditions enabling the security of their systems and/or data to be
- * ensured and, more generally, to use and operate it in the same conditions
- * as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms.
- * ************************************************************************* */
-#include "../internals.hpp"
-
-using namespace wesh;
-
-/* TODO */
diff --git a/lib/meter/meter_base.cpp b/lib/meter/meter_base.cpp
deleted file mode 100644
index 14a08cf..0000000
--- a/lib/meter/meter_base.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ****************************************************************************
- * meter/meter_base.cpp -- méthodes de la classe `meter_base`.
- * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
- *
- * This project is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the
- * CeCILL license as circulated by CEA, CNRS and INRIA at the
- * following URL: "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the project's author, the holder of the
- * economic rights, and the successive licensors have only limited liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also therefore
- * means that it is reserved for developers and experienced professionals
- * having in-depth computer knowledge. Users are therefore encouraged to load
- * and test the software's suitability as regards their requirements in
- * conditions enabling the security of their systems and/or data to be
- * ensured and, more generally, to use and operate it in the same conditions
- * as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms.
- * ************************************************************************* */
-#include "../internals.hpp"
-
-using namespace wesh;
-
-/* ---
- * Constructeur, destructeur.
- * --- */
-
-meter_base::meter_base(void)
-{
- this->parent = nullptr;
- this->id = -1;
-}
-
-meter_base::meter_base(wes_base *parent_to_use, int num_to_use)
-{
- if (!parent_to_use || num_to_use <= 0 || num_to_use > 32766)
- throw no_meter_exception();
-
- /* FIXME: Vérifier si les arguments sont valides. */
-
- this->parent = parent_to_use;
- this->id = num_to_use;
-
- this->gather();
-}
-
-/* ---
- * Récupération de l'objet.
- * --- */
-
-/* Remarque : l'absence de `default` dans les switch est volontaire. */
-
-void meter_base::gather(void)
-{
- wespid_with_meter_id_t args = {
- static_cast<wespid_t>(this->parent->get_id()),
- this->num};
- wespret_with_tic_t *resp;
-
- if (this->num < 0)
- throw not_loaded_exception();
-
- /* Requête au démon. */
-
- resp = get_tic_1(&args, clnt(this->parent));
- if (!resp)
- throw connexion_exception();
-
- /* TODO: other values */
-}
-
-void meter_base::gather(wes_base *parent_now, int num_now)
-{
- if (this->num >= 0)
- throw not_loaded_exception();
-
- /* FIXME: vérifier si les arguments sont valides. */
-
- this->parent = parent_now;
- this->num = num_now;
-
- this->gather();
-}
-
-/* TODO: meter_base::update() */
diff --git a/lib/meter/pulse_meter.cpp b/lib/meter/pulse_meter.cpp
deleted file mode 100644
index bb988dd..0000000
--- a/lib/meter/pulse_meter.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ****************************************************************************
- * meter/pulse_meter.cpp -- méthodes de la classe `pulse_meter`.
- * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
- *
- * This project is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the
- * CeCILL license as circulated by CEA, CNRS and INRIA at the
- * following URL: "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the project's author, the holder of the
- * economic rights, and the successive licensors have only limited liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also therefore
- * means that it is reserved for developers and experienced professionals
- * having in-depth computer knowledge. Users are therefore encouraged to load
- * and test the software's suitability as regards their requirements in
- * conditions enabling the security of their systems and/or data to be
- * ensured and, more generally, to use and operate it in the same conditions
- * as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms.
- * ************************************************************************* */
-#include "../internals.hpp"
-
-using namespace wesh;
-
-/* TODO */
diff --git a/lib/meter/teleinfo_meter.cpp b/lib/sensor.cpp
index 1f8d800..db66e6a 100644
--- a/lib/meter/teleinfo_meter.cpp
+++ b/lib/sensor.cpp
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * meter/teleinfo_meter.cpp -- méthodes de la classe `teleinfo_meter`.
+ * sensor.cpp -- méthodes de la classe `sensor_base` et dérivées.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -27,8 +27,54 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
* ************************************************************************* */
-#include "../internals.hpp"
+#include "internals.hpp"
using namespace wesh;
-/* TODO */
+/* ---
+ * Constructeurs, destructeur, méthodes de base.
+ * --- */
+
+sensor_base::sensor_base(wes_base *given_parent, int given_id)
+{
+ if (id_to_use <= 0 || id_to_use > 32766 || !given_parent)
+ throw no_sensor_exception();
+
+ given_parent->add_sensor_ref(this);
+
+ parent = given_parent;
+ id = given_id;
+}
+
+sensor_base::sensor_base(sensor_base const &original)
+{
+ /* Les données ont déjà été copiées. */
+
+ if (parent)
+ parent->add_sensor_ref(this);
+}
+
+sensor_base::~sensor_base(void)
+{
+ if (parent)
+ given_parent->del_sensor_ref(this);
+}
+
+void sensor_base::orphan(void)
+{
+ parent = nullptr;
+}
+
+int sensor_base::get_id(void)
+{
+ return (id);
+}
+
+CLIENT *sensor_base::get_clnt(void)
+{
+ if (!parent)
+ throw no_parent_exception();
+ return (parent->get_clnt());
+}
+
+/* TODO: getters, setters */
diff --git a/lib/wes/wes_base.cpp b/lib/wes.cpp
index 6f75b6c..d313a65 100644
--- a/lib/wes/wes_base.cpp
+++ b/lib/wes.cpp
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * wes/wes_base.cpp -- méthodes de la classe `wes_base`.
+ * wes.cpp -- méthodes de la classe `wes_base` et dérivées.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -27,78 +27,91 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
* ************************************************************************* */
-#include "../internals.hpp"
+#include "internals.hpp"
using namespace wesh;
/* ---
- * Constructeur, destructeur.
+ * Constructeur et destructeur de la classe de base.
* --- */
-wes_base::wes_base(void)
+wes_base::wes_base(interface *given_parent, int given_id)
{
- this->id = 0;
- this->client = nullptr;
+ if (given_id <= 0 || given_id > 32766 || !given_parent)
+ throw no_wes_exception();
+
+ given_parent->add_wes_ref(this);
+
+ parent = given_parent;
+ id = given_id;
}
-wes_base::~wes_base(void)
+wes_base::wes_base(wes_base const &original)
{
- if (this->client)
- clnt_destroy(static_cast<CLIENT*>(this->client));
-}
+ /* Les données ont déjà été copiées. */
-/* ---
- * Utilitaires pour les méthodes de cette classe et les objets qui
- * en dépendent.
- * --- */
+ if (parent)
+ parent->add_wes_ref(this);
+}
-CLIENT *wes_base::get_clnt(void)
+wes_base::~wes_base(void)
{
- if (this->client)
- return (this->client);
+ /* Prévenons le parent pour ne pas qu'il nous informe quand il meurt,
+ * puisque nous serons morts nous-mêmes. */
- this->client = clnt_create("localhost", WESHD_PROG, WESHD_VERS1, "tcp");
- if (!this->client)
- throw connexion_exception();
+ if (parent)
+ parent->del_wes_ref(this);
+
+ /* Prévenons également les enfants qu'ils sont orphelins avant de
+ * mourir. */
- return (this->client);
+ for (wes_base *p : meter_list)
+ p->orphan();
+ for (sensor_base *p : sensor_list)
+ p->orphan();
}
-int wes_base::get_id(void)
+int get_id(void)
{
- return (this->id);
+ return (id);
}
-/* ---
- * Récupération et suppression de la ressource.
- * --- */
-
-void wes_base::use(int given_id)
+CLIENT *wes_base::get_clnt(void)
{
- if (this->id != 0)
- throw already_created_exception();
-
- this->id = given_id;
+ return (parent->get_clnt());
}
-void wes_base::remove(void)
+void wes_base::add_meter_ref(wes_base *resource)
{
- wespid_t wid;
- wespret_t ret, *retp;
+ if (parent)
+ meter_list.insert(resource);
+}
- if (this->id == 0)
- throw not_loaded_exception();
+void wes_base::del_meter_ref(wes_base *resource)
+{
+ auto it = meter_list.find(resource);
+ if (resource != std::set::end)
+ meter_list.erase(resource);
+}
- wid = static_cast<wespid_t>(this->id);
- retp = unregister_1(&wid, clnt(this));
- if (!retp)
- throw connexion_exception();
+void wes_base::add_sensor_ref(wes_base *resource)
+{
+ if (parent)
+ sensor_list.insert(resource);
+}
- ret = *retp;
- if (ret != WESPRET_OK)
- throw_exception_using_ret(ret);
+void wes_base::del_sensor_ref(wes_base *resource)
+{
+ auto it = sensor_list.find(resource);
+ if (resource != std::set::end)
+ sensor_list.erase(resource);
+}
- this->id = 0;
+void wes_base::orphan(void)
+{
+ if (!parent)
+ return ;
+ parent = nullptr;
}
/* ---
@@ -110,12 +123,9 @@ std::string wes_base::get_name(void)
wespid_with_wes_flags_t args;
wespret_with_wes_t *resp;
- if (this->id == 0)
- throw not_loaded_exception();
-
args.id = static_cast<wespid_t>(this->id);
args.to_get = WESP_NAME;
- resp = get_1(&args, clnt(this));
+ resp = get_1(&args, get_clnt());
if (!resp)
throw connexion_exception();
@@ -125,43 +135,37 @@ std::string wes_base::get_name(void)
return (std::string(resp->wes.name));
}
-void wes_base::set_name(std::string name_to_set)
-{
- set_name(name_to_set.c_str());
-}
-
-void wes_base::set_name(const char *name_to_set)
+void wes_base::set_name(char const *name_to_set)
{
wespid_with_wes_t args;
wespret_t ret, *retp;
+ char namebuf[33];
+ const char *nm;
+ size_t len;
- if (this->id == 0)
- throw not_loaded_exception();
-
- {
- char namebuf[33];
- const char *nm;
- size_t len;
+ nm = static_cast<const char*>(memchr(name_to_set, '\0', 33));
+ len = nm ? static_cast<size_t>(nm - name_to_set) : 32;
+ memcpy(namebuf, name_to_set, len);
+ namebuf[len] = '\0';
- nm = static_cast<const char*>(memchr(name_to_set, '\0', 33));
- len = nm ? static_cast<size_t>(nm - name_to_set) : 32;
- memcpy(namebuf, name_to_set, len);
- namebuf[len] = '\0';
-
- args.id = static_cast<wespid_t>(this->id);
- args.wes.name = namebuf;
- args.wes.to_set = WESP_NAME;
+ args.id = static_cast<wespid_t>(this->id);
+ args.wes.name = namebuf;
+ args.wes.to_set = WESP_NAME;
- retp = set_1(&args, clnt(this));
- if (!retp)
- throw connexion_exception();
- }
+ retp = set_1(&args, get_clnt());
+ if (!retp)
+ throw connexion_exception();
ret = *retp;
if (ret != WESPRET_OK)
throw_exception_using_ret(ret);
}
+void wes_base::set_name(std::string name_to_set)
+{
+ set_name(name_to_set.c_str());
+}
+
/* ---
* Récupération de la date.
* --- */
@@ -173,12 +177,9 @@ struct tm wes_base::get_date(void)
wespdt_t *dt;
struct tm tm;
- if (this->id == 0)
- throw not_loaded_exception();
-
args.id = static_cast<wespid_t>(this->id);
args.to_get = WESP_TIME;
- resp = get_1(&args, clnt(this));
+ resp = get_1(&args, get_clnt());
if (!resp)
throw connexion_exception();
@@ -201,15 +202,48 @@ struct tm wes_base::get_date(void)
* Récupération des compteurs.
* --- */
+#if 0
+/* Code provenant de l'ancienne méthode `gather()` de `meter_base`.
+ * TODO: la réutiliser? */
+
+void meter_base::gather(void)
+{
+ wespid_with_meter_id_t args = {
+ static_cast<wespid_t>(this->parent->get_id()),
+ this->num};
+ wespret_with_tic_t *resp;
+
+ if (this->num < 0)
+ throw not_loaded_exception();
+
+ /* Requête au démon. */
+
+ resp = get_tic_1(&args, clnt(this->parent));
+ if (!resp)
+ throw connexion_exception();
+
+ /* TODO: other values */
+}
+#endif
+
clamp wes_base::get_clamp(int cl_id)
{
clamp cl(this, cl_id);
- /* TODO: préférer la recherche */
-
return (cl);
}
+clamp wes_base::get_clamp_no(int cl_no)
+{
+ wespid_with_meter_query_t args;
+ wespret_with_meter_list_t *resp;
+ int cl_id;
+
+
+
+ return (clamp(this, cl_id));
+}
+
pulse_meter wes_base::get_pulse_meter(int pl_id)
{
pulse_meter pm(this, pl_id);
diff --git a/lib/wes/wes.cpp b/lib/wes/wes.cpp
deleted file mode 100644
index b8d469d..0000000
--- a/lib/wes/wes.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/* ****************************************************************************
- * wes/wes.cpp -- méthodes de la classe `wes` héritée de `wes_base`.
- * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
- *
- * This project is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the
- * CeCILL license as circulated by CEA, CNRS and INRIA at the
- * following URL: "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the project's author, the holder of the
- * economic rights, and the successive licensors have only limited liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also therefore
- * means that it is reserved for developers and experienced professionals
- * having in-depth computer knowledge. Users are therefore encouraged to load
- * and test the software's suitability as regards their requirements in
- * conditions enabling the security of their systems and/or data to be
- * ensured and, more generally, to use and operate it in the same conditions
- * as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms.
- * ************************************************************************* */
-#include "../internals.hpp"
-
-using namespace wesh;
-
-/* ---
- * Utilitaires.
- * --- */
-
-static int decode_ipv4(const char *s, unsigned char ip[4])
-{
- int i;
-
- ip[0] = 0;
- ip[1] = 0;
- ip[2] = 0;
- ip[3] = 0;
-
- for (i = 0; *s; s++) switch (*s) {
- case '1': case '2': case '3':
- case '4': case '5': case '6':
- case '7': case '8': case '9':
- case '0':
-
- ip[i] = static_cast<unsigned char>(ip[i] * 10 + (*s - '0'));
- break;
-
- case '.':
- if (++i >= 4)
- return (1);
- break;
-
- default:
- return (1);
- }
-
- if (i < 3) {
- ip[3] = ip[i];
- ip[i] = 0;
- }
-
- return (0);
-}
-
-/* ---
- * Récupération de la ressource.
- * --- */
-
-void wes::gather(const unsigned char ip[4],
- std::string http_username, std::string http_password,
- std::string ftp_username, std::string ftp_password)
-{
- wespoptions_t args;
- wespret_with_id_t *resp;
- wespret_t ret;
- char hu[http_username.length() + 1],
- hp[http_password.length() + 1],
- fu[ftp_username.length() + 1],
- fp[ftp_password.length() + 1];
-
- if (this->id != 0)
- throw already_created_exception();
-
- strcpy(hu, http_username.c_str());
- strcpy(hp, http_password.c_str());
- strcpy(fu, ftp_username.c_str());
- strcpy(fp, ftp_password.c_str());
-
- args.type = WESPTYPE_IP;
- args.wespoptions_t_u.ip.addr.type = WESPIPTYPE_4;
- args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[0] = ip[0];
- args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[1] = ip[1];
- args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[2] = ip[2];
- args.wespoptions_t_u.ip.addr.wespip_t_u.addr4[3] = ip[3];
- args.wespoptions_t_u.ip.http_username = hu;
- args.wespoptions_t_u.ip.http_password = hp;
- args.wespoptions_t_u.ip.ftp_username = fu;
- args.wespoptions_t_u.ip.ftp_password = fp;
-
- resp = gather_1(&args, clnt(this));
- if (!resp)
- throw connexion_exception();
-
- ret = resp->ret;
- if (ret != WESPRET_OK)
- throw_exception_using_ret(ret);
-
- this->id = resp->id;
-}
-
-void wes::gather(const std::string ip,
- std::string http_username, std::string http_password,
- std::string ftp_username, std::string ftp_password)
-{
- this->gather(ip.c_str(), http_username, http_password,
- ftp_username, ftp_password);
-}
-
-void wes::gather(const char *ip_string,
- std::string http_username, std::string http_password,
- std::string ftp_username, std::string ftp_password)
-{
- unsigned char ip[4];
-
- decode_ipv4(ip_string, ip);
- this->gather(ip, http_username, http_password, ftp_username, ftp_password);
-}
-
-void wes::gather(const unsigned char ip[4],
- std::string username, std::string password)
-{
- this->gather(ip, username, password, username, password);
-}
-
-void wes::gather(const std::string ip,
- std::string username, std::string password)
-{
- this->gather(ip.c_str(), username, password, username, password);
-}
-
-void wes::gather(const char *ip,
- std::string username, std::string password)
-{
- this->gather(ip, username, password, username, password);
-}
-
-void wes::gather(const unsigned char ip[4])
-{
- this->gather(ip, "admin", "wes", "adminftp", "wesftp");
-}
-
-void wes::gather(const std::string ip)
-{
- this->gather(ip.c_str());
-}
-
-void wes::gather(const char *ip_string)
-{
- unsigned char ip[4];
-
- decode_ipv4(ip_string, ip);
- this->gather(ip);
-}
diff --git a/weshd.x b/weshd.x
index f20fa3b..99ef4ca 100644
--- a/weshd.x
+++ b/weshd.x
@@ -616,7 +616,7 @@ struct wespid_with_meter_id_and_span_t {
wespid_t id;
wespmeterid_t meter_id;
wespdt_t from;
- wespdt_t to; /* not included! */
+ wespdt_t to; /* non inclus ! */
};
struct wespid_with_meter_query_t {
@@ -646,6 +646,55 @@ struct wespret_with_meter_list_t {
wespmeter_list_element_t meters<>;
};
+/* Gestion des capteurs. */
+
+struct wespid_with_sensor_id_t {
+ wespid_t id;
+ wespsensorid_t sensor_id;
+ wespmetertype_t expected_type;
+ unsigned long to_get;
+};
+
+struct wespid_with_sensor_t {
+ wespid_t id;
+ wespsensorid_t sensor_id;
+ wespsensor_t sensor;
+};
+
+struct wespid_with_sensor_id_and_span_t {
+ wespid_t id;
+ wespsensorid_t sensor_id;
+ wespdt_t from;
+ wespdt_t to; /* non inclus ! */
+};
+
+struct wespid_with_sensor_query_t {
+ wespid_t id;
+ wespsensortype_t of_type;
+ int offset;
+ int count; /* min. 1, max. 10 */
+};
+
+struct wespret_with_sensor_t {
+ wespret_t ret;
+ wespsensor_t sensor;
+};
+
+struct wespret_with_sensor_data_t {
+ wespret_t ret;
+ wespsensorvalues_t val;
+};
+
+struct wespsensor_list_element_t {
+ wespsensorid_t id;
+ wespsensortype_t type;
+};
+
+struct wespret_with_sensor_list_t {
+ wespret_t ret;
+ wespsensor_list_element_t sensors<>;
+};
+
/* ---
* Définition du programme.
* --- */
@@ -675,6 +724,15 @@ program WESHD_PROG {
wespret_with_meter_list_t
QUERY_METERS(wespid_with_meter_query_t args) = 9;
+ /* Gérer les capteurs. */
+
+ wespret_with_sensor_t GET_SENSOR(wespid_with_sensor_id_t id) = 10;
+ wespret_t SET_SENSOR(wespid_with_sensor_t id) = 11;
+ wespret_with_sensor_data_t
+ GET_SENSOR_DATA(wespid_with_sensor_id_and_span_t args) = 12;
+ wespret_with_sensor_list_t
+ QUERY_SENSORS(wespid_with_sensor_query_t args) = 13;
+
/* TODO: interactions avec le LCD */
} = 1;
} = 0x20001234;