2023-12-14 17:22:43 -05:00
|
|
|
#include <iostream>
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
#include <SDL2/SDL_ttf.h>
|
|
|
|
#include <string>
|
2023-12-15 15:38:22 -05:00
|
|
|
#include <thread>
|
|
|
|
#include <chrono>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
2024-02-08 17:34:00 -05:00
|
|
|
#include <vector>
|
2024-02-08 17:50:40 -05:00
|
|
|
#include <iomanip> // for std::setprecision
|
2024-02-27 18:54:59 -05:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <ctime>
|
2024-02-08 17:34:00 -05:00
|
|
|
|
|
|
|
const std::string error_txt[16] = {
|
|
|
|
"Reset Button", //0
|
|
|
|
"Emergency Switch", //1
|
|
|
|
"Cage Door Open", //2
|
|
|
|
"Fume Hood Flow", //3
|
|
|
|
"Vacuum Gauge 2", //4
|
|
|
|
"Tritium Monitor", //5
|
2024-05-23 16:29:20 -04:00
|
|
|
"Control Room Emergency Switch", //6
|
2024-02-08 17:34:00 -05:00
|
|
|
"Bldg Power Fail", //7
|
|
|
|
"Coolant Flow 2", //8
|
|
|
|
"Vacuum Gauge 1", //9
|
|
|
|
"error: port map", //10
|
|
|
|
"Coolant Flow 1", //11
|
|
|
|
"Smoke at Source", //12
|
|
|
|
"error: port map", //13
|
|
|
|
"error: port map", //14
|
|
|
|
"error: port map" //15
|
|
|
|
};
|
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
|
|
|
|
SDL_Window* window = nullptr;
|
|
|
|
SDL_Renderer* renderer = nullptr;
|
|
|
|
TTF_Font* font = nullptr;
|
|
|
|
|
|
|
|
SDL_Color blackColor = { 0, 0, 0, 255};
|
|
|
|
SDL_Color redColor = { 255, 0, 0, 255};
|
|
|
|
SDL_Color greenColor = { 0, 200, 0, 255};
|
|
|
|
SDL_Color blueColor = { 0, 0, 255, 255};
|
|
|
|
|
|
|
|
SDL_Texture* textTexture = nullptr;
|
|
|
|
|
|
|
|
void textDisplay(std::string text, int posX, int posY, SDL_Color color){
|
|
|
|
|
|
|
|
SDL_Surface* textSurface = TTF_RenderText_Solid(font, text.c_str(), color);
|
|
|
|
textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
|
|
|
|
|
|
|
|
SDL_Rect textRect = { posX, posY, textSurface->w, textSurface->h };
|
|
|
|
|
|
|
|
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
|
|
|
|
|
|
|
|
SDL_FreeSurface(textSurface);
|
|
|
|
SDL_DestroyTexture(textTexture);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int statusReading = 0;
|
|
|
|
double tritiumReading = 0;
|
|
|
|
double vaccumReading = 0;
|
|
|
|
double subPumpReading = 0;
|
|
|
|
|
|
|
|
bool preAccel = true;
|
|
|
|
bool valve1 = true;
|
|
|
|
bool valve2 = true;
|
|
|
|
bool hv = true;
|
|
|
|
bool boiler = true ;
|
|
|
|
bool ionizer = true ;
|
|
|
|
|
2024-02-08 17:34:00 -05:00
|
|
|
std::vector<int> error_code;
|
|
|
|
bool isTritiumError = false;
|
|
|
|
bool isVaccumError = false;
|
2024-02-27 18:54:59 -05:00
|
|
|
char timeBuffer[80];
|
2024-02-08 17:34:00 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
void readStatus(){
|
|
|
|
std::ifstream file("data.txt"); // Replace "your_file.txt" with your actual file path
|
|
|
|
if (!file.is_open()) {
|
|
|
|
std::cout << "Unable to open file" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-02-08 17:34:00 -05:00
|
|
|
error_code.clear();
|
|
|
|
isTritiumError = false;
|
|
|
|
isVaccumError = false;
|
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
std::string line;
|
|
|
|
while (std::getline(file, line)) {
|
|
|
|
std::istringstream iss(line);
|
|
|
|
std::string key;
|
|
|
|
double value;
|
|
|
|
|
|
|
|
if (std::getline(iss, key, '=')) {
|
|
|
|
// Extract the key
|
|
|
|
std::string valueStr;
|
|
|
|
if (std::getline(iss, valueStr)) {
|
|
|
|
// Convert the value string to double
|
|
|
|
try {
|
|
|
|
value = std::stod(valueStr);
|
|
|
|
//std::cout << "Key: " << key << ", Value: " << value << std::endl;
|
|
|
|
// Use 'value' as needed
|
|
|
|
|
|
|
|
if( key == "State value" ) statusReading = value;
|
|
|
|
if( key == "Tritium value" ) tritiumReading = value;
|
|
|
|
if( key == "Vaccum value" ) vaccumReading = value;
|
|
|
|
if( key == "SubPump value" ) subPumpReading = value;
|
|
|
|
|
|
|
|
} catch (const std::invalid_argument& e) {
|
|
|
|
std::cout << "Invalid value format for key: " << key << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-08 17:34:00 -05:00
|
|
|
|
|
|
|
if ( line[0] == '#' ) {
|
|
|
|
int code = line[1] -'0' ;
|
|
|
|
|
|
|
|
error_code.push_back( code );
|
|
|
|
|
|
|
|
if( code == 9 ) isVaccumError = true;
|
|
|
|
if( code == 5 ) isTritiumError = true;
|
|
|
|
|
|
|
|
// printf("error code : %d, %s\n", error_code.back(), error_txt[error_code.back()].c_str());
|
|
|
|
|
|
|
|
}
|
2023-12-15 15:38:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
2024-02-27 18:54:59 -05:00
|
|
|
|
|
|
|
struct stat fileStat;
|
|
|
|
stat("data.txt", &fileStat);
|
|
|
|
time_t lastModifiedTime = fileStat.st_mtime;
|
|
|
|
struct tm* timeinfo = localtime(&lastModifiedTime);
|
|
|
|
strftime(timeBuffer, sizeof(timeBuffer), "data.txt : %Y-%m-%d %H:%M:%S", timeinfo);
|
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
if( statusReading == 0 || statusReading == 1 ){ // startup or normal
|
|
|
|
preAccel = true;
|
|
|
|
valve1 = true;
|
|
|
|
valve2 = true;
|
|
|
|
hv = true;
|
|
|
|
boiler = true;
|
|
|
|
ionizer = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( statusReading == 2 ){ // toruble1
|
|
|
|
preAccel = false;
|
|
|
|
hv = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( statusReading == 3 ){ // toruble2
|
|
|
|
preAccel = false;
|
|
|
|
valve1 = false;
|
|
|
|
valve2 = false;
|
|
|
|
hv = false;
|
|
|
|
ionizer = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( statusReading == 4 ){ // toruble3
|
|
|
|
preAccel = false;
|
|
|
|
valve1 = false;
|
|
|
|
valve2 = false;
|
|
|
|
hv = false;
|
|
|
|
boiler = false;
|
|
|
|
ionizer = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2024-02-08 17:34:00 -05:00
|
|
|
std::string FormatDouble(double value){
|
|
|
|
|
2024-02-08 17:50:40 -05:00
|
|
|
int decimalPlaces = 1;
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << std::fixed << std::setprecision(decimalPlaces) << value;
|
|
|
|
return oss.str();
|
2024-02-08 17:34:00 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-12-14 17:22:43 -05:00
|
|
|
int main() {
|
|
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
|
|
|
|
|
|
// Create a window
|
2023-12-15 15:38:22 -05:00
|
|
|
window = SDL_CreateWindow("Tritium Source Status",
|
2023-12-14 17:22:43 -05:00
|
|
|
SDL_WINDOWPOS_UNDEFINED,
|
|
|
|
SDL_WINDOWPOS_UNDEFINED,
|
2023-12-14 17:53:47 -05:00
|
|
|
1577, 695, 0);
|
2023-12-14 17:22:43 -05:00
|
|
|
|
|
|
|
// Create a renderer
|
2023-12-15 15:38:22 -05:00
|
|
|
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
2023-12-14 17:22:43 -05:00
|
|
|
|
|
|
|
// Font initialization for rendering text
|
|
|
|
TTF_Init();
|
2023-12-15 15:38:22 -05:00
|
|
|
font = TTF_OpenFont("/usr/share/fonts/truetype/freefont/FreeSerifBold.ttf", 24);
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
// Load an image
|
|
|
|
SDL_Surface* imageSurface = IMG_Load("BG.png");
|
|
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, imageSurface);
|
|
|
|
SDL_FreeSurface(imageSurface);
|
|
|
|
SDL_Rect imageRect = { 0, 0, 1577, 695 }; // Image position and size
|
2023-12-14 17:22:43 -05:00
|
|
|
|
|
|
|
SDL_Event event;
|
|
|
|
bool running = true;
|
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
int count = 0;
|
|
|
|
|
2023-12-14 17:22:43 -05:00
|
|
|
while (running) {
|
2023-12-14 17:53:47 -05:00
|
|
|
while (SDL_PollEvent(&event)) {
|
|
|
|
if (event.type == SDL_QUIT) {
|
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
}
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
if( count == 0 ) readStatus();
|
|
|
|
|
|
|
|
count ++;
|
|
|
|
if( count >= 5 ) count = 0;
|
|
|
|
|
2023-12-14 17:53:47 -05:00
|
|
|
// Clear the renderer
|
|
|
|
SDL_RenderClear(renderer);
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-14 17:53:47 -05:00
|
|
|
// Render the image
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, &imageRect);
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
{// Get current time
|
|
|
|
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
|
|
|
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
// Convert time to a string
|
|
|
|
std::string timeString = std::ctime(&now_c);
|
|
|
|
timeString.erase(timeString.length() - 1); //remove the '\n'
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
textDisplay(timeString, 10, 10, blackColor);
|
|
|
|
}
|
2023-12-14 17:22:43 -05:00
|
|
|
|
2023-12-15 15:38:22 -05:00
|
|
|
textDisplay( valve1 ? "Open" : "Close", 570, 455, valve1 ? greenColor : redColor); // GateValve-1
|
|
|
|
textDisplay( valve2 ? "Open" : "Close", 1270, 455, valve2 ? greenColor : redColor); // GateValve-2
|
|
|
|
textDisplay( "Pre-Accel. supply : ", 750, 455, blackColor); // pre-accel. supply text
|
|
|
|
textDisplay( preAccel ? "On" : "Off", 950, 455, preAccel ? greenColor : redColor); // pre-accel. supply text
|
2023-12-14 17:53:47 -05:00
|
|
|
|
2024-02-08 17:50:40 -05:00
|
|
|
int yPos = 300;
|
|
|
|
textDisplay( "HV Supply : ", 30, yPos, blackColor);
|
|
|
|
textDisplay( hv ? "On" : "Off", 230, yPos, hv ? greenColor : redColor);
|
2023-12-15 15:38:22 -05:00
|
|
|
|
2024-02-08 17:50:40 -05:00
|
|
|
textDisplay( "Boiler Supply : ", 30, yPos + 40, blackColor);
|
|
|
|
textDisplay( boiler ? "On" : "Off", 230, yPos + 40, boiler ? greenColor : redColor);
|
2023-12-15 15:38:22 -05:00
|
|
|
|
2024-02-08 17:50:40 -05:00
|
|
|
textDisplay( "Ionizer Supply : ", 30, yPos + 80, blackColor);
|
|
|
|
textDisplay( ionizer ? "On" : "Off", 230, yPos + 80, ionizer ? greenColor : redColor);
|
2023-12-15 15:38:22 -05:00
|
|
|
|
|
|
|
switch (statusReading){
|
|
|
|
case 0: textDisplay( "Start-Up", 10, 40, blueColor); break;
|
|
|
|
case 1: textDisplay( "Normal", 10, 40, greenColor); break;
|
2024-01-30 12:56:30 -05:00
|
|
|
case 2: textDisplay( "Cage Door (Tripped-1)", 10, 40, redColor); break;
|
|
|
|
case 3: textDisplay( "Vacuum (Tripped-2)", 10, 40, redColor); break;
|
|
|
|
case 4: textDisplay( "Source (Tripped-3)", 10, 40, redColor); break;
|
2023-12-15 15:38:22 -05:00
|
|
|
}
|
|
|
|
|
2024-02-08 17:34:00 -05:00
|
|
|
if( error_code.size() > 0 ){
|
|
|
|
for( size_t i = 0; i < error_code.size(); i++){
|
|
|
|
textDisplay( error_txt[error_code[i]], 10, 80 + 25*i, redColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-24 15:14:15 -04:00
|
|
|
textDisplay( "Tritium Sensor : " + FormatDouble(tritiumReading) + " uCr/m3", 720, 200, isTritiumError ? redColor : blueColor);
|
2024-02-08 17:34:00 -05:00
|
|
|
textDisplay( "Vaccum : " + FormatDouble(vaccumReading) + "x1e-6 Torr", 630, 20, isVaccumError ? redColor: blueColor);
|
|
|
|
textDisplay( "SubPump : " + FormatDouble(subPumpReading*1000) + " mA", 300, 40, blueColor);
|
2023-12-15 15:38:22 -05:00
|
|
|
|
|
|
|
textDisplay("update every 5 sec.", 1200, 670, blackColor);
|
2024-02-27 18:54:59 -05:00
|
|
|
textDisplay(timeBuffer, 0, 670, blackColor);
|
2023-12-14 17:53:47 -05:00
|
|
|
|
|
|
|
// Update the screen
|
|
|
|
SDL_RenderPresent(renderer);
|
2023-12-15 15:38:22 -05:00
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
|
|
|
2023-12-14 17:22:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
SDL_DestroyTexture(texture);
|
|
|
|
SDL_DestroyRenderer(renderer);
|
|
|
|
SDL_DestroyWindow(window);
|
|
|
|
TTF_Quit();
|
|
|
|
SDL_Quit();
|
|
|
|
|
|
|
|
return 0;
|
2024-01-30 12:56:30 -05:00
|
|
|
}
|