XBConvertTool V1.0 by XBary

To ściśle tajne i tajemnicze miejsce z którego wyłania się mroczna postać
Wchodzący robią to na własne ryzyko. Prosimy zachować Ciszę i nie karmić
-- Xbary jest strasznie wybredny
ODPOWIEDZ
Awatar użytkownika
SunRiver
Użytkownik
Posty: 1338
Rejestracja: 08 paź 2017, 11:27
Lokalizacja: Festung Oppeln
Kontakt:

XBConvertTool V1.0 by XBary

Post autor: SunRiver »

 ! Wiadomość z: SunRiver

Oryginalny tekst samego Xbarego -- ze starego bloga
Witam serdecznie, chciałbym zaprezentować pewne narzędzie programowe które ostatnio byłem zmuszony napisać. Już tłumaczę od początku
o co chodzi ...

W czasach kiedy praktycznie technologie zmieniają się z miesiąca na miesiąc, standardem prawie w każdym urządzeniu, które powstaje
(dziś) jest WIFI, bo o wiele łatwiej jest zrobić sterownik powiedzmy z kilkoma parametrami pracy, które to zmieniać można przez przeglądarkę
WWW - niż tworzenie wyświetlaczy, przycisków co wiąże się z większymi kosztami oraz większą awaryjnością urządzenia.
Po prostu tworzymy panel kontrolny urządzenia/sterownika w HTML, do którego dostęp mamy przez punkt dostępu WIFI danego urządzenia.
O ile taki panel kontrolny HTML ma wyświetlić na ekranie jakąś wartość to jeszcze niema większego problemu, problem powstaje kiedy danych
w takim panelu musimy mieć więcej i dokument HTML generowany jest dynamicznie, zależnie od kilku warunków zaistniałych w urządzeniu.
Do tego dochodzi tzw autoryzacja, utrzymanie sesji, panel serwisowy, panel użytkownika. Przy tych wspomnianych funkcjonalnościach małe mikrokontrolery mogą się po prostu zapchać ze względu na małą ilość pamięci RAM, operowanie na łańcuchach znaków relokowanie pamięci
może szybko doprowadzić do zawieszenia się urządzenia. I tak właśnie urodził się pomysł na dynamiczne HTML przy praktycznie minimalnym obciążeniu pamięci RAM oraz czynności jakie SERVER http musi wykonać podczas serwowania dokumentu, aby to wszystko ułatwić powstał
właśnie XBConverTool.

Działanie programu polega na tym że w IDE edytujemy sobie dokument HTML w nim zaznaczamy w odpowiedni sposób miejsca gdzie będą
wstawiane łańcuchy danych dynamicznych, następnie zapisujemy a XBConvertTool pracując w tle automatycznie na podstawie szablonu
wygeneruje inklude z treścią dokumentu HTML w postaci tablicy strawnej przez kompilator C.

Zaczynamy:

Ściągamy program (link na końcu wpisu) i rozpakowujemy gdzieś gdzie mamy swoje narzędzia.

Aby XBConvertTool mieć zawsze pod ręką można sobie go dodać w menu w VisualStudio w taki sposób:

menu: Tools-External Tools...

Obrazek

Taka konfiguracja zapewnia uruchomienie monitorowania folderu projektu.

Pierwsze uruchomienie.

Obrazek

-> Możliwość włączenia/wyłączenia monitorowania.
-> Dodawanie rozszerzenia pliku na które będzie XBConvertTool reagować.
-> Tutaj można ręcznie wskazać folder który będzie monitorowany, przeważnie powinno się korzystać z XBConvertTool uruchamiając
go z IDE (w naszym przypadku VisualStudio) wtedy to pole zostanie ustawione automatycznie na folder projektu.
-> Tutaj będzie można zobaczyć ostatnią konwersje, będą to dane przed konwersją do pliku wynikowego.
-> Natomiast tutaj będzie widać ostatnio generowany plik.
-> Prosty log czynności.


No to klikamy w "Dodaj rozszerzenie do reakcji..."

Obrazek

Powinna się ukazać zakładka z domyślną konfiguracją rozszerzenia, nazwa zakładki będzie pochodzić właśnie od rozszerzenia.
Na pierwszy rzut oka jest to dość zagmatwane bo zastosowałem tu własny autorski pomysł konwersji używającej szablonu, który składa się
między innymi ze zmiennych i funkci sterujących konwersją. Jak posługiwać się tymi %zmiennymi% opiszę w kolejnych wpisach.

Co jest co:

> Pole w którym wpisujemy rozszerzenia plików na które ma zareagować XBConvertTool, wpisujemy je oddzielając średnikiem np.
htm;html co spowoduje ze ten szablon zostanie zastosowany do dwóch rozszerzeń plików.
> Zahaczenie tej opcji spowoduje że zawartość zmiennej %datafile% zostanie poddana filtracji przez konwerter. Na razie zostawmy
tą opcje żeby nie zaciemniać.
> Tutaj edytujemy nazwę pliku wynikowego, jak widać zastosowane zostały zmienne które przybierają wartość w zależności od konwertowanego
pliku. Domyślnie generujemy inkludę C, np. "c:\plik.htm" będzie zapisany tak "c:\plik_htm.h". To dość istotne bo w przyszłości nie tylko do
HTMLa będzie można stosować konwerter.
> Szablon danych, domyślnie mamy tutaj gotową odpowiedź serwera HTTP, bardzo ważne to pole Content-Length: %datafilelength% .
Tutaj automatycznie się wstawi wielkość pliku konwertowanego, wartość która nie będzie się zmieniać pomimo że dane przez serwer będą
dynamicznie tworzone. Jak później zobaczymy server będzie zwolniony z budowania nagłówka odpowiedzi, wystarczy  tylko podać wskaźnik
i wysłać do klienta(przeglądarki).
> To już szablon inkludy, ja sobie to wymyśliłem tak że w inkludzie wszelkie dane będą w makrach (#define) przez co po podłączeniu inkludy
do projektu będzie można tablicę z danymi wstawić w dowolnym miejscu projektu. Oczywiście można to tak zmodyfikować, że będzie
generowany np. plik .c a w nim bez makr już wstawione dane ale to już zależy jak to kto sobie wymyśli.

>Usuwanie całej zakładki jeśli np. okaże się już nie potrzebna.<

Czyli mamy już reakcje na rozszerzenie .htm, teraz najlepiej zamknąć program przez co konfiguracja zostanie zapamiętana,
pojawi się plik XBConvertTool.ini obok programu.

Pora zaprezentować prosty przykład. Użyjemy do tego VisualStudio z pluginem VisualMicro, Arduino dla ESP8266 jako mikrokontroler
aplikacji z WIFI.

Obrazek

Kody wymagają obróbki po skopiowaniu ze względu na mogące się wkradać nieprawidłowe znaki. 

1. Tworzymy projekt arduino dla ESP8266.
2. W głównym pliku projektu zamieszczamy taki oto przykładowy server działający w trybie AP.
  1. #include <WiFiUdp.h>
  2. #include <WiFiServer.h>
  3. #include <WiFiClientSecure.h>
  4. #include <WiFiClient.h>
  5. #include <ESP8266WiFiType.h>
  6. #include <ESP8266WiFiSTA.h>
  7. #include <ESP8266WiFiScan.h>
  8. #include <ESP8266WiFiMulti.h>
  9. #include <ESP8266WiFiGeneric.h>
  10. #include <ESP8266WiFiAP.h>
  11. #include <ESP8266WiFi.h>
  12. #include <ESP8266WebServer.h>
  13.  
  14.  
  15. #include "xbutil.h"
  16. #include "index_htm.h"
  17.  
  18. ESP8266WebServer server(80);
  19.  
  20. uint32_t licznik;
  21. DEF_INDEX()
  22. void handle_root(void)
  23. {
  24.     SETVARI(index,LICZNIK,String(++licznik).c_str());
  25.     SEND(index);
  26. }
  27.  
  28. void setup()
  29. {
  30.     Serial.begin(115200);
  31.  
  32.     WiFi.mode(WIFI_AP);
  33.     WiFi.softAP("SunDuinoEXAM","12345678");
  34.  
  35.     server.on("/",handle_root);
  36.     server.begin();
  37. }
  38.  
  39. void loop()
  40. {
  41.     server.handleClient();
  42. }

3. Dodajemy plik index.htm do projektu.
  1. <HTML>
  2. <HEAD>
  3. <META NAME="GENERATOR" Content="Microsoft Visual Studio">
  4. <TITLE></TITLE>
  5. </HEAD>
  6. <BODY>
  7.     Sunduino Example. <br />    
  8.     Licznik odwiedzin: %licznik%
  9. </BODY>
  10. </HTML>
4. No i do prawidłowego działania należy podczepić do projektu moduł xbutil.cpp oraz jego inkludę.

xbutil.cpp
  1. #include "xbutil.h"
  2.  
  3.  
  4. void SetValueVar(const char *Anamevar, const char *Avalue, const char * Anames[], char * Avalues[], uint32_t Acount)
  5. {
  6.     uint32_t i;
  7.     for (i = 0;i < Acount;i++)
  8.     {
  9.         if (strcmp_P(Anamevar, Anames[i]))
  10.         {
  11.             Avalues[i] = (char *)Avalue;
  12.             exit;
  13.         }
  14.     }
  15.  
  16. }
  17. //===========================================================================================
  18. void SetValueVar(const uint32_t Aindxvar, const char *Avalue, char * Avalues[])
  19. {
  20.     Avalues[Aindxvar] = (char *)Avalue;
  21. }
  22. //===========================================================================================
  23. const char spaces[130] = "                                                                                                                              \0";
  24. void server_sendContent(ESP8266WebServer &Aserver, const char *Ahtml, const char * Anames[], char * Avalues[], const Tlpv Alpv[], const uint32_t Acountlpv)
  25. {
  26.     uint32_t i;
  27.     int32_t in;
  28.     for (i = 0;i < Acountlpv;i++)
  29.     {
  30.  
  31.         in = Alpv[i].indxnamevar;
  32.         if (in == -1)
  33.         {
  34.             Aserver.sendContent_P(&Ahtml[Alpv[i].begindx], (Alpv[i].endindx - Alpv[i].begindx) + 1);
  35.         }
  36.         else
  37.         {
  38.             if (Avalues[in] != nullptr)
  39.             {
  40.                 uint32_t ls = strlen_P(Avalues[in]);
  41.                 uint32_t l = strlen_P(Anames[in]);
  42.  
  43.                 if (ls >= l)
  44.                 {
  45.                     Aserver.sendContent_P(Avalues[in], ls);
  46.                 }
  47.                 else if (ls < l)
  48.                 {
  49.                     Aserver.sendContent_P(Avalues[in], ls);
  50.                     Aserver.sendContent_P(&spaces[0], l - ls);
  51.                 }
  52.             }
  53.             else
  54.             {
  55.                 uint32_t l = strlen_P(Anames[in]);
  56.                 Aserver.sendContent_P(&spaces[0], l);
  57.             }
  58.         }
  59.     }
  60. }

xbutil.h
  1. #ifndef _XBUTIL_h
  2. #define _XBUTIL_h
  3.  
  4. #if defined(ARDUINO) && ARDUINO >= 100
  5.     #include "arduino.h"
  6. #else
  7.     #include "WProgram.h"
  8. #endif
  9.  
  10. #include <ESP8266WiFi.h>
  11. #include <ESP8266WebServer.h>
  12.  
  13. typedef const char THtmlStr_;
  14. #define THtmlStr ICACHE_RODATA_ATTR THtmlStr_
  15.  
  16. typedef struct {
  17.     uint32_t begindx;
  18.     int32_t indxnamevar;
  19.     uint32_t endindx;
  20. } Tlpv;
  21.  
  22. #define SETVAR(Anamedoc,Anamevar,Avalue) SetValueVar(Anamevar,Avalue,Anamedoc##_varnames,Anamedoc##_varvalues,Anamedoc##_varcount)
  23. #define SETVARI(Anamedoc,Anamevar,Avalue) SetValueVar(Anamedoc##_##Anamevar,Avalue,Anamedoc##_varvalues)
  24. #define SEND(Anamedoc)  server_sendContent(server,Anamedoc##_htm,Anamedoc##_varnames,Anamedoc##_varvalues,Anamedoc##_lpv,Anamedoc##_lpvcount)
  25.  
  26. extern void ICACHE_FLASH_ATTR SetValueVar(const char *Anamevar, const char *Avalue, const char * Anames[], char * Avalues[], uint32_t Acount);
  27. extern void ICACHE_FLASH_ATTR  SetValueVar(const uint32_t Aindxvar, const char *Avalue, char * Avalues[]);
  28. extern void ICACHE_FLASH_ATTR server_sendContent(ESP8266WebServer &Aserver,const char *Ahtml, const char * Anames[], char * Avalues[], const Tlpv Alpv[], const uint32_t Acountlpv);
  29.  
  30. #endif
I tak powinno wyglądać drzewo projektu:

Obrazek

Jeszcze zanim tak to będzie wyglądało należy wygenerować inklude index_htm.h z dokumentem HTML. Uruchamiamy XBConvertTool,
przechodzimy do dokumentu index.htm i zapisujemy ( jeśli już był zapisywany to należy wstawić spacje po to żeby odbył się zapis).
Następnie tą inkludę wygenerowaną dodajemy do projektu.
Całość powinna się dać skompilować, i po załadowaniu do ESP8266 będziemy mieli dostępną sieć "SunDuinoEXAM" zabezpieczoną
hasłem: "12345678" (bez cudzysłowów) pod adresem 192.168.4.1 będziemy widzieć wynik naszej ciężkiej pracy.

Teraz chcąc coś zmienić, dopisać w index.htm wystarczy po zmianach zapisać i w tle uruchomiony XBConvertTool automatycznie
przekonwertuje do inkludy i można kompilować oraz załadować do ESPa nasz kod.

Program XBConvertTool będzie na pewno modyfikowany oraz będą poprawiane błędy, i na pewno będzie się tu pojawiać nowe wersje.
To by było na tyle tego skrótowego opisu, mam nadzieje jak zdrowie pozwoli rozpiszę się na temat jak zbudować własny szablon.

Obrazek


https://raw.githubusercontent.com/xbary ... rtTool.exe
ODPOWIEDZ

Wróć do „Jaskinia Xbarego”