Adding new config system, template modbus coke, AUTHIDENT in client
[tpg/opendispense2.git] / src / server / handler_coke.c
1 /*
2  * OpenDispense 2 
3  * UCC (University [of WA] Computer Club) Electronic Accounting System
4  *
5  * handler_coke.c - Coke controller code
6  *
7  * This file is licenced under the 3-clause BSD Licence. See the file
8  * COPYING for full details.
9  *
10  * NOTES:
11  * - Remember, the coke machine echoes your text back to you!
12  */
13 #include "common.h"
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdarg.h>
17 #include <pthread.h>
18 #include <unistd.h>
19 #include <modbus/modbus.h>
20
21 #define MIN_DISPENSE_PERIOD     5
22
23 // === CONSTANTS ===
24 const int       ciCoke_MinPeriod = 5;
25 const int       ciCoke_DropBitBase = 0;
26 const int       ciCoke_StatusBitBase = 0;
27
28 // === IMPORTS ===
29
30 // === PROTOTYPES ===
31  int    Coke_InitHandler();
32  int    Coke_CanDispense(int User, int Item);
33  int    Coke_DoDispense(int User, int Item);
34
35 // === GLOBALS ===
36 tHandler        gCoke_Handler = {
37         "coke",
38         Coke_InitHandler,
39         Coke_CanDispense,
40         Coke_DoDispense
41 };
42 const char      *gsCoke_ModbusAddress = "130.95.13.73";
43 modbus_t        *gCoke_Modbus;
44 time_t  gtCoke_LastDispenseTime;
45  int    gbCoke_DummyMode = 1;
46
47 // == CODE ===
48 int Coke_InitHandler()
49 {
50         printf("Connecting to coke machine on '%s'\n", gsCoke_ModbusAddress);
51
52         // Configuable dummy/blank mode (all dispenses succeed)
53         // TODO: Find a better way of handling missing/invalid options
54         if( Config_GetValueCount("coke_dummy_mode") > 0 )
55         {
56                 gbCoke_DummyMode = Config_GetValue_Bool("coke_dummy_mode", 0);
57                 if(gbCoke_DummyMode == -1)      gbCoke_DummyMode = 0;
58         }
59
60         // Open modbus
61         modbus_new_tcp(gsCoke_ModbusAddress, 502);
62         if( !gCoke_Modbus )
63         {
64                 perror("coke - modbus_new_tcp");
65         }
66         else
67         {
68                 if( modbus_connect(gCoke_Modbus) )
69                 {
70                         perror("coke - modbus_connect");
71                 }
72         }
73
74         return 0;
75 }
76
77 int Coke_CanDispense(int UNUSED(User), int Item)
78 {
79         uint8_t status;
80         // Sanity please
81         if( Item < 0 || Item > 6 )      return -1;
82
83         // Check for 'dummy' mode
84         if( gbCoke_DummyMode )
85                 return 0;
86         
87         // Can't dispense if the machine is not connected
88         if( !gCoke_Modbus )
89                 return -2;
90
91         modbus_read_bits(gCoke_Modbus, ciCoke_StatusBitBase + Item, 1, &status);
92
93         return status == 0;
94 }
95
96 /**
97  * \brief Actually do a dispense from the coke machine
98  */
99 int Coke_DoDispense(int UNUSED(User), int Item)
100 {
101         // Sanity please
102         if( Item < 0 || Item > 6 )      return -1;
103
104         // Check for 'dummy' mode
105         if( gbCoke_DummyMode )
106                 return 0;
107         
108         // Can't dispense if the machine is not connected
109         if( !gCoke_Modbus )
110                 return -2;
111
112         // Make sure there are not two dispenses within n seconds
113         if( time(NULL) - gtCoke_LastDispenseTime < ciCoke_MinPeriod )
114         {
115                  int    delay = ciCoke_MinPeriod - (time(NULL) - gtCoke_LastDispenseTime);
116                 printf("Wait %i seconds?\n", delay);
117                 sleep( delay );
118                 printf("wait done\n");
119         }
120         
121         // Dispense (with locking)
122         modbus_write_bit(gCoke_Modbus, ciCoke_DropBitBase + Item, 1);
123         
124         return 0;
125 }
126

UCC git Repository :: git.ucc.asn.au