thermferm/thermferm.h

Thu, 10 Jan 2019 16:33:42 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 10 Jan 2019 16:33:42 +0100
changeset 569
9c69d43bfb06
parent 564
3fc61dd28656
child 570
1e0192b295b9
permissions
-rw-r--r--

Version 0.9.0. Implemented DCMD via mqtt to set stage, mode, setpoint low and high. Implemeted DCMD via mqtt to set heater, cooler, fan and light state. Implemented DCMD via mqtt to set product code and name. Set the PID's in fridge mode without idle range offset, that was an old leftover setting that was obsolete.

#ifndef	_MBSELIB_H
#define	_MBSELIB_H


#define TRUE 1
#define FALSE 0

#include "../config.h"
#include "pid.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 <ifaddrs.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 <json-c/json.h>
#ifndef HAVE_WIRINGPI_H
#include <pthread.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include <mosquitto.h>

#ifdef HAVE_WIRINGPI_H
/* wiringPi */
#include <wiringPi.h>
#include <pcf8574.h>
#include <lcd.h>


/*
 * Thread locks
 */
#define	LOCK_DEVICES		0
#define	LOCK_LCD		1
#define	LOCK_MENU		2
#define	LOCK_SPARE2		3

#endif


/*
 * Frontpanel menu numbers
 */
#define MENU_NONE       	0
#define MENU_TOP_DEFAULT       	1
#define	MENU_TOP_UNITS		2
#define	MENU_UNITS		21
#define MENU_MODE_OFF		211
#define	MENU_MODE_NONE		212
#define MENU_NONE_HEAT          2121
#define MENU_NONE_COOL          2122
#define MENU_NONE_FAN           2123
#define MENU_MODE_BEER		213
#define MENU_BEER_TEMP          2131
#define MENU_MODE_FRIDGE	214
#define MENU_FRIDGE_TEMP	2141
#define MENU_MODE_PROFILE	215
#define	MENU_PROFILE_SELECT	2151
#define	MENU_PROFILE_START	2152
#define	MENU_PROFILE_PAUSE	2153
#define	MENU_PROFILE_ABORT	2154
#define	MENU_PROFILE_RESUME	2155
#define	MENU_PROFILE_GOOFF	2156
#define	MENU_TOP_SYS		3
#define	MENU_SYS_HALT		31
#define	MENU_SYS_REBOOT		32



/*
 * 1-Wire devices
 */
#define W1_FAMILY_DEFAULT       0
#define W1_FAMILY_SMEM_01       0x01
#define W1_FAMILY_SMEM_81       0x81
#define W1_THERM_DS18S20        0x10
#define W1_FAMILY_DS28E04       0x1C
#define W1_COUNTER_DS2423       0x1D
#define W1_THERM_DS1822         0x22
#define W1_EEPROM_DS2433        0x23
#define W1_THERM_DS18B20        0x28
#define W1_FAMILY_DS2408        0x29
#define W1_EEPROM_DS2431        0x2D
#define W1_FAMILY_DS2760        0x30
#define W1_FAMILY_DS2780        0x32
#define W1_FAMILY_DS2413        0x3A
#define W1_THERM_DS1825         0x3B
#define W1_FAMILY_DS2781        0x3D
#define W1_THERM_DS28EA00       0x42



#define MBSE_SS(x) (x)?(x):"(null)"


/*
 * Fermenter units. These units are connected via the 1-wire bus.
 * Each unit can have:
 *  a DS18B20 sensor to measure the air temperature inside the unit.
 *  a DS18B20 sensor(s) to measure the beer temperature.
 *  a DS2408 to turn the cooler, heater and fans on or off. Sense door and PSU state.
 */
typedef struct _units_list {
    struct _units_list	*next;
    int			version;		/* Record version		*/
    char		*uuid;			/* uid code			*/
    char		*product_uuid;		/* Beer product uuid		*/
    char		*product_code;		/* Beer product code		*/
    char		*product_name;		/* Beer product name		*/
    char		*alias;			/* alias name 'unit1'		*/
    float		volume;			/* Volume of this unit		*/
    char		*air_address;		/* DS18B20 address		*/
    int			air_state;		/* 0=ok, 1=missing, 2=error	*/
    int			air_temperature;	/* Air temperature in C * 1000	*/
    int			air_idx;		/* Domoticz idx			*/
    char		*beer_address;		/* DS18B20 address		*/
    int			beer_state;		/* 0=ok, 1=missing, 2=error 	*/
    int			beer_temperature;	/* Beer temperature in C * 1000	*/
    int			beer_idx;		/* Domoticz idx			*/
    char		*chiller_address;	/* DS18B20 address		*/
    int			chiller_state;		/* 0=ok, 1=missing, 2=error	*/
    int			chiller_temperature;	/* Chiller temp. in C * 1000	*/
    int			chiller_idx;		/* Domoticz idx			*/
    char		*heater_address;	/* Heater relay or PWM		*/
    int			heater_state;		/* Heater state 0..100		*/
    int			heater_delay;		/* Heater delay time /15 sec	*/
    int			heater_wait;		/* Heater wait counter		*/
    int			heater_usage;		/* Heater usage in seconds	*/
    int			heater_idx;		/* Domoticz idx			*/
    char		*cooler_address;	/* Cooler relay or PWM		*/
    int			cooler_state;		/* Cooler state 0..100		*/
    int			cooler_delay;		/* Cooler delay time /15 sec	*/
    int			cooler_wait;		/* Cooler wait counter		*/
    int			cooler_usage;		/* Cooler usage in seconds	*/
    int			cooler_idx;		/* Domoticz idx			*/
    char		*fan_address;		/* Fan relay or PWM 		*/
    int			fan_state;		/* Fan state 0..100		*/
    int			fan_delay;		/* Fan delay time /15 sec	*/
    int			fan_wait;		/* Fan wait counter		*/
    int			fan_usage;		/* Fan usage in seconds		*/
    int			fan_idx;		/* Domoticz idx			*/
    char		*light_address;		/* Lights relay			*/
    int			light_state;		/* Lights state 0..100		*/
    int			light_delay;		/* Lights delay time /15 sec	*/
    int			light_wait;		/* Lights wait counter		*/
    int			light_usage;		/* Lights usage in seconds	*/
    int			light_idx;		/* Domoticz idx			*/
    char		*door_address;		/* Door input address		*/
    int			door_state;		/* Door status			*/
    int			door_idx;		/* Domoticz idx			*/
    char		*psu_address;		/* Power Supply input address	*/
    int			psu_state;		/* Power Supply status		*/
    int			psu_idx;		/* Domoticz idx			*/
    int			mode;			/* Unit mode			*/
    float		beer_set;		/* Beer temperature setting	*/
    float		fridge_set;		/* Fridge temperature setting	*/
    float		temp_set_min;		/* Minimum temperature		*/
    float		temp_set_max;		/* Maximum temperature		*/
    char		*profile;		/* Active profile uuid		*/
    time_t		prof_started;		/* Profile start time		*/
    int			prof_state;		/* Profile OFF|PAUSE|RUN|DONE	*/
    float		prof_target_lo;		/* Profile current target low	*/
    float		prof_target_hi;		/* Profile current target high	*/
    time_t		prof_paused;		/* Profile total pause time	*/
    int			prof_percent;		/* Profile percentage done	*/
    float		prof_peak_abs;		/* Profile absolute peak temp	*/
    float		prof_peak_rel;		/* Profile relative peak temp	*/
    time_t		prof_primary_done;	/* Profile primary is done	*/
    int			prof_fridge_mode;	/* Profile fridge/beer mode	*/
    pid_var		*PID_cool;		/* PID cooler			*/
    pid_var		*PID_heat;		/* PID heater			*/
    int			mqtt_flag;		/* MQTT print values flag	*/
    char		*event_msg;		/* Event message to log		*/
    int			alarm_flag;		/* Alarm flag			*/
    int			alarm_last;		/* Last alarm state		*/
    int			stage;			/* Fermentation stage		*/
} units_list;

#define	UNITMODE_OFF		0		/* Unit turned off		*/
#define	UNITMODE_NONE		1		/* Unit on but does nothing	*/
#define	UNITMODE_FRIDGE		2		/* Unit acts as a fridge	*/
#define	UNITMODE_BEER		3		/* Unit acts as beer cooler	*/
#define	UNITMODE_PROFILE	4		/* Unit runs in profile mode	*/

#define	UNITSTAGE_PRIMARY	0		/* Fermentation primary stage	*/
#define	UNITSTAGE_SECONDARY	1		/* Fermentation secondary stage	*/
#define	UNITSTAGE_TERTIARY	2		/* Fermentation tertiary stage	*/
#define	UNITSTAGE_CARBONATION	3		/* Carbonation packaged beer	*/

#define	MQTT_FLAG_DATA		0x0001		/* Show updated data values	*/
#define	MQTT_FLAG_BIRTH		0x0002		/* Show birth instead of data	*/
#define MQTT_FLAG_DEATH		0x0004		/* Show death of a unit		*/
#define	MQTT_FLAG_DLOG		0x0008		/* Send DLOG message		*/



/*
 * Alarm bits, value above 255 are serious alarms.
 */
#define	ALARM_FLAG_DOOR		0x0001		/* Door open			*/
#define	ALARM_FLAG_PSU		0x0002		/* PSU problem			*/
#define	ALARM_FLAG_CHILLER	0x0100		/* Chiller too warm		*/



/*
 * Fermenting steps
 */
typedef struct _prof_step {
    struct _prof_step	*next;
    int			version;		/* Version 1			*/
    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;

/*
 * Fermenting profiles
 */
typedef struct _prof_list {
    struct _prof_list	*next;
    int			version;		/* Version 1			*/
    char		*uuid;			/* Profile uuid			*/
    char		*name;			/* Profile name			*/
    int			busy;			/* Profile busy == 1, free == 0	*/
    float		inittemp_lo;		/* Low target before start	*/
    float		inittemp_hi;		/* High target before start	*/
    int			fridge_mode;		/* Fridge or beer mode		*/
    prof_step		*steps;			/* Profile steps		*/
} profiles_list;

#define PROFILE_OFF		0		/* Profile not active		*/
#define	PROFILE_PAUSE		1		/* Profile pause		*/
#define	PROFILE_RUN		2		/* Profile is running		*/
#define	PROFILE_DONE		3		/* Profile is finished		*/
#define	PROFILE_ABORT		4		/* Profile abort		*/


/*
 * External devices like sensors, relays.
 */
typedef struct _dev_list {
    struct _dev_list	*next;
    int			version;		/* Version 1			*/
    char		*uuid;			/* UUID of this device		*/
    int			type;			/* Device type			*/
    int			direction;		/* Device direction		*/
    int			value;			/* Device value			*/
    int			offset;			/* Device offset value		*/
    int			present;		/* Device present		*/
    char		*address;		/* Device address		*/
    int			subdevice;		/* Device sub address		*/
    int			gpiopin;		/* Device GPIO pin or -1	*/
    char		*description;		/* Device description		*/
    int			inuse;			/* In use counter		*/
    char		*comment;		/* What we think it is		*/
    time_t		timestamp;		/* Last updated			*/
} devices_list;

#define	DEVTYPE_NA		0		/* Unknown device type		*/
#define	DEVTYPE_W1		1		/* 1-Wire bus			*/
#define	DEVTYPE_GPIO		2		/* GPIO I/O device		*/
#define	DEVTYPE_RC433		3		/* 433 MHz device		*/
#define	DEVTYPE_DHT		4		/* DHT type device on GPIO	*/
#define	DEVTYPE_I2C		5		/* I2C bus device		*/
#define	DEVTYPE_SPI		6		/* SPI bus device		*/
#ifdef USE_SIMULATOR
#define DEVTYPE_SIM		7		/* Simulated device		*/
#endif

#define	DEVPRESENT_UNDEF	0		/* Precence not testable	*/
#define	DEVPRESENT_NO		1		/* Device is missing		*/
#define	DEVPRESENT_YES		2		/* Device is detected		*/
#define	DEVPRESENT_ERROR	3		/* Device is in error		*/

#define	DEVDIR_UNDEF		0		/* Undefined			*/
#define	DEVDIR_IN_BIN		1		/* Binary input			*/
#define	DEVDIR_OUT_BIN		2		/* Binary output		*/
#define	DEVDIR_IN_ANALOG	3		/* Temperature input etc.	*/
#define	DEVDIR_OUT_ANALOG	4		/* Analog steering		*/
#define	DEVDIR_OUT_PWM		5		/* PWM outout			*/
#define	DEVDIR_INTERN		6		/* Internal function		*/

#ifdef USE_SIMULATOR

/*
 * The frigo is a simulation of a fridge with a heating device. 
 * It has a volume air, a volume of your beer. There is a simulated
 * thermal sensor that measures the air and one that measures the beer.
 * It looks like a normal live setup.
 */
typedef struct _simulator {
    struct _simulator	*next;
    int			version;		/* Version of this record	*/
    char		*uuid;			/* Simulator uuid		*/
    char		*name;			/* Simulator name		*/
    int			volume_air;		/* Volume air of the frigo	*/
    int			volume_beer;		/* Volume beer inside frigo	*/
    double		room_temperature;	/* Temp outside frigo		*/
    double		room_humidity;		/* Humidity outside frigo	*/
    double		air_temperature;	/* Simulated air temperature	*/
    double		beer_temperature;	/* Simulated beer temperature	*/
    double		chiller_temperature;	/* Simulated chiller temp.	*/
    double		cooler_temp;		/* Lowest cooler temperature	*/
    int			cooler_time;		/* Time to reach temperature	*/
    float		cooler_size;		/* Size of cooler in square mtr	*/
    double		heater_temp;		/* Highest heater temperature	*/
    int			heater_time;		/* Time to reach temperature	*/
    float		heater_size;		/* Size of heater in square mtr	*/
    int			heater_state;		/* Heater status		*/
    int			cooler_state;		/* Cooler status		*/
    float		frigo_isolation;	/* Frigo isolation value	*/
    /*
     * Status values, maintained by the simulator but stored
     * here so they don't get lost over program restarts.
     */
    double		s_yeast_heat;		/* Heat generated by yeast	*/
    time_t		s_yeast_started;	/* Start date/time fermentation	*/
    double		s_cool_temp;		/* Temp cooler			*/
    double		s_heat_temp;		/* Temp heater			*/
    time_t		s_cool_changed;		/* Start date/time cooler	*/
    time_t		s_heat_changed;		/* Start date/time heater	*/
} simulator_list;

#endif

typedef struct _sys_config {
    char		*name;			/* Configuration name		*/
    int			my_port;		/* my client/server port	*/
    unsigned char	tempFormat;		/* Temperature format, C or F	*/
    char		*temp_address;		/* Environment temperature	*/
    int			temp_state;		/* 0=ok, 1=missing, 2=error	*/
    int			temp_value;		/* Air temperature in C * 1000	*/
    char		*hum_address;		/* Environment huminity		*/
    int			hum_state;		/* 0=ok, 1=missing, 2=error	*/
    int			hum_value;		/* Huminity in % * 1000		*/
    int			temp_hum_idx;		/* Domoticz idx			*/
    int			lcd_cols;		/* LCD display columns		*/
    int			lcd_rows;		/* LCD display rows		*/
    int			lcd_address;		/* LCD display i2c address	*/
    int			next_unit;		/* Next unit alias name		*/
    units_list		*units;			/* Fermenter units		*/
    profiles_list	*profiles;		/* Ferment profiles		*/
    devices_list	*devices;		/* Sensors and switches		*/
#ifdef USE_SIMULATOR
    simulator_list	*simulators;		/* Simulators			*/
#endif
    char		*mqtt_host;		/* MQTT host to connect to	*/
    int			mqtt_port;		/* MQTT port to connect to	*/
    char		*mqtt_username;		/* MQTT username		*/
    char		*mqtt_password;		/* MQTT password		*/
    char		*uuid;			/* System uuid			*/
} sys_config;



#endif

mercurial