Sat, 19 Aug 2023 15:11:35 +0200
De iSpindel plato berekening is in het webscript gezet omdat er dan met meer cijfers achter de komman gerekend wordt. De uitkomst verschilt 0.25 plato! De calibratie is nu dus extern.
/** * @file bms.h */ #ifndef _BMS_H #define _BMS_H #define _GNU_SOURCE // for secure_getenv() #include "../config.h" #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/un.h> #include <sys/utsname.h> #include <pwd.h> #include <time.h> #include <fcntl.h> #include <syslog.h> #include <unistd.h> #include <errno.h> #include <signal.h> #include <getopt.h> #include <limits.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> #include <poll.h> #include <dirent.h> #include <uuid/uuid.h> #include <math.h> #include <assert.h> #include <libgen.h> #include <pthread.h> #include <libxml/xmlmemory.h> #include <libxml/parser.h> #include <libxml/encoding.h> #include <libxml/xmlwriter.h> #include <mosquitto.h> #ifdef HAVE_MYSQL_MYSQL_H #include <mysql/mysql.h> #endif #ifdef HAVE_MARIADB_MYSQL_H #include <mariadb/mysql.h> #endif #include <json-c/json.h> #define MBSE_SS(x) (x)?(x):"(null)" #define MQTT_NODE_CONTROL 0x0001 ///< Show node control #define LOWBATT 3.3 ///< Low battery voltage /** * @brief Configuration structure. Stored in a flat ascii file ~/.bms/bms.config */ typedef struct _sys_config { char *bms_name; ///< Brewery name char *bms_uuid; ///< Brewery uuid char *mysql_host; ///< MySQL host int mysql_port; ///< MySQL port char *mysql_user; ///< MySQL user name char *mysql_pass; ///< MySQL password char *mysql_database; ///< MySQL database char *mqtt_host; ///< MQTT host int mqtt_port; ///< MQTT port char *mqtt_user; ///< MQTT username of NULL char *mqtt_pass; ///< MQTT password of NULL char *web_root; ///< WWW root directory int websocket_port; ///< Websocket port } sys_config; /** * @brief Structure for the nodes. Database table 'mon_nodes'. */ typedef struct _sys_node_list { struct _sys_node_list *next; char *uuid; ///< uuid string char *node; ///< nodename bool online; ///< on-line state char *group_id; ///< group type char *hardwaremake; ///< hardware make char *hardwaremodel; ///< hardware model char *os; ///< os type char *os_version; ///< os version char *firmware; ///< application version time_t firstseen; ///< First seen this session time_t lastseen; ///< Last seen this session float temperature; ///< environment temperature float humidity; ///< environment humidity float barometer; ///< environment barometer pressure float gps_latitude; ///< GPS latitude float gps_longitude; ///< GPS longitude float gps_altitude; ///< GPS altitude char *net_address; ///< IPv4 or IPv6 address char *net_ifname; ///< Interface name int net_rssi; ///< RSSI value if wireless. int interval; ///< Update interval char *net_ssid; ///< WiFi SSID } sys_node_list; /** * @brief Fermenting profile steps */ typedef struct _prof_step { struct _prof_step *next; int steptime; ///< Step time to target in hours int resttime; ///< Rest time on target in hours float target_lo; ///< Low Target temperature float target_hi; ///< High target temperature int fridge_mode; ///< Fridge or beer mode } prof_step; typedef enum { FERMENTER_MODE_OFF = 0, ///< Fermenter is off. FERMENTER_MODE_NONE, ///< Fermenter on but does nothing. FERMENTER_MODE_FRIDGE, ///< Fermenter acts as a fridge. FERMENTER_MODE_BEER, ///< Fermenter acts as beer cooler. FERMENTER_MODE_PROFILE, ///< Fermenter runs in profile mode. } FERMENTER_MODE; typedef enum { FERMENTER_STAGE_PRIMARY = 0, ///< Fermentation primage stage. FERMENTER_STAGE_SECONDARY, ///< Fermenter secondary stage. FERMENTER_STAGE_TERTIARY, ///< Fermenter tertiary stage. FERMENTER_STAGE_CARBONATION, ///< Fermenter carbonation stage. } FERMENTER_STAGE; typedef enum { DEVPRESENT_UNDEF = 0, ///< Precence not detectable. DEVPRESENT_NO, ///< Device is missing. DEVPRESENT_YES, ///< Device is present and Ok. DEVPRESENT_ERROR, ///< Device is present but in error state. } DEVPRESENT_STATE; typedef enum { ALARM_FLAG_DOOR = 0x0001, ///< Door open ALARM_FLAG_PSU = 0x0002, ///< PSU problem ALARM_FLAG_BATTERY = 0x0004, ///< Low battery ALARM_FLAG_CHILLER = 0x0100, ///< Chiller too warm } ALARM_FLAGS; /** * @brief Structure for the fermenters. Stored in database table 'mon_fermenters'. */ typedef struct _fermenter_list { struct _fermenter_list *next; char *uuid; ///< Fixed uuid string char *alias; ///< Fixed short name char *node; ///< Fixed node name bool online; ///< Online status char *beercode; ///< Beer unique code char *beername; ///< Beer name in fermenter char *beeruuid; ///< Beer uuid in fermenter char *air_address; ///< Air sensor address char *air_state; ///< Air sensor state float air_temperature; ///< Air temperature char *beer_address; ///< Beer sensor address char *beer_state; ///< Beer sensor state float beer_temperature; ///< Beer temperature char *chiller_address; ///< Chiller sensor address char *chiller_state; ///< Chiller sensor state float chiller_temperature; ///< Chiller temperature char *heater_address; ///< Heater address int heater_state; ///< Heater state uint64_t heater_usage; ///< Heater usage char *cooler_address; ///< Cooler address int cooler_state; ///< Cooler state uint64_t cooler_usage; ///> Cooler usage char *fan_address; ///< Fan address int fan_state; ///< Fan state uint64_t fan_usage; ///< Fan usage char *light_address; ///< Light address int light_state; ///< Light state uint64_t light_usage; ///< Light usage char *door_address; ///< Door address int door_state; ///< Door state char *psu_address; ///< PSU address int psu_state; ///< PSU state char *mode; ///< Fermenter mode char *stage; ///< Fermentation stage uint32_t alarm; ///< Alarm flag float setpoint_high; ///< Setpoint high float setpoint_low; ///< Setpoint low char *profile_uuid; ///< Profile uuid char *profile_name; ///< Profile name char *profile_state; ///< Profile state int profile_percent; ///< Profile percent done float profile_inittemp_high; ///< Profile init temp high float profile_inittemp_low; ///< Profile init temp low char *profile_steps; ///< Profile steps in JSON float yeast_lo; ///< Yeast minimum temperature float yeast_hi; ///< Yeast maximum temperature char *webcam_url; ///< Webcam url to the stream int webcam_light; ///< Webcam control lights } sys_fermenter_list; typedef enum { PROFILE_OFF = 0, ///< Profile not active PROFILE_PAUSE, ///< Profile pause PROFILE_RUN, ///< Profile is running PROFILE_DONE, ///< Profile is finished PROFILE_ABORT, ///< Profile abort } PROFILE_STATE; /** * @brief Strcuture holding a fermentation log entry. */ typedef struct fermenting_log { char *datetime; ///< Date/time stamp char *product_uuid; ///< Product uuid char *product_code; ///< Product code char *product_name; ///< Product name float temperature_air; ///< Temperature air float temperature_beer; ///< Temperature beer float temperature_chiller; ///< Temperature chiller (if pressent) float temperature_room; ///< Temperature room int heater_power; ///< Heater power 0..100 uint64_t heater_usage; ///< Heater usage counter in seconds. int cooler_power; ///< Cooler power 0..100 uint64_t cooler_usage; ///< Cooler usage counter in seconds. int fan_power; ///< Fan power 0 or 100 uint64_t fan_usage; ///< Fan usage counter in seconds float setpoint_low; ///< Target temperature low float setpoint_high; ///< Target temperature high char *mode; ///< Working mode. char *stage; ///< Fermentation stage char *event; ///< Optional event char *fermenter_uuid; ///< Fermenter in use char *fermenter_node; ///< Fermenter node char *fermenter_alias; ///< Fermenter_alias } fermentation_log; /** * @brief Structure for the co2meters. Stored in database table 'mon_co2meters'. */ typedef struct _co2meter_list { struct _co2meter_list *next; char *uuid; ///< Fixed uuid string char *alias; ///< Fixed short name char *node; ///< Fixed node name bool online; ///< Online status char *mode; ///< Working mode uint32_t alarm; ///< Alarm bits char *beercode; ///< Beer unique code char *beername; ///< Beer name in fermenter char *beeruuid; ///< Beer uuid in fermenter char *temperature_state; ///< Temperature sensor state char *temperature_address; ///< Temperature sensor address float temperature; ///< Temperature value char *pressure_state; ///< Pressure sensor state uint8_t pressure_channel; ///< Pressure sensor channel float pressure_voltage; ///< Pressure voltage reading float pressure_zero; ///< Pressure zero offset voltage float pressure_bar; ///< Pressure in bar } sys_co2meter_list; /** * @brief Structure holding a co2 pressure log entry. */ typedef struct co2meter_log { char *datetime; ///< Date/time stamp char *product_uuid; ///< Product uuid char *product_code; ///< Product code char *product_name; ///< Product name float temperature; ///< Temperature float pressure; ///< Pressure char *uuid; ///< Unit uuid char *node; ///< Unit node char *alias; ///< Unit alias } co2pressure_log; /** * @brief Brew computer controllers. Must have hardware + installation + recipe data. */ typedef struct _brewer_list { struct _brewer_list *next; char *uuid; } brewer_list; /** * @brief Structure for the iSpindels. Stored in database table 'mon_ispindels'. */ typedef struct _ispindel_list { struct _ispindel_list *next; char *uuid; ///< Fixed uuid string. char *alias; ///< Alias name. char *node; ///< Node name received. bool online; ///< Is considered online. char *mode; ///< Working mode OFF or ON. uint32_t alarm; ///< Alarm flags. char *beercode; ///< Beer unique code char *beername; ///< Beer name being measured char *beeruuid; ///< Beer uuid being measured float angle; ///< Tilt angle in degrees float temperature; ///< Temperature in C float battery; ///< Battery voltage float gravity; ///< Gravity in Plato int interval; ///< Measure interval float og_gravity; ///< OG gravity in Plato detected float yeast_lo; ///< Yeast low temperature limit float yeast_hi; ///< Yeast high temperature limit } sys_ispindel_list; #endif