source: tools/SkyQualityMonitor/sqm.cpp@ 2942

Last change on this file since 2942 was 229, checked in by ogrimm, 14 years ago
Config requests non-blocking if not made from main thread, adapted all servers to GetConfig() returning std::string, workaround for erroneous SERVICE_LIST
File size: 3.5 KB
Line 
1/********************************************************************\
2
3 Interface to the sky quality monitor (essentially a socket interface)
4
5 Terminate with CTRL-c. Socket is closed automatically by exit().
6
7 Oliver Grimm, September 2009
8
9\********************************************************************/
10
11#include <iostream>
12#include <sys/socket.h>
13#include <netdb.h>
14#include <signal.h>
15#include <errno.h>
16#include <stdarg.h>
17
18#define SERVER_NAME "SQM" // Name to use in DIM
19#include "Evidence.h"
20
21#define READ_CMD "rx" // Command to read from device
22#define BUF_SIZE 1000 // Read and text buffer size
23
24
25// Main program
26int main() {
27
28 int SocketDescriptor;
29 struct sockaddr_in SocketAddress;
30 fd_set ReadFileDescriptor;
31 time_t Time;
32 unsigned int Period;
33
34 // Start server and request configuration data
35 EvidenceServer Srv(SERVER_NAME);
36 const char *Address = Srv.GetConfig("address").c_str();
37 unsigned int Port = atoi(Srv.GetConfig("port").c_str());
38
39 // Open socket descriptor
40 if ((SocketDescriptor = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
41 Srv.Message(Srv.FATAL, "Could not open socket (%s)", strerror(errno));
42 }
43
44 // Resolve hostname
45 struct hostent *hostent = gethostbyname(Address);
46 if (hostent==0) {
47 Srv.Message(Srv.FATAL, "Could not resolve host name '%s' (%s)", Address, hstrerror(h_errno));
48 }
49
50 // Connect to server
51 SocketAddress.sin_family = PF_INET;
52 SocketAddress.sin_port = htons((unsigned short) Port);
53 SocketAddress.sin_addr = *(struct in_addr*) hostent->h_addr;
54
55 if (connect(SocketDescriptor, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress))==-1) {
56 Srv.Message(Srv.FATAL, "Could not connect to server '%s' on port %d (%s)", Address, Port, strerror(errno));
57 }
58
59 Srv.Message(Srv.INFO, "Connected to server '%s' on port %d", Address, Port);
60 signal(SIGPIPE,SIG_IGN); // Do not kill process if writing to closed socket
61
62 // Create DIM services
63 double sqm_reading=0.0;
64 char Buffer[BUF_SIZE];
65
66 DimService SQM_Brightness(SERVER_NAME"/NSB", sqm_reading);
67 DimService SQM_Response(SERVER_NAME"/Response", NO_LINK);
68
69 while(!Srv.ExitRequest) {
70 // Request measurement period
71 Period = atoi(Srv.GetConfig("period").c_str());
72
73 // Write read command to socket
74 if ((write(SocketDescriptor, READ_CMD, strlen(READ_CMD)))<1) {
75 Srv.Message(Srv.ERROR, "Could not write read command '%s' to socket.", READ_CMD);
76 }
77
78 // Wait for response (minimum 100 ms)
79 usleep(100000);
80 FD_ZERO(&ReadFileDescriptor);
81 FD_SET(SocketDescriptor, &ReadFileDescriptor);
82 struct timeval WaitTime = {Period, 0};
83 if (select(((int) SocketDescriptor)+1, &ReadFileDescriptor, NULL, NULL, &WaitTime)==-1) {
84 Srv.Message(Srv.FATAL, "Error with select() (%s)", strerror(errno));
85 }
86
87 if (!FD_ISSET(SocketDescriptor, &ReadFileDescriptor)) {
88 Srv.Message(Srv.WARN, "Time-out of %d seconds expired before receiving response from socket", Period);
89 continue;
90 }
91
92 memset(Buffer, 0, BUF_SIZE);
93 if(read(SocketDescriptor, Buffer, BUF_SIZE) == 0) {
94 Srv.Message(Srv.FATAL, "Server not existing anymore, exiting...\n");
95 }
96
97 // Update full textual response and brightness reading
98 for (int i=0; i<strlen(Buffer); i++) if (Buffer[i] == '\n') Buffer[i] = '\0';
99 sqm_reading = strtod(Buffer+2 ,NULL);
100
101 SQM_Brightness.updateService(sqm_reading);
102 SQM_Response.updateService(Buffer);
103
104 Time = time(NULL);
105 printf("%s\n %s CTRL-c to exit.\r", Buffer, asctime(localtime(&Time)));
106 fflush(stdout);
107
108 sleep(Period);
109 } // while()
110
111}
Note: See TracBrowser for help on using the repository browser.