ECS Build/Design Document

Build ECS from sources (for Windows/Linux):
  PC Setup
Design notes

PC Setup:

  1. Install 7Zip

  2. Download ECSSources.dlm into any folder
    NOTE: This .dlm is actually a .7z file. It was renamed to evade DreamHost's Acceptable Use Policy (they don't like "personal backups" on server)
    Rename ECSSources.dlm to ECSSources.7z
    Extract ECSSources.7z

  3. Move the (resulting) \Mark and \Installs folders to C:\ (i.e. C:\Mark and C:\Installs)

  4. Install Inno: C:\Installs\Inno (Win software installer)\isetup-5.4.3.exe
    Note: "Inno Setup Preprocessor" is not required.

  5. Install Jpeg for Windows: C:\Installs\jpegs\jpeg-6b-4.exe (from

  6. Install MySQL for Windows: C:\installs\MySQL\mysql-8.0.29-winx64.msi (from

  7. Install Visual Studio Community
     The C++ option is all that's needed.
     If the "Submit"(?) button is off-screen, press <Enter> to continue.

  8. Setup Linux/Debian (to run in Windows):

    1. Start CMD

    2. Install the Ubuntu Windows Subsystem for Linux:
      wsl --update
      wsl --install
      IMPORTANT:If you run into trouble and need to re-install, assure that Windows deletes all data when you uninstall
      (else some old Linux files will remain in the new install - which can cause havoc!!).
      Select the app, click "Advanced options", and "Reset"

    3. Start CMD, and enter:

    4. Enter:
        chmod +x *.sh
        sudo passwd
        {enter desired password}
        sudo ./

    5. Build/install OpenSSL:
      OpenSSL (for "https://" support) is optional (but enabled by default). To disable ssl support, remove " -DMYOPENSSL in c:\mark\
      These steps were determined per OpenSSL Compilation and Installation:
      1. Download openssl-3.0.11.tar.gz to c:\mark
      2. Start CMD and Enter:
         cd \mark
         tar xvfz openssl-3.0.11.tar.gz
         cd openssl-3.0.11
         make depend
         sudo make install
        (takes a while)
         cd ..


If ECSSources.7z has been updated since the last build:

  1. Rename (or delete) the existing \Mark and \Installs folders

  2. Download/extract ECSSources.7z into any folder
    Rename ECSSources.dlm to ECSSources.7z
    Extract ECSSources.7z

  3. Move the (resulting) \Mark and \Installs folders to C:\ (i.e. C:\Mark and C:\Installs)

  4. Start CMD, and enter:
      CD \MARK
      chmod +x *.sh

Build all libraries/executables (windows and linux): BuildAll.bat (run in C:\Mark)
 Build all libraries/executables (windows): BuildAllForWindows.bat (run in C:\Mark)
 Build all libraries/executables (linux): (run in C:\Mark)

Build distros: BuildAllDistros.bat (run in C:\Mark)
  Resulting distros:

  Omnipotence ( / 423-368-2339):
  ECS_SETUP.exe (ECS/Windows)
  ecs.tar.gz (ECS/Linux)

Install instructions

Design notes

ALL files created/maintained are standard ASCII text files (vs binary files, which can't be easily inspected by a person).

ECS uses char[] arrays/pointers inst of std::string - which proved significantly faster per *past* benchmarks.
But recent benchmarks show that speeds are comparable (due to std::string class enhanements).
std::strings can more convenient - esp as they support operators: e.g. st += "12345" vs st = AppSt(st, "12345");
Regardless, the exclusive use of char[] allows us to use a *single* data type for all byte-array data (text strings, file buffers, image data, etc).
It also allow us to monitor memory usage (as all char[] pointers are allocated/freed via *our* rtns - e.g. AllocU1, FreeSP).

ECS is "single threaded" but for network connection requests (which are done via ascynrounous threads).
The main advantage to this approach is *predictabilty* (if a test fails, it will fail the same way ever time).
The disadvantage is that object service rtns must do what work can be done *at the moment*,
save any context info related to incomplete/in-progess tasks (so they can be resumed on the next call),
and return control to ECS asap.

Web pages (generated by the ECS web server) contain javascript code which communicates with ECS via websockets
This code is defined in sections "part0_js" to "part17_js" (in ECS.c).
I had to break it up into sections due to the C++ limitation on the size of text strings.

I've dedicated many hours tweaking/benchmarking the memory allocation, file I/O, and text search/replace functions.

I believe them to be as fast as possible.

Naming conventions (in rtn/arg names):
Bf Buffer: char[] array or pointer
St String: char[] array of text (terminated by NULL)
SP String Pointer: Allocated char array of text (terminated by NULL)

Memory Allocation:
All memory allocation/free operations are done by my functions (AllocU1/FreeSP/ReplaceSP in mem_lb.c) ("SP" is String Pointer).
They use malloc()/free() functions (vs "new" / "delete" operators).
Routing all memory allocation tasks thru these rtns allows us to track the amount of memory allocated (persistent and dynamic) and detect memory leaks.
AllocU1() allocates a structure ("MEMDSC") that lies before the pointer returned.
This structure defines the allocated size, a dynamic flag (vs persistent), and an optional index into the LPMA pointer array (if applicable - see below).
FreeSP/ReplaceSP access this structure by simply subtracting the size of MEMDSC from the passed pointer.
Loop memory denotes temporary buffers (as returned by various functions) that are freed at the top of the main pgm loop (among other places):
Loop Memory / Internal: LPMI buffers are defined in a static/fixed-length array (super fast). These are used for limited-size buffers when available.
Loop Memory / Allocated: LPMA pointers are stored in an array. This is for buffers that are too large for LPMI (or if no LPMI buffers are available)
Internal Transitory Memory: ITM buffers are defined in a static/fixed-length array (like LPMI). These are used for temporary buffers that will be freed at some point (such as FIFO data)

Z Lists:
ECS uses "Z Lists" (ZL) extensively.
These allow *very* large/flexible lists to be defined with minimal data - e.g.:

	static U1	*zl_misc_choices[] = {
		"Off, On, Unknown",		// Off, On, Unknown
		"0...5",			// 0, 1, 2, 3, 4, 5
		"0...10+2",			// 0, 2, 4, 6, 8, 10 ("+2" denotes an increment of 2)
		"0.0...0.5",			// 0.0, 0.1, 0.2, 0.3, 0.4, 0.5
		"Sunday...Saturday",		// Sunday, Monday, . . . Saturday
		"1/1...12/31",			// 1/1, 1/2, . . . 12/31
		"12:00 AM...12:05 AM",		// 12:00 AM, 12:01 AM, 12:02 AM, 12:03 AM, 12:04 AM, 12:05 AM
		"12:00:00 AM...12:00:05 AM",	// 12:00:00 AM, 12:00:01 AM, 12:00:02 AM, 12:00:03 AM, 12:00:04 AM, 12:00:05 AM
		"00:00...00:05/TMC",		// minute-counts: 00:00, 00:01, 00:02, 00:03, 00:04, 00:05
		"00:00:00...00:00:05/TMC",	// second-counts: 00:00:00, 00:00:01, 00:00:02, 00:00:03, 00:00:04, 00:00:05
The primary VLST rtns are:
ZLText_LPM: Returns the choice for an index
ZLIndex: Returns the index of a choice

Logic flow:
 start init.htm in the default browser (the page that says "ECS initializing (please wait) . . .")
  this page refreshes itself every 5 seconds
 read main.cfg and construct the objects therein
 re-create init.htm such that it displays the ECS "Home" page
  init.htm will subsequently refresh itself and display "Home"
  the javascript therein will then connect to ECS (via a websocket), and "subscribe" to the Properties in the page.
  it subsequently requests updates (e.g. Property value changes) every 1/2 second
 do until exit
  service all objects (incl scripts)
  service all sockets (respond to http web page requests, and update requests from websockets)

NOTE: All .C sources are actually C++ (whose convential extension is ".CPP").
File Description
\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.30.30704\x86\Microsoft.VC143.CRT\msvcp140.dll Visual C++ Redistributable for Visual Studio 2015 (
\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.30.30704\x86\Microsoft.VC143.CRT\vcruntime140.dll Visual C++ Redistributable for Visual Studio 2015 (
\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64\Xinput9_1_0.lib for XBox360Controller Class (Windows 10 SDK, version 2004 (10.0.19041.0)
\installs\winddk\3790.1830\lib\wxp\i386\hid.lib for PowerLinc Classes
\Installs\GNUPlot\gp527-win32-mingw\gnuplot\bin\*.dll for DataPlot Class
\installs\GNUPlot\gp527-win32-mingw\gnuplot\bin\gnuplot.exe for DataPlot Class
\installs\Inno (Win software installer)\* creates Windows ECS installer (ECS_SETUP.exe)
\Program Files (x86)\GnuWin32\bin\jpeg62.dll for Windows Image.Compare and "internal" camera motion detection (i.e. done manually by ECS)
\installs\jpegs\jpeg-6b\libjpeg.a for Linux Image.Compare and "internal" camera motion detection (i.e. done manually by ECS)
\installs\MySQL\* Windows/Linux MySQL installers (for MySQLDataBase Class)
\Program Files (x86)\MySQL\MySQL Connector C++ 8.0\lib\libssl-1_1.dll
\Program Files (x86)\MySQL\MySQL Connector C++ 8.0\lib\libcrypto-1_1.dll C:\Program Files (x86)\MySQL\MySQL Connector C++ 8.0\lib\libcrypto-1_1.dll
\Installs\canvas-gauges-master\* for Gauge3 Widgets
\Installs\ImageMagick\identify.exe used to determine image file height/width (
\Installs\LAME\lame3.100.1-x64\lame.exe lame file compressor
\Installs\mailsend\mailsend.exe for EMail Class (default emailer for windows) (
\Installs\Postie (emailer)\postie.exe for EMail Class (alternate emailer for Windows) (
\Installs\SNMP\snmpget.exe for SNMPObject Class
\Installs\SNMP\snmpset.exe for SNMPObject Class
\Installs\SQLite\sqlite3.exe for SQLiteDataBase Class
\installs\OpenSSL\openssl-1.1.1\Include for HTTPS (SSL) support (Windows)
\installs\OpenSSL\openssl-master\include for HTTPS (SSL) support (Windows)
\installs\OpenSSL\openssl-master\libssl_static.lib for HTTPS (SSL) support (Windows)
\installs\OpenSSL\openssl-master\libcrypto_static.lib for HTTPS (SSL) support (Windows)
\installs\OpenSSL\openssl-master\libcrypto-3.dll for HTTPS (SSL) support (Windows)
\mark\*.gui custom Class GUIs (e.g. weather.gui)
\mark\*.widget* widget defs
\mark\*ModBusDeviceMap.txt modbus device register maps
\mark\IncludeExclude.c Includes desired lines (in a text file) and removes undesired lines (per tags)
\mark\ActivateWindow.c used by ActivateWindow() to bring window to foreground (when running as daemon)
\mark\ActivityLogModifiers.txt denotes the Classes that are to trigger Activity logging when THEY make a change
\mark\ActivityLogProperties.txt denotes the Properties that are to trigger Activity logging when they are modified
\mark\alarm1.wav alarm sound
\mark\array_lb.c array/symbol rtns
\mark\bacrp reads BACNET value (linux)
\mark\bacrp.exe reads BACNET value (windows)
\mark\bacwp writes BACNET value (linux)
\mark\bacwp.exe writes BACNET value (windows)
\mark\base64_lb.c BASE64 encode/decode rtns (for images and passwords to/from web pages)
\mark\bell.wav alarm sound
\mark\BuildAll.bat build libraries and pgms (windows & linux)
\mark\BuildAllDistros.bat build all distros
\mark\ build all linux distros
\mark\BuildAllDistrosForWindows.bat build all windows distros
\mark\ build libraries and pgms (linux)
\mark\BuildAllForWindows.bat build libraries and pgms (windows)
\mark\ build linux install (ecs.tar.gz)
\mark\cc.bat compile C++ source (windows / console)
\mark\ compile C++ source (linux)
\mark\ccl.bat compile/link C++ source (windows / console)
\mark\ compile/link C++ source (linux)
\mark\cclall.bat compile/link C++ source (windows & linux)
\mark\cclw.bat compile/link C++ source (windows)
\mark\ccw.bat compile C++ source (windows)
\mark\click.mp3 click sound (for use in web pages)
\mark\clipboard_lb.c clipboard rtns
\mark\colors.htm hex color map
\mark\comio.c COM (serial) I/O testing utility
\mark\com_lb.c "COM" (serial) I/O rtns
\mark\console_lb.c Console (e.g. keyboard/terminal) I/O rtns
\mark\conversions_lb.c Conversion rtns (integer to text, etc)
\mark\cr.bat compile and replace in ut.lib library (windows)
\mark\ compile and replace in ut.a library (linux)
\mark\CreateService.c creates windows servce (daemon) for ECS
\mark\DogBark.wav alarm sound
\mark\ecs.c "main" source (also includes javascript data/functions defined via text strings)
\mark\ecs.htm "source" file for manual.htm (see ECSManual.bat)
\mark\ECS.ISS INNO (windows) install file
\mark\ecs.manifest ??
\mark\ecs.service Linux service file (64 bit)
\mark\ECSAPI.c Reads or writes an ECS Property via API command (command-line pgm)
\mark\ecsb.bat build all executables (windows & linux)
\mark\ECSBuildAndDesignNotes.htm This build/design document
\mark\ECSErrTray.ico windows pgm tray icon (when new errors have been logged)
\mark\ECSFavicon.ico pgm icon (appears in browser tab). Copied to favicon.ico on install
\mark\ECSIB.bat build windows/linux installations (ECS_SETUP.exe / ecs.tar.gz)
\mark\ECSLogo.png company logo
\mark\ECSManual.bat Builds manual.htm from ecs.htm
\mark\ECSTray.ico windows pgm tray icon (when no new errors have been logged)
\mark\edm.bin mark's text-file editor (linux64)
\mark\edm.c mark's text-file editor source
\mark\edm.exe mark's text-file editor (windows)
\mark\edm.txt mark's text-file editor help file
\mark\Elkm1Events.txt for ELK-M1 Classes
\mark\error.mp3 error sound file (played in browser)
\mark\error.wav alarm sound
\mark\exec_lb.c rtns for executing/monitoring external processes
\mark\ExternalLogProperties.txt denotes Properties that are considered "external" to PC. All changes to such Properties are logged to ExternalChanges.log
\mark\ffmpeg.exe used to convert camera images to videos (
\mark\ffplay.exe used by FFPlayFile() to play audio files (
\mark\file_lb.c File I/O rtns (incl MRF:Memory-Resident-Files)
\mark\fnd_lb.c find(search) / string match / parsing rtns
\mark\ftpx.c ftp upload/download/delete pgm (used by FTPClient Class)
\mark\GardIn.cfg GardIn demo cfg
\mark\HABridge.json used by IFTTT (may work for some existing users, but no longer supported)
\mark\HeartbeatMonitor.c monitors a process "heartbeat" and restarts it no heartbeat detected after n seconds
\mark\holidays.txt US holidays (used by Clock.Date Property)
\mark\HubitatDriverCapabilities.txt used by HubitatDevice Class
\mark\inpfld_lb.c (user) input "field" rtns (used only by mark's pgms - NOT used by ECS)
\mark\ installs packages used by ecs
\mark\ installs packages (in Debian Windows Subsystem for Linux) used to build ECS/Linux in windows
\mark\jpeg_lb.c jpeg rtns
\mark\justgage.js Gauge2 widget
\mark\kb_lb.c Keyboard I/O rtns
\mark\lm.exe mark's directory list pgm (similar to "dir" and "ls")
\mark\lnk.bat link a pgm (windows / console)
\mark\ link a pgm (linux)
\mark\lnkw.bat link a pgm (windows)
\mark\log_lb.c log/error-processing rtns
\mark\main.cfg default ECS configuration
\mark\manual.htm ECS users manual
\mark\mem_lb.c memory/etc rtns
\mark\misc_dt.c misc/global variables/arrays
\mark\MobileAgents.txt mobile http agents+info
\mark\modbus.h modbus packet structures
\mark\mp3_lb.c mp3 rtns (used only by mark's pgms - NOT used by ECS)
\mark\mysql-connector-c++-8.0.29-src\* MySQL includes (for windows build)
\mark\mysqlcppconn-9-vs14.lib MySQL library (for windows build)
\mark\network_lb.c network (ethernet, TCP/IP) rtns
\mark\NOAAAlertZones.txt NOAA Alert Zones (used by Weather Class)
\mark\notice.htm user notice (used in main.cfg)
\mark\omnipotence_logo.jpg omnipotence logo
\mark\os_vsn.c OS info rtn
\mark\pausex.exe pause pgm for use in batch files: arg1=prompt, arg2=timeout (in seconds)
\mark\PrintFileNameIfNewerThanOthers.exe used by cc*.bat (windows) to ignore compile if object is newer than source
\mark\ProblemReport0.htm problem report form
\mark\PropertyHelp.c creates Property Help (hover text) for every Property (as extracted from manual.htm)
\mark\PropertyHelp.txt Property Help (hover text) for every Property
\mark\raphael-2.1.4.min.js used by Dial2*.widget and Gauge2*.widget
\mark\reboot.bat used by Program Class to reboot PC (when set to "Reboot")
\mark\ used by Program Class to reboot PC (when set to "Reboot")
\mark\ReplaceTextInFile.c replace text in a file
\mark\ReplaceTextInFile.exe replace text in a file
\mark\rev.c updates ecs cfgs to current revision
\mark\rev.htm revision history
\mark\server.crt for HTTPS support
\mark\server.key for HTTPS support
\mark\SimKey.c Emulates keystroke or mouse activity (windows). Used by Window.Key Property
\mark\snmp_lb.c SNMP (Simple Network Management Protocol) rtns
\mark\snmp_trap_linux.cfg Example cfg for trapping SNMP in Linux
\mark\sound_lb.c Sound-related rtns
\mark\sqlite3.c SQLite3 library. Used by SQLDataBase Class (
\mark\sqlite3.h SQLite3 library header. Used by SQLDataBase Class (
\mark\sql_lb.c SQLite3/MySQL rtns
\mark\stdout_capture.c Used by CC.BAT/etc to capture compile output and check for errors
\mark\stdout_capture.exe Used by CC.BAT/etc to capture compile output and check for errors
\mark\styles.css CSS styles used by ECS pages
\mark\sun_calc.c Used to calc sun rise/set times per latitude/longitude/zone/year/month/mday
\mark\sun_calc2.c Used to calc dawn/dusk times per latitude/longitude
\mark\sys.h Misc constants
\mark\time_lb.c Time-related rtns
\mark\TrayIcon.exe Supports tray icon when ECS is running as a service
\mark\tts_lb.c Text-To-Speech rtns
\mark\tts_lexicon.txt Denotes text/words which must be "re-spelled" in order to be pronounced properly by the text-to-speech. Also expands some abbreviations (e.g. TX -> Texas)
\mark\ Used in updating ECS
\mark\ut.h Global rtn/data declarations
\mark\utb.bat build ut.lib (windows)
\mark\ build ut.lib (linux)
\mark\ValueListIgnore.txt Denotes which Classes/Names/Properties/values are to be omitted from the ValueList file (used by Program.ValueList)
\mark\vlc_lb.c VLC (media player) rtns
\mark\vlst_lb.c VLST (Virtual List) rtns (used extensively by ECS)
\mark\W800.btn W800 buttons (used by W800 Class)
\mark\W800.chc W800 values (used by W800 Class)
\mark\webcam_lb.c WebCam rtns
\mark\webdl.c WWW file download pgm
\mark\Widget*Decl.txt Widget declarations
\mark\WidgetDefaults.txt Denotes default widget for various Properties
\mark\WidgetHelp.htm HTML showing WidgetHelp.png
\mark\WidgetHelp.png Image showing various widgets/formats
\mark\WidgetImages\* Widget images (bulbs, floodlights, switches, etc)
\mark\win_lb.c Windows-specific rtns
\mark\ZipcodeInfo.txt US zip codes info (used by Clock and Weather Classes)
\mark\ZipCodes.chc US zip codes (used by Clock and Weather Classes)
\mark\zl_lb.c ZL library (see above)