]> vcs.slashdirt.org Git - sw/tic2json.git/commitdiff

vcs.slashdirt.org Git - sw/tic2json.git/commitdiff

git git / sw / tic2json.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 246e3f5)
PME-PMI: working parser
2022年5月31日 10:37:23 +0000 (12:37 +0200)
Tue, 7 Jun 2022 17:06:03 +0000 (19:06 +0200)
src/ticv01pme.y [new file with mode: 0644] patch | blob

diff --git a/src/tic.c b/src/tic.c
index 016ec003f2bf5533927f3f72ec8085670d0bb5f9..debda4378d5fcdf38584128b84471592723ffe45 100644 (file)
--- a/src/tic.c
+++ b/src/tic.c
@@ -2,7 +2,7 @@
// tic.c
// Common routines for TIC parsers
//
-// (C) 2021 Thibaut VARENE
+// (C) 2021-2022 Thibaut VARENE
// License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html
//
@@ -29,6 +29,8 @@ void make_field(struct tic_field *field, const struct tic_etiquette *etiq, char
memcpy(&field->etiq, etiq, sizeof(field->etiq));
switch ((etiq->unittype & 0xF0)) {
+ case T_IGN:
+ return;
case T_STRING:
field->data.s = data;
return;
diff --git a/src/tic.h b/src/tic.h
index ff60db1f5476199609890d49870f487686ac2e5c..6fcdb6f9fb5a5294ffd274e38864f904dd3e2661 100644 (file)
--- a/src/tic.h
+++ b/src/tic.h
@@ -2,7 +2,7 @@
// tic.h
// Interface for TIC parsers
//
-// (C) 2021 Thibaut VARENE
+// (C) 2021-2022 Thibaut VARENE
// License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html
//
@@ -32,16 +32,20 @@
/**
* TIC units.
- * @warning The code assumes this fits on 4 bits
+ * @warning The code assumes this fits on 4 bits (16 values)
*/
enum tic_unit {
U_SANS = 0x00,
+ U_VAH,
+ U_KWH,
U_WH,
+ U_KVARH,
U_VARH,
U_A,
U_V,
U_KVA,
U_VA,
+ U_KW,
U_W,
U_MIN,
U_DAL,
@@ -55,6 +59,8 @@ enum tic_unit {
enum data_type {
T_STRING = 0x10,
T_HEX = 0x20,
+ T_DATE = 0x30,
+ T_IGN = 0x40,
};
/** Internal parser representation of a TIC etiquette */
diff --git a/src/ticv01pme.y b/src/ticv01pme.y
new file mode 100644 (file)
index 0000000..04b727f
--- /dev/null
+++ b/src/ticv01pme.y
@@ -0,0 +1,221 @@
+//
+// ticv01pme.y
+// A parser for ENEDIS TIC version 01 protocol
+//
+// (C) 2022 Thibaut VARENE
+// License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html
+//
+// Development of this file was sponsored by Wiztivi - www.wiztivi.com
+
+/**
+ * @file
+ * This parser implements a complete grammar that supports TIC version 01 - PME-PMI variant
+ * as specified in Enedis-NOI-CPT_02E.pdf version 6.
+ *
+ * This parser does not allocate memory, except if a filter configuration is used in
+ * which case the etiq_en array will be allocated (it's a few hundred bytes).
+ * A left-recursion grammar has been implemented to keep the memory usage to the bare
+ * minimum as well. As a tradeoff, valid datasets are always emitted regardless of the
+ * overall status of the containing frame.
+ *
+ * Compteurs supportés:
+ * - PME-PMI (tous paliers)
+ *
+ * Certains champs ne sont actuellement pas supportés par ce code: ils ne sont pas émis.
+ * Il s'agit des champs relatifs à la tarification dynamique et aux mesures de tangente phi.
+ * Me contacter pour implémentation:
+ * - ETATDYN1 PREAVIS1 TDYN1CD TDYN1CF TDYN1FD TDYN1FF
+ * - ETATDYN2 PREAVIS2 TDYN2CD TDYN2CF TDYN2FD TDYN2FF
+ * - TGPHI_s TGPHI_i
+ */
+
+%{
+#include <stdlib.h>
+#include "tic.h"
+
+int ticv01pmeyylex();
+int ticv01pmeyylex_destroy();
+extern FILE *ticv01pmeyyin;
+static void yyerror(const char *);
+
+extern bool filter_mode;
+extern bool *etiq_en;
+%}
+
+%union {
+ char *text;
+ const char *label;
+ struct tic_etiquette etiq;
+ struct tic_field field;
+}
+
+%verbose
+
+%token TOK_STX TOK_ETX TOK_EOT TOK_SEP
+%token FIELD_START FIELD_OK FIELD_KO
+%token TICFILTER
+%token ET_IGNORED
+
+%token <text> TOK_DATA TOK_HDATE
+
+%token <label> ET_TRAME ET_ADS ET_MESURES ET_DATE ET_MODE ET_CONFIG ET_PTCOUR ET_TARIFDYN
+%token <label> ET_EA_s ET_ERP_s ET_ERM_s ET_EAPP_s ET_EA_i ET_ERP_i ET_ERM_i ET_EAPP_i
+%token <label> ET_DATEPAX ET_PAX_i ET_PAX_s ET_DEBP ET_EAP_s ET_EAP_i
+%token <label> ET_ERPP_s ET_ERMP_s ET_ERPP_i ET_ERMP_i ET_DEBPM1 ET_FINPM1 ET_EAPM1_s ET_EAPM1_i
+%token <label> ET_ERPPM1_s ET_ERMPM1_s ET_ERPPM1_i ET_ERMPM1_i ET_PS ET_PREAVIS ET_PA1MN ET_PMAX_s ET_PMAX_i
+
+%type <etiq> etiquette etiquette_horodate etiquette_nodate etiquette_ignored
+%type <field> field field_horodate field_nodate field_ignored
+
+%destructor { free($$); } <text>
+%destructor { free_field(&$$); } <field>
+%destructor { } <> <*>
+
+%%
+
+start: filter | frames ;
+
+/* filter config only */
+filter:
+ TICFILTER etiquettes
+;
+
+etiquettes:
+ etiquette { etiq_en[1ドル.tok]=1; }
+ | etiquettes etiquette { etiq_en[2ドル.tok]=1; }
+ | error { YYABORT; }
+;
+
+etiquette:
+ etiquette_horodate
+ | etiquette_nodate
+ | etiquette_ignored
+;
+
+/* stream processing */
+frames:
+ frame
+ | frames frame
+;
+
+frame:
+ TOK_STX datasets TOK_ETX { frame_sep(); }
+ | TOK_STX datasets TOK_EOT { /*mark error but don't print*/ frame_err(); frame_sep(); }
+ | error TOK_EOT { frame_err(); frame_sep(); pr_err("transmission interrupted\n"); yyerrok; }
+ | error TOK_ETX { frame_err(); frame_sep(); pr_err("frame error\n"); yyerrok; }
+;
+
+datasets:
+ error { frame_err(); pr_err("dataset error\n"); }
+ | dataset
+ | datasets dataset
+;
+
+dataset:
+ FIELD_START field FIELD_OK { print_field(&2ドル); free_field(&2ドル); }
+ | FIELD_START field FIELD_KO { frame_err(); pr_err("dataset invalid checksum\n"); free_field(&2ドル); }
+ | FIELD_START error FIELD_OK { /*not a frame error*/ pr_err("unrecognized dataset\n"); yyerrok; }
+;
+
+field: field_horodate
+ | field_nodate
+ | field_ignored
+;
+
+field_horodate:
+ etiquette_horodate TOK_SEP TOK_HDATE { make_field(&$,ドル &1,ドル 3,ドル NULL); }
+;
+
+field_nodate:
+ etiquette_nodate TOK_SEP TOK_DATA { make_field(&$,ドル &1,ドル NULL, 3ドル); }
+;
+
+/* special-case ignored fields: token data must be explicitely freed */
+field_ignored:
+ etiquette_ignored TOK_SEP TOK_DATA { make_field(&$,ドル &1,ドル NULL, NULL); free(3ドル); }
+ | etiquette_ignored TOK_SEP TOK_HDATE { make_field(&$,ドル &1,ドル NULL, NULL); free(3ドル); }
+ | etiquette_ignored TOK_SEP TOK_HDATE TOK_DATA { make_field(&$,ドル &1,ドル NULL, NULL); free(3ドル); free(4ドル); }
+;
+
+etiquette_horodate:
+ ET_DATE { $$.tok=yytranslate[ET_DATE]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Date et heure courante"; }
+ | ET_DATEPAX { $$.tok=yytranslate[ET_DATEPAX]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Date de la puissance active moyenne Tc min d’étiquette PAX (X = 1 à 6)"; }
+ | ET_DEBP { $$.tok=yytranslate[ET_DEBP]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Date et heure de début de la période P"; }
+ | ET_DEBPM1 { $$.tok=yytranslate[ET_DEBPM1]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Date et heure de début de la période P-1"; }
+ | ET_FINPM1 { $$.tok=yytranslate[ET_FINPM1]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Date et heure de fin de la période P"; }
+;
+
+etiquette_nodate:
+ ET_TRAME { $$.tok=yytranslate[ET_TRAME]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="TEST"; }
+ | ET_ADS { $$.tok=yytranslate[ET_ADS]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Identifiant du compteur"; }
+ | ET_MESURES { $$.tok=yytranslate[ET_MESURES]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Nom du traitement tarifaire"; }
+ | ET_EA_s { $$.tok=yytranslate[ET_EA_s]; $$.unittype=U_WH; $$.label=1ドル; $$.desc="Energie active soutirée (au primaire) depuis dernier top Td"; }
+ | ET_ERP_s { $$.tok=yytranslate[ET_ERP_s]; $$.unittype=U_VARH; $$.label=1ドル; $$.desc="Energie réactive positive (au primaire) depuis dernier top Td en période de soutirage d'énergie active"; }
+ | ET_ERM_s { $$.tok=yytranslate[ET_ERM_s]; $$.unittype=U_VARH; $$.label=1ドル; $$.desc="Energie réactive négative (au primaire) depuis dernier top Td en période de soutirage d'énergie active"; }
+ | ET_EAPP_s { $$.tok=yytranslate[ET_EAPP_s]; $$.unittype=U_VAH; $$.label=1ドル; $$.desc="Energie apparente soutirée (au primaire) depuis dernier top Td"; }
+ | ET_EA_i { $$.tok=yytranslate[ET_EA_i]; $$.unittype=U_WH; $$.label=1ドル; $$.desc="Energie active injectée (au primaire) depuis dernier top Td"; }
+ | ET_ERP_i { $$.tok=yytranslate[ET_ERP_i]; $$.unittype=U_VARH; $$.label=1ドル; $$.desc="Energie réactive positive (au primaire) depuis dernier top Td en période d'injection d'énergie active"; }
+ | ET_ERM_i { $$.tok=yytranslate[ET_ERM_i]; $$.unittype=U_VARH; $$.label=1ドル; $$.desc="Energie réactive négative (au primaire) depuis dernier top Td en période d'injection d'énergie active"; }
+ | ET_EAPP_i { $$.tok=yytranslate[ET_EAPP_i]; $$.unittype=U_VAH; $$.label=1ドル; $$.desc="Energie apparente injectée (au primaire) depuis dernier top Td"; }
+ | ET_PTCOUR { $$.tok=yytranslate[ET_PTCOUR]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Période tarifaire courante"; }
+ | ET_TARIFDYN { $$.tok=yytranslate[ET_TARIFDYN]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Chaîne de caractères indiquant la présence du signal tarifaire externe"; }
+ | ET_MODE { $$.tok=yytranslate[ET_MODE]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Prend la valeur « CONTROLE » si le compteur est dans ce mode"; }
+ | ET_CONFIG { $$.tok=yytranslate[ET_CONFIG]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Prend la valeur « CONSO » ou « PROD »"; }
+ | ET_PAX_s { $$.tok=yytranslate[ET_PAX_s]; $$.unittype=U_KW; $$.label=1ドル; $$.desc="Puissance active moyenne Tc min (X = 1 à 6) en soutirage"; }
+ | ET_PAX_i { $$.tok=yytranslate[ET_PAX_i]; $$.unittype=U_KW; $$.label=1ドル; $$.desc="Puissance active moyenne Tc min (X = 1 à 6) en injection"; }
+ | ET_EAP_s { $$.tok=yytranslate[ET_EAP_s]; $$.unittype=U_KWH; $$.label=1ドル; $$.desc="Energie active soutirée de la période P pour la période tarifaire en cours"; }
+ | ET_EAP_i { $$.tok=yytranslate[ET_EAP_i]; $$.unittype=U_KWH; $$.label=1ドル; $$.desc="Energie active injectée de la période P pour la période tarifaire en cours"; }
+ | ET_ERPP_s { $$.tok=yytranslate[ET_ERPP_s]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive positive de la période P pour la période tarifaire en cours en période de soutirage d'énergie active"; }
+ | ET_ERMP_s { $$.tok=yytranslate[ET_ERMP_s]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive négative de la période P pour la période tarifaire en cours en période de soutirage d'énergie active"; }
+ | ET_ERPP_i { $$.tok=yytranslate[ET_ERPP_i]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive positive de la période P pour la période tarifaire en cours en période d'injection d'énergie active"; }
+ | ET_ERMP_i { $$.tok=yytranslate[ET_ERMP_i]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive négative de la période P pour la période tarifaire en cours en période d'injection d'énergie active"; }
+ | ET_EAPM1_s { $$.tok=yytranslate[ET_EAPM1_s]; $$.unittype=U_KWH; $$.label=1ドル; $$.desc="Energie active soutirée de la période P-1 pour la période tarifaire en cours"; }
+ | ET_EAPM1_i { $$.tok=yytranslate[ET_EAPM1_i]; $$.unittype=U_KWH; $$.label=1ドル; $$.desc="Energie active injectée de la période P-1 pour la période tarifaire en cours"; }
+ | ET_ERPPM1_s { $$.tok=yytranslate[ET_ERPPM1_s]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive positive de la période P-1 pour la période tarifaire en cours en période de soutirage d'énergie active"; }
+ | ET_ERMPM1_s { $$.tok=yytranslate[ET_ERMPM1_s]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive négative de la période P-1 pour la période tarifaire en cours en période de soutirage d'énergie active"; }
+ | ET_ERPPM1_i { $$.tok=yytranslate[ET_ERPPM1_i]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive positive de la période P-1 pour la période tarifaire en cours en période d'injection d'énergie active"; }
+ | ET_ERMPM1_i { $$.tok=yytranslate[ET_ERMPM1_i]; $$.unittype=U_KVARH; $$.label=1ドル; $$.desc="Energie réactive négative de la période P-1 pour la période tarifaire en cours en période d'injection d'énergie active"; }
+
+ | ET_PS { $$.tok=yytranslate[ET_PS]; $$.unittype=U_SANS; $$.label=1ドル; $$.desc="Puissance souscrite de la période tarifaire en cours"; }
+
+ | ET_PREAVIS { $$.tok=yytranslate[ET_PREAVIS]; $$.unittype=U_SANS|T_STRING; $$.label=1ドル; $$.desc="Chaîne « DEP »"; }
+ | ET_PA1MN { $$.tok=yytranslate[ET_PA1MN]; $$.unittype=U_KW; $$.label=1ドル; $$.desc="Puissance active 1 minute"; }
+
+ | ET_PMAX_s { $$.tok=yytranslate[ET_PMAX_s]; $$.unittype=U_SANS; $$.label=1ドル; $$.desc="Puissance maximale atteinte en période de soutirage d’énergie active pour la période tarifaire en cours"; }
+ | ET_PMAX_i { $$.tok=yytranslate[ET_PMAX_i]; $$.unittype=U_SANS; $$.label=1ドル; $$.desc="Puissance maximale atteinte en période d’injection d’énergie active pour la période tarifaire en cours"; }
+;
+
+etiquette_ignored:
+ ET_IGNORED { $$.tok=yytranslate[ET_IGNORED]; $$.unittype=T_IGN; }
+;
+
+%%
+
+#ifndef BAREBUILD
+void parse_config_v01pme(const char *filename)
+{
+ if (!(ticv01pmeyyin = fopen(filename, "r"))) {
+ perror(filename);
+ exit(-1);
+ }
+
+ etiq_en = calloc(YYNTOKENS, sizeof(*etiq_en));
+ if (!etiq_en)
+ abort(); // OOM
+
+ filter_mode = true;
+ if (ticv01pmeyyparse()) {
+ pr_err("%s: filter config error!\n", filename);
+ exit(-1);
+ }
+
+ fclose(ticv01pmeyyin);
+ ticv01pmeyylex_destroy();
+ ticv01pmeyyin = stdin;
+ filter_mode = false;
+}
+#endif /* !BAREBUILD */
+
+static void yyerror(const char * s)
+{
+}
tic2json TIC parser/converter
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /