|
|
【程序】Powerlog 开机时间及室温自动记录程序 V2.4 |
一派護法 十九級 |
|
一派護法 十九級 |
【autorun.sh】 cd /home/octopus/Programs/powerlog ./powerlog2 on ./templog
|
一派護法 十九級 |
【conn.h】 #define SERVER_NAME "localhost" #define DB_USER "server" #define DB_PASSWORD "密码" #define DB_NAME "server"
|
一派護法 十九級 |
【IP.txt】 192.168.0.4
|
一派護法 十九級 |
【logview.c】 #include <mysql/mysql.h> #include <stdio.h> #include "conn.h"
void putstr(char *s, FILE *fp, char display) { fputs(s, fp); fputc('\n', fp); if (display == 1) puts(s); }
int main(int argc, char *argv[]) { char ch; char IP[16]; char line[100]; char sql[150]; int i = 0; FILE *fp; MYSQL conn; MYSQL_RES *rs; MYSQL_ROW row; /* Get IP Address */ if ((fp = fopen("IP.txt", "r")) == NULL) { printf("Cannot open the file for IP Address.\n"); return 1; } while (ch = fgetc(fp), !feof(fp)) { if ((ch >= '0' && ch <= '9') || ch == '.') IP[i++] = ch; else break; if (i == sizeof(IP) - 1) break; } IP[i] = '\0'; fclose(fp); /* Open Log File */ if ((fp = fopen("powerlog.txt", "w")) == NULL) { printf("Cannot open the file.\n"); return 2; } printf("Powerlog Version 2.4\n"); putstr("ID\tTIME", fp, 1); /* Init MySQL Connection */ mysql_init(&conn); if (!mysql_real_connect(&conn, SERVER_NAME, DB_USER, DB_PASSWORD, DB_NAME, 0, NULL, 0)) { printf("Cannot connect to the database server.\n"); return 3; } mysql_set_character_set(&conn, "utf8"); /* Query */ sprintf(sql, "SELECT LogID, LogTime FROM PowerLog WHERE LogFlag = 'POWER ON' AND ComputerIP = '%s' ORDER BY LogTime DESC", IP); mysql_query(&conn, sql); rs = mysql_store_result(&conn); for (i = 0; row = mysql_fetch_row(rs); i++) { sprintf(line, "%d\t%s", atoi(row[0]), row[1]); putstr(line, fp, (i < 20)); } mysql_free_result(rs); fclose(fp); mysql_close(&conn); return 0; }
|
一派護法 十九級 |
【Makefile】 MYSQL = -lmysqlclient
powerlog2: conn.h temperature.h temperature.c UART.h UART.c powerlog2.c gcc temperature.c UART.c powerlog2.c -o powerlog2 $(MYSQL)
logview: conn.h logview.c gcc logview.c -o logview $(MYSQL)
templog: conn.h temperature.h temperature.c UART.h UART.c templog.c gcc temperature.c UART.c templog.c -o templog $(MYSQL)
|
一派護法 十九級 |
【powerlog2.c】 #include <mysql/mysql.h> #include <stdio.h> #include <string.h> #include "conn.h" #include "UART.h"
int main(int argc, char *argv[]) { char sql[200]; char *sql_err; char temp_str[10]; char temp_str_buffer[120] = {0}; char uart_open = 1; float temp; int i = 10; MYSQL conn; MYSQL_RES *rs; MYSQL_ROW row; if (UART_Open() == 0) uart_open = 0; mysql_init(&conn); if (!mysql_real_connect(&conn, SERVER_NAME, DB_USER, DB_PASSWORD, DB_NAME, 0, NULL, 0)) { printf("Cannot connect to the database server.\n"); return 3; } mysql_set_character_set(&conn, "utf8"); printf("Powerlog Version 2.4\n"); printf("Welcome\n"); if (uart_open) { get_temperature(&temp); // avoid the first possible error value while (i--) { usleep(10000); get_temperature(&temp); get_temperature_str(&temp, temp_str); strcat(temp_str_buffer, temp_str); } } else strcpy(temp_str_buffer, "UART Unavailable"); if (argc >= 2 && strcmp(argv[1], "on") == 0) { sprintf(sql, "INSERT INTO PowerLog (LogTime, LogFlag, Temperature) VALUES (NOW(), 'POWER ON', '%s')", temp_str_buffer); sql_err = "INSERT INTO PowerLog (LogTime, LogFlag, Temperature) VALUES (NOW(), 'POWER ON', 'Query Error')"; } else { // Just for debug sprintf(sql, "INSERT INTO PowerLog (LogTime, Temperature) VALUES (NOW(), '%s')", temp_str_buffer); sql_err = "INSERT INTO PowerLog (LogTime, Temperature) VALUES (NOW(), 'Query Error')"; } i = mysql_query(&conn, sql); if (i == 1) mysql_query(&conn, sql_err); mysql_query(&conn, "SELECT NOW()"); rs = mysql_store_result(&conn); row = mysql_fetch_row(rs); printf("MySQL Time: %s\n", row[0]); mysql_free_result(rs); mysql_close(&conn); if (uart_open) UART_Close(); return 0; }
|
一派護法 十九級 |
【temperature.c】 #include <stdio.h> #include <unistd.h> #include "UART.h" #include "temperature.h"
char buffer[513];
void get_temperature(float *temp) { UART_Send(0x83); usleep(100000); UART_Receive(buffer); if (buffer[1] & TEMP_ERROR) { *temp = -999.99; return; } *temp = buffer[2] * 1.00 + buffer[3] * 0.01; if (buffer[1] & TEMP_NEGATIVE) *temp = -*temp; }
void get_temperature_str(float *temp, char *s) { sprintf(s, "%.2f℃\t", *temp); }
|
一派護法 十九級 |
【temperature.h】 #define _BV(n) (1 << n) #define TEMP_NEGATIVE _BV(4) #define TEMP_ERROR _BV(6)
void get_temperature(float *temp); void get_temperature_str(float *temp, char *s);
|
一派護法 十九級 |
【templog.c】 #include <fcntl.h> #include <mysql/mysql.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "conn.h" #include "temperature.h" #include "UART.h"
#define EXIT_FLAG _BV(7) #define COUNTER (flags & (~EXIT_FLAG)) #define COUNTER_CLEAR (flags &= EXIT_FLAG) int flags = 23;
void record(void) { char sql[300] = "INSERT INTO TemperatureLog (TemperatureA, TemperatureB, TemperatureC, TemperatureD, TemperatureE, TemperatureF, TemperatureG, TemperatureH, TemperatureI, TemperatureJ) VALUES ("; char *pStr; float temp; int i; MYSQL conn; MYSQL_RES *rs; flags++; if (COUNTER >= 24) COUNTER_CLEAR; if (COUNTER == 0) { if (UART_Open() == 0) return; for (i = 0; i < 5; i++) get_temperature(&temp); // avoid the first possible error value } mysql_init(&conn); if (!mysql_real_connect(&conn, SERVER_NAME, DB_USER, DB_PASSWORD, DB_NAME, 0, NULL, 0)) { if (COUNTER == 0) UART_Close(); return; } mysql_set_character_set(&conn, "utf8"); if (COUNTER == 0) { pStr = sql + strlen(sql); for (i = 0; i < 10; i++) { get_temperature(&temp); pStr += sprintf(pStr, "%.2f", temp); if (i < 9) *pStr++ = ','; sleep(1); } *pStr++ = ')'; *pStr++ = '\0'; mysql_query(&conn, sql); } mysql_query(&conn, "SELECT FlagValue FROM Flags WHERE FlagName = 'TEMPLOG_EXIT' AND FlagValue = 'EXIT'"); rs = mysql_store_result(&conn); i = mysql_num_rows(rs); mysql_free_result(rs); if (i == 1) { mysql_query(&conn, "UPDATE Flags SET FlagValue = NOW() WHERE FlagName = 'TEMPLOG_EXIT'"); flags |= EXIT_FLAG; } mysql_close(&conn); if (COUNTER == 0) UART_Close(); }
int main(void) { int fd; pid_t pid; printf("Powerlog Version 2.4\n"); pid = fork(); if (pid < 0) exit(1); if (pid > 0) exit(0); pid = setsid(); fd = open("/dev/null", O_RDWR); dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); for (;;) { sleep(100); record(); if (flags & EXIT_FLAG) break; } return 0; }
|
一派護法 十九級 |
【UART.c】 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // UNIX Standard Function Definitions #include <fcntl.h> // File Control Definitions #include <errno.h> // File Control Definitions #include <termios.h> // POSIX Terminal Control Definitions #include "UART.h"
struct termios tty; struct termios tty_old; int UART_id = 0;
int UART_Open(void) { memset(&tty, 0, sizeof(tty)); UART_id = open(UART_PORT, O_RDWR | O_NOCTTY | O_NDELAY); if (UART_id < 0) { printf("Warning: Cannot open the serial port!\n"); return 0; } /* Error Handling */ if (tcgetattr(UART_id, &tty) != 0) { printf("Error: %d from tcgetattr: %s \n", errno,strerror(errno)); return 0; } /* Save old tty parameters */ tty_old = tty; /* Set Baud Rate */ cfsetospeed(&tty, (speed_t)B9600); cfsetispeed(&tty, (speed_t)B9600); /* Setting other Port Stuff */ tty.c_cflag &= ~PARENB; // Make 8n1 tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; tty.c_cflag &= ~CRTSCTS; // no flow control tty.c_cc[VMIN] = 1; // read doesn't block tty.c_cc[VTIME] = 5; // 0.5 second read timeout tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines /* Make raw */ cfmakeraw(&tty); /* Flush Port, then applies attributes */ tcflush(UART_id, TCIFLUSH); if (tcsetattr(UART_id, TCSANOW, &tty) != 0) { printf("Error: %d from tcgetattr\n", errno); return 0; } return UART_id; }
void UART_Send(unsigned char Byte) { write(UART_id, &Byte, 1); // It was definitely not necessary to write byte per byte, also int n_written = write( UART_id, cmd, sizeof(cmd) -1) worked fine. }
int UART_Receive(char* buf) { int len = read(UART_id, buf, 512); buf[len] = '\0'; return len; }
void UART_Close() { close(UART_id); }
|
一派護法 十九級 |
【UART.h】 #define UART_PORT "/dev/ttyUSB0"
int UART_Open(void); void UART_Send(unsigned char Byte); int UART_Receive(char* buf); void UART_Close();
|
一派護法 十九級 |
Powerlog V2.4
程序主要功能
开机时自动启动powerlog2程序记录开机时间及室温到MySQL数据库的PowerLog表中,表中的IP地址字段由IP.txt决定。powerlog2程序退出后,自动启动templog守护进程,每隔2400秒左右记录一次室温到TemperatureLog表中。首次启动templog后100秒自动记录一次室温。若想要退出templog守护程序,可将Flags表中的TEMPLOG_EXIT的FlagValue设置为EXIT,大约100秒之后,程序自动退出。
logview程序用于查看最近的开机记录,并自动输出所有的开机记录到powerlog.txt文件中。
|
一派護法 十九級 |
【数据表: Flags】 CREATE TABLE `Flags` ( `FlagName` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, `FlagValue` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`FlagName`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO `Flags` (`FlagName`) VALUES ('TEMPLOG_EXIT');
|
一派護法 十九級 |
【数据表: PowerLog】 CREATE TABLE `PowerLog` ( `LogID` int(11) NOT NULL AUTO_INCREMENT, `LogTime` datetime NOT NULL, `LogFlag` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'TEST', `LogTimeZone` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'UTC+8', `ComputerIP` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT '192.168.0.4', `Temperature` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'NO DATA', PRIMARY KEY (`LogID`) ) ENGINE=InnoDB AUTO_INCREMENT=1163 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
|
一派護法 十九級 |
【数据表: TemperatureLog】 CREATE TABLE `TemperatureLog` ( `LogTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `TemperatureA` float NOT NULL, `TemperatureB` float NOT NULL, `TemperatureC` float NOT NULL, `TemperatureD` float NOT NULL, `TemperatureE` float NOT NULL, `TemperatureF` float NOT NULL, `TemperatureG` float NOT NULL, `TemperatureH` float NOT NULL, `TemperatureI` float NOT NULL, `TemperatureJ` float NOT NULL, PRIMARY KEY (`LogTime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
|
|