mirror of
https://github.com/eddyem/small_tel.git
synced 2026-06-19 10:26:25 +03:00
weather check for astrosib dome daemon
This commit is contained in:
@@ -15,7 +15,7 @@ message("VER: ${VERSION}")
|
|||||||
option(DEBUG "Compile in debug mode" OFF)
|
option(DEBUG "Compile in debug mode" OFF)
|
||||||
|
|
||||||
# default flags
|
# default flags
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wextra -std=gnu99")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wextra -std=c23")
|
||||||
if(DEBUG)
|
if(DEBUG)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g3 -ggdb -fno-builtin-strlen -Werror")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g3 -ggdb -fno-builtin-strlen -Werror")
|
||||||
add_definitions(-DEBUG)
|
add_definitions(-DEBUG)
|
||||||
@@ -53,11 +53,12 @@ target_include_directories(${PROJ} PUBLIC ${MODULES_INCLUDE_DIRS})
|
|||||||
# -L
|
# -L
|
||||||
target_link_directories(${PROJ} PUBLIC ${MODULES_LIBRARY_DIRS})
|
target_link_directories(${PROJ} PUBLIC ${MODULES_LIBRARY_DIRS})
|
||||||
# -l
|
# -l
|
||||||
target_link_libraries(${PROJ} ${MODULES_LIBRARIES})
|
target_link_libraries(${PROJ} ${MODULES_LIBRARIES} -lweather)
|
||||||
# -D
|
# -D
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DPACKAGE_VERSION=\"${VERSION}\" -DMINOR_VERSION=\"${MINOR_VERSION}\"
|
-DPACKAGE_VERSION=\"${VERSION}\" -DMINOR_VERSION=\"${MINOR_VERSION}\"
|
||||||
-DMID_VERSION=\"${MID_VERSION}\" -DMAJOR_VERSION=\"${MAJOR_VESION}\"
|
-DMID_VERSION=\"${MID_VERSION}\" -DMAJOR_VERSION=\"${MAJOR_VESION}\"
|
||||||
|
-D_GNU_SOURCE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Installation of the program
|
# Installation of the program
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "astrosib_proto.h"
|
#include "astrosib_proto.h"
|
||||||
#include "dome.h"
|
#include "dome.h"
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
// number of relay turning on/off motors power
|
// number of relay turning on/off motors power
|
||||||
#define MOTRELAY_NO 1
|
#define MOTRELAY_NO 1
|
||||||
@@ -269,5 +270,6 @@ ret:
|
|||||||
if(state == DOME_S_IDLE) status_req_interval = STATUSREQ_IDLE;
|
if(state == DOME_S_IDLE) status_req_interval = STATUSREQ_IDLE;
|
||||||
else status_req_interval = STATUSREQ_MOVE;
|
else status_req_interval = STATUSREQ_MOVE;
|
||||||
pthread_mutex_unlock(&serialmutex);
|
pthread_mutex_unlock(&serialmutex);
|
||||||
|
write_header();
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
-std=c17
|
-std=c23
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
// Add predefined macros for your project here. For example:
|
// Add predefined macros for your project here. For example:
|
||||||
// #define THE_ANSWER 42
|
// #define THE_ANSWER 42
|
||||||
|
#define _XOPEN_SOURCE 666
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 16.0.2, 2025-06-04T11:18:43. -->
|
<!-- Written by QtCreator 19.0.1, 2026-05-15T14:43:04. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
@@ -86,12 +86,14 @@
|
|||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
|
<value type="int" key="RcSync">0</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="DeviceType">Desktop</value>
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
|
||||||
@@ -109,8 +111,8 @@
|
|||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
@@ -122,8 +124,8 @@
|
|||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
@@ -133,13 +135,49 @@
|
|||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
@@ -153,6 +191,7 @@
|
|||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
@@ -163,6 +202,7 @@
|
|||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
@@ -173,10 +213,6 @@
|
|||||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
<value type="qlonglong">1</value>
|
<value type="qlonglong">1</value>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
<data>
|
||||||
<variable>Version</variable>
|
<variable>Version</variable>
|
||||||
<value type="int">22</value>
|
<value type="int">22</value>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
-std=c++17
|
-std=c++23
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
astrosib_proto.h
|
astrosib_proto.h
|
||||||
dome.c
|
dome.c
|
||||||
dome.h
|
dome.h
|
||||||
|
header.c
|
||||||
|
header.h
|
||||||
main.c
|
main.c
|
||||||
server.c
|
server.c
|
||||||
server.h
|
server.h
|
||||||
|
|||||||
132
Daemons/domedaemon-astrosib/header.c
Normal file
132
Daemons/domedaemon-astrosib/header.c
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the baader_dome project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
#include "dome.h"
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
|
#define VAL_LEN 22
|
||||||
|
|
||||||
|
static char *headername = NULL;
|
||||||
|
static char *dome_name = NULL;
|
||||||
|
|
||||||
|
static int printhdr(int fd, const char *key, const char *val, const char *cmnt){
|
||||||
|
char tmp[81];
|
||||||
|
char tk[9];
|
||||||
|
if(strlen(key) > 8){
|
||||||
|
snprintf(tk, 8, "%s", key);
|
||||||
|
key = tk;
|
||||||
|
}
|
||||||
|
if(cmnt){
|
||||||
|
snprintf(tmp, 81, "%-8s= %-21s / %s", key, val, cmnt);
|
||||||
|
}else{
|
||||||
|
snprintf(tmp, 81, "%-8s= %s", key, val);
|
||||||
|
}
|
||||||
|
size_t l = strlen(tmp);
|
||||||
|
tmp[l] = '\n';
|
||||||
|
++l;
|
||||||
|
if(write(fd, tmp, l) != (ssize_t)l){
|
||||||
|
WARN("write()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return TRUE if can write to given header file
|
||||||
|
int header_create(const char *file){
|
||||||
|
if(!file) return FALSE;
|
||||||
|
FILE *hf = fopen(file, "w");
|
||||||
|
if(!hf) return FALSE;
|
||||||
|
unlink(file);
|
||||||
|
if(headername) FREE(headername);
|
||||||
|
headername = strdup(file);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set given `name` for telescope name
|
||||||
|
void domename(const char *name){
|
||||||
|
if(dome_name) FREE(dome_name);
|
||||||
|
if(name){
|
||||||
|
int l = strlen(name) + 3;
|
||||||
|
dome_name = MALLOC(char, l);
|
||||||
|
snprintf(dome_name, l, "'%s'", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* stringst[] = {
|
||||||
|
[DOME_S_IDLE] = "idle",
|
||||||
|
[DOME_S_MOVING] = "moving",
|
||||||
|
[DOME_S_ERROR] = "error",
|
||||||
|
};
|
||||||
|
|
||||||
|
void write_header(){
|
||||||
|
if(!headername) return;
|
||||||
|
char aname[PATH_MAX];
|
||||||
|
char val[VAL_LEN];
|
||||||
|
#define WRHDR(k, v, c) do{if(printhdr(fd, k, v, c)){goto returning;}}while(0)
|
||||||
|
snprintf(aname, PATH_MAX-1, "%sXXXXXX", headername);
|
||||||
|
int fd = mkstemp(aname);
|
||||||
|
if(fd < 0){
|
||||||
|
LOGWARN("Can't write header file: mkstemp()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fchmod(fd, 0644);
|
||||||
|
dome_status_t st;
|
||||||
|
dome_state_t curstate = get_dome_state();
|
||||||
|
double stattime = get_dome_status(&st);
|
||||||
|
if(get_forbidden()) WRHDR("OPERATIO", "'FORBIDDEN'", "Observations are forbidden");
|
||||||
|
if(dome_name) WRHDR("DOME", dome_name, "Dome manufacturer/name");
|
||||||
|
int idx = (int)curstate;
|
||||||
|
if(idx < 0 || idx > DOME_S_ERROR) idx = DOME_S_ERROR;
|
||||||
|
snprintf(val, VAL_LEN, "'%s'", stringst[idx]);
|
||||||
|
WRHDR("DOMESTAT", val, "Dome status");
|
||||||
|
snprintf(val, VAL_LEN, "'%s'", textst(st.coverstate[0]));
|
||||||
|
WRHDR("DOMECVR1", val, "Dome cover 1 status");
|
||||||
|
snprintf(val, VAL_LEN, "'%s'", textst(st.coverstate[1]));
|
||||||
|
WRHDR("DOMECVR2", val, "Dome cover 2 status");
|
||||||
|
snprintf(val, VAL_LEN, "%d", st.encoder[0]);
|
||||||
|
WRHDR("DOMEANG1", val, "Dome cover 1 angle");
|
||||||
|
snprintf(val, VAL_LEN, "%d", st.encoder[1]);
|
||||||
|
WRHDR("DOMEANG2", val, "Dome cover 2 angle");
|
||||||
|
snprintf(val, VAL_LEN, "%d", st.relay[0]);
|
||||||
|
WRHDR("DOMERLY1", val, "Dome relay1 state");
|
||||||
|
snprintf(val, VAL_LEN, "%d", st.relay[1]);
|
||||||
|
WRHDR("DOMERLY2", val, "Dome relay2 state");
|
||||||
|
snprintf(val, VAL_LEN, "%d", st.relay[2]);
|
||||||
|
WRHDR("DOMERLY3", val, "Dome relay3 state");
|
||||||
|
if(st.israin) WRHDR("DOMERAIN", "1", "Dome rain sensor armed");
|
||||||
|
snprintf(val, VAL_LEN, "%.3f", stattime);
|
||||||
|
char timebuf[BUFSIZ];
|
||||||
|
time_t t = (time_t) stattime;
|
||||||
|
struct tm *tmp;
|
||||||
|
tmp = localtime(&t);
|
||||||
|
if(!tmp || 0 == strftime(timebuf, BUFSIZ, "Measurement time: %F %T", tmp)){
|
||||||
|
LOGERR("localtime() returned NULL");
|
||||||
|
goto returning;
|
||||||
|
}
|
||||||
|
WRHDR("TDOMMEAS", val, timebuf);
|
||||||
|
#undef WRHDR
|
||||||
|
returning:
|
||||||
|
close(fd);
|
||||||
|
rename(aname, headername);
|
||||||
|
}
|
||||||
23
Daemons/domedaemon-astrosib/header.h
Normal file
23
Daemons/domedaemon-astrosib/header.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the domedaemon-astrosib project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void write_header();
|
||||||
|
int header_create(const char *file);
|
||||||
|
void domename(const char *name);
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <sys/prctl.h> //prctl
|
#include <sys/prctl.h> //prctl
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
// TCP socket port
|
// TCP socket port
|
||||||
@@ -31,45 +32,101 @@
|
|||||||
#define DEFAULT_SERSPEED 9600
|
#define DEFAULT_SERSPEED 9600
|
||||||
// serial polling timeout - 100ms
|
// serial polling timeout - 100ms
|
||||||
#define DEFAULT_SERTMOUT 100000
|
#define DEFAULT_SERTMOUT 100000
|
||||||
|
#define DEFAULT_PIDFILE "/tmp/domedaemon.pid"
|
||||||
|
#define DEFAULT_HEADERFILE "/tmp/dome.fits"
|
||||||
|
#define DEFAULT_DOMENAME "Astrosib"
|
||||||
|
|
||||||
|
static pid_t childpid = 0;
|
||||||
|
static sl_tty_t *serial = NULL;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
|
int help;
|
||||||
char *device; // serial device name
|
char *device; // serial device name
|
||||||
char *node; // port to connect or UNIX socket name
|
char *node; // port to connect or UNIX socket name
|
||||||
char *logfile; // logfile name
|
char *logfile; // logfile name
|
||||||
|
char *pidfile; // PID-file path
|
||||||
|
char *headerfile; // path to FITS-header with dome parameters
|
||||||
|
char *dome_name; // name of dome
|
||||||
int isunix; // open UNIX-socket instead of TCP
|
int isunix; // open UNIX-socket instead of TCP
|
||||||
int verbose; // verbose level
|
int verbose; // verbose level
|
||||||
} parameters;
|
} parameters;
|
||||||
|
|
||||||
|
|
||||||
static parameters G = {
|
static parameters G = {
|
||||||
.node = DEFAULT_PORT,
|
.node = DEFAULT_PORT,
|
||||||
|
.pidfile = DEFAULT_PIDFILE,
|
||||||
|
.headerfile = DEFAULT_HEADERFILE,
|
||||||
|
.dome_name = DEFAULT_DOMENAME,
|
||||||
};
|
};
|
||||||
static int help;
|
|
||||||
|
|
||||||
static sl_option_t cmdlnopts[] = {
|
static sl_option_t cmdlnopts[] = {
|
||||||
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), "show this help"},
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
||||||
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), "serial device name"},
|
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), "serial device name"},
|
||||||
{"node", NEED_ARG, NULL, 'n', arg_string, APTR(&G.node), "UNIX socket name or network port to connect (default: " DEFAULT_PORT ")"},
|
{"node", NEED_ARG, NULL, 'n', arg_string, APTR(&G.node), "UNIX socket name or network port to connect (default: " DEFAULT_PORT ")"},
|
||||||
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), "save logs to file"},
|
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), "save logs to file"},
|
||||||
{"unix", NO_ARGS, NULL, 'u', arg_int, APTR(&G.isunix), "open UNIX-socket instead of TCP"},
|
{"unix", NO_ARGS, NULL, 'u', arg_int, APTR(&G.isunix), "open UNIX-socket instead of TCP"},
|
||||||
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose), "logging verbose level (each -v adds one)"},
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose), "logging verbose level (each -v adds one)"},
|
||||||
|
{"pidfile", NEED_ARG, NULL, 'p', arg_string, APTR(&G.pidfile), "full path to PID-file (default: " DEFAULT_PIDFILE ")"},
|
||||||
|
{"headerfile",NEED_ARG, NULL, 'H', arg_string, APTR(&G.headerfile),"full path to output FITS-header (default: " DEFAULT_HEADERFILE ")"},
|
||||||
|
{"domename",NEED_ARG, NULL, 'N', arg_string, APTR(&G.dome_name), "dome name in FITS-header (default: " DEFAULT_DOMENAME ")"},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void sl_iffound_deflt(pid_t pid){
|
||||||
|
WARNX("Another copy of this process found, pid=%d. Exit.", pid);
|
||||||
|
exit(1); // don't run `signals` to protect foreign PID-file from removal
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIGUSR1 - FORBID observations
|
||||||
|
// SIGUSR2 - allow
|
||||||
void signals(int sig){
|
void signals(int sig){
|
||||||
if(sig){
|
if(sig){
|
||||||
signal(sig, SIG_IGN);
|
if(signals != signal(sig, SIG_IGN)) exit(sig); // function called "as is", before sig registration
|
||||||
DBG("Get signal %d, quit.\n", sig);
|
if(childpid == 0){ // child -> test USR1/USR2
|
||||||
LOGERR("Exit with status %d", sig);
|
LOGDBG("Child gotta signal %d", sig);
|
||||||
}else LOGERR("Exit");
|
if(sig == SIGUSR1){
|
||||||
|
forbid_observations(1);
|
||||||
|
LOGMSG("Got signal `observations forbidden`");
|
||||||
|
signal(sig, signals);
|
||||||
|
return;
|
||||||
|
}else if(sig == SIGUSR2){
|
||||||
|
forbid_observations(0);
|
||||||
|
LOGMSG("Got signal `observations permitted`");
|
||||||
|
signal(sig, signals);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGDBG("Get signal %d, quit.\n", sig);
|
||||||
|
}
|
||||||
|
if(childpid == 0){
|
||||||
|
DBG("Stop server");
|
||||||
|
LOGMSG("Stop server");
|
||||||
|
stopserver();
|
||||||
|
DBG("Close terminal");
|
||||||
|
LOGMSG("Close terminal");
|
||||||
|
if(serial) sl_tty_close(&serial);
|
||||||
|
}else{
|
||||||
|
if(G.pidfile){
|
||||||
|
LOGMSG("Unlink %s", G.pidfile);
|
||||||
|
usleep(10000);
|
||||||
|
unlink(G.pidfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGERR("Exit with status %d", sig);
|
||||||
exit(sig);
|
exit(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
sl_init();
|
sl_init();
|
||||||
sl_parseargs(&argc, &argv, cmdlnopts);
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
if(help) sl_showhelp(-1, cmdlnopts);
|
if(G.help) sl_showhelp(-1, cmdlnopts);
|
||||||
if(!G.node) ERRX("Point node");
|
if(!G.node) ERRX("Point node");
|
||||||
if(!G.device) ERRX("Point path to serial device");
|
if(!G.device) ERRX("Point path to serial device");
|
||||||
|
if(!header_create(G.headerfile))
|
||||||
|
ERRX("Cannot write into '%s'", G.headerfile);
|
||||||
|
domename(G.dome_name);
|
||||||
|
sl_check4running((char*)__progname, G.pidfile);
|
||||||
|
if(sl_daemonize()) ERR("Can't daemonize!");
|
||||||
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
||||||
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
if(G.logfile) OPENLOG(G.logfile, lvl, 1);
|
if(G.logfile) OPENLOG(G.logfile, lvl, 1);
|
||||||
@@ -79,6 +136,8 @@ int main(int argc, char **argv){
|
|||||||
signal(SIGQUIT, signals);
|
signal(SIGQUIT, signals);
|
||||||
signal(SIGTSTP, SIG_IGN);
|
signal(SIGTSTP, SIG_IGN);
|
||||||
signal(SIGHUP, signals);
|
signal(SIGHUP, signals);
|
||||||
|
signal(SIGUSR1, SIG_IGN);
|
||||||
|
signal(SIGUSR2, SIG_IGN);
|
||||||
#ifndef EBUG
|
#ifndef EBUG
|
||||||
time_t lastd = 0;
|
time_t lastd = 0;
|
||||||
while(1){ // guard for dead processes
|
while(1){ // guard for dead processes
|
||||||
@@ -101,7 +160,7 @@ int main(int argc, char **argv){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sl_socktype_e type = (G.isunix) ? SOCKT_UNIX : SOCKT_NETLOCAL;
|
sl_socktype_e type = (G.isunix) ? SOCKT_UNIX : SOCKT_NETLOCAL;
|
||||||
sl_tty_t *serial = sl_tty_new(G.device, DEFAULT_SERSPEED, 4096);
|
serial = sl_tty_new(G.device, DEFAULT_SERSPEED, 4096);
|
||||||
if(serial) serial = sl_tty_open(serial, 1);
|
if(serial) serial = sl_tty_open(serial, 1);
|
||||||
if(!serial){
|
if(!serial){
|
||||||
LOGERR("Can't open serial device %s", G.device);
|
LOGERR("Can't open serial device %s", G.device);
|
||||||
|
|||||||
@@ -18,15 +18,22 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
#include <weather_data.h>
|
||||||
|
|
||||||
#include "dome.h"
|
#include "dome.h"
|
||||||
|
|
||||||
// max age time of last status - 30s
|
// max age time of last status - 30s
|
||||||
#define STATUS_MAX_AGE (30.)
|
#define STATUS_MAX_AGE (30.)
|
||||||
|
|
||||||
|
// if there's no signal from weather over `WEATHER_LOST` seconds, close the dome
|
||||||
|
#define WEATHER_LOST (300.)
|
||||||
|
// interval of weather polling
|
||||||
|
#define WEATH_POLL (5.)
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
#define CMD_UNIXT "unixt"
|
#define CMD_UNIXT "unixt"
|
||||||
@@ -41,6 +48,13 @@
|
|||||||
// main socket
|
// main socket
|
||||||
static sl_sock_t *s = NULL;
|
static sl_sock_t *s = NULL;
|
||||||
|
|
||||||
|
// external (manual) signal "deny/allow"
|
||||||
|
static atomic_bool ForbidObservations = 0; // ==1 if all is forbidden -> close dome and not allow to open
|
||||||
|
// weather don't allow to open
|
||||||
|
static atomic_bool BadWeather = 0;
|
||||||
|
|
||||||
|
#define CHKALLOWED() do{if(ForbidObservations || BadWeather){return RESULT_FAIL;}}while(0)
|
||||||
|
|
||||||
/////// handlers
|
/////// handlers
|
||||||
// unixt - send to ALL clients
|
// unixt - send to ALL clients
|
||||||
static sl_sock_hresult_e dtimeh(sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
static sl_sock_hresult_e dtimeh(sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
||||||
@@ -60,7 +74,7 @@ static sl_sock_hresult_e statush(sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ co
|
|||||||
sl_sock_sendstrmessage(c, buf);
|
sl_sock_sendstrmessage(c, buf);
|
||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
static const char *textst(int coverstate){
|
const char *textst(int coverstate){
|
||||||
switch(coverstate){
|
switch(coverstate){
|
||||||
case COVER_INTERMEDIATE: return "intermediate";
|
case COVER_INTERMEDIATE: return "intermediate";
|
||||||
case COVER_OPENED: return "opened";
|
case COVER_OPENED: return "opened";
|
||||||
@@ -110,16 +124,19 @@ static sl_sock_hresult_e domecmd(dome_cmd_t cmd){
|
|||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
static sl_sock_hresult_e opendome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
static sl_sock_hresult_e opendome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
||||||
|
CHKALLOWED();
|
||||||
return domecmd(DOME_OPEN);
|
return domecmd(DOME_OPEN);
|
||||||
}
|
}
|
||||||
static sl_sock_hresult_e closedome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
static sl_sock_hresult_e closedome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
||||||
return domecmd(DOME_CLOSE);
|
return domecmd(DOME_CLOSE);
|
||||||
}
|
}
|
||||||
static sl_sock_hresult_e stopdome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
static sl_sock_hresult_e stopdome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){
|
||||||
|
CHKALLOWED(); // don't allow to stop closing on forbidden state
|
||||||
return domecmd(DOME_STOP);
|
return domecmd(DOME_STOP);
|
||||||
}
|
}
|
||||||
// half open/close
|
// half open/close
|
||||||
static sl_sock_hresult_e halfmove(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){
|
static sl_sock_hresult_e halfmove(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){
|
||||||
|
CHKALLOWED();
|
||||||
char buf[128];
|
char buf[128];
|
||||||
int N = item->key[sizeof(CMD_HALF) - 1] - '0';
|
int N = item->key[sizeof(CMD_HALF) - 1] - '0';
|
||||||
if(N < 1 || N > 2) return RESULT_BADKEY;
|
if(N < 1 || N > 2) return RESULT_BADKEY;
|
||||||
@@ -196,6 +213,7 @@ void server_run(sl_socktype_e type, const char *node, sl_tty_t *serial){
|
|||||||
LOGERR("server_run(): wrong parameters");
|
LOGERR("server_run(): wrong parameters");
|
||||||
ERRX("server_run(): wrong parameters");
|
ERRX("server_run(): wrong parameters");
|
||||||
}
|
}
|
||||||
|
weather_data_t weather;
|
||||||
dome_serialdev(serial);
|
dome_serialdev(serial);
|
||||||
s = sl_sock_run_server(type, node, -1, handlers);
|
s = sl_sock_run_server(type, node, -1, handlers);
|
||||||
if(!s) ERRX("Can't create socket and/or run threads");
|
if(!s) ERRX("Can't create socket and/or run threads");
|
||||||
@@ -203,14 +221,59 @@ void server_run(sl_socktype_e type, const char *node, sl_tty_t *serial){
|
|||||||
sl_sock_maxclhandler(s, toomuch);
|
sl_sock_maxclhandler(s, toomuch);
|
||||||
sl_sock_connhandler(s, connected);
|
sl_sock_connhandler(s, connected);
|
||||||
sl_sock_dischandler(s, disconnected);
|
sl_sock_dischandler(s, disconnected);
|
||||||
|
double tnow = sl_dtime(), tweather = 0.;
|
||||||
|
int cmdclosed = 0;
|
||||||
while(s && s->connected){
|
while(s && s->connected){
|
||||||
if(!s->rthread){
|
if(!s->rthread){
|
||||||
LOGERR("Server handlers thread is dead");
|
LOGERR("Server handlers thread is dead");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(tnow - tweather > WEATH_POLL){
|
||||||
|
if(0 == get_weather_data(&weather)){ // got OK -> check if observations are forbidden
|
||||||
|
tweather = tnow;
|
||||||
|
int bad = 0;
|
||||||
|
if((double)weather.last_update - tnow > WEATHER_LOST) bad = 1;
|
||||||
|
if(weather.forceoff || weather.rain || weather.weather > WEATHER_BAD) bad = 1;
|
||||||
|
if(bad) BadWeather = 1;
|
||||||
|
else BadWeather = 0;
|
||||||
|
}else{
|
||||||
|
if(tnow - tweather > WEATHER_LOST) BadWeather = 1; // lost weather IPC
|
||||||
|
}
|
||||||
|
}
|
||||||
// finite state machine polling
|
// finite state machine polling
|
||||||
dome_poll(DOME_POLL, 0);
|
dome_poll(DOME_POLL, 0);
|
||||||
|
if(ForbidObservations || BadWeather){
|
||||||
|
if(0 == cmdclosed){
|
||||||
|
if(DOME_S_ERROR != dome_poll(DOME_CLOSE, 0)){
|
||||||
|
LOGERR("Send command 'close' due to forbidden state");
|
||||||
|
cmdclosed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sl_sock_delete(&s);
|
sl_sock_delete(&s);
|
||||||
ERRX("Server handlers thread is dead");
|
ERRX("Server handlers thread is dead");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopserver(){
|
||||||
|
if(s && s->connected){
|
||||||
|
s->connected = 0;
|
||||||
|
usleep(5000);
|
||||||
|
if(s) sl_sock_delete(&s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void forbid_observations(int forbid){
|
||||||
|
if(forbid){
|
||||||
|
ForbidObservations = true;
|
||||||
|
LOGWARN("Got forbidden signal");
|
||||||
|
}else{
|
||||||
|
ForbidObservations = false;
|
||||||
|
LOGWARN("Got allowed signal");
|
||||||
|
}
|
||||||
|
DBG("Change ForbidObservations=%d", forbid);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_forbidden(){
|
||||||
|
return (ForbidObservations || BadWeather);
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,4 +20,13 @@
|
|||||||
|
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
// size of weather/status buffers
|
||||||
|
#define STATBUF_SZ 256
|
||||||
|
// dome polling interval (clear watchdog & get status)
|
||||||
|
#define T_INTERVAL (5.0)
|
||||||
|
|
||||||
void server_run(sl_socktype_e type, const char *node, sl_tty_t *serial);
|
void server_run(sl_socktype_e type, const char *node, sl_tty_t *serial);
|
||||||
|
const char *textst(int coverstate);
|
||||||
|
void stopserver();
|
||||||
|
void forbid_observations(int forbid);
|
||||||
|
int get_forbidden();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 18.0.0, 2026-04-01T11:06:44. -->
|
<!-- Written by QtCreator 19.0.1, 2026-05-15T14:02:48. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
@@ -155,6 +155,7 @@
|
|||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
@@ -191,6 +192,7 @@
|
|||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
|||||||
@@ -136,10 +136,6 @@ int main(int argc, char **argv){
|
|||||||
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
if(G.logfile) OPENLOG(G.logfile, lvl, 1);
|
if(G.logfile) OPENLOG(G.logfile, lvl, 1);
|
||||||
LOGMSG("Started");
|
LOGMSG("Started");
|
||||||
if(!term_open(G.termpath, G.serspeed, G.sertmout)){
|
|
||||||
LOGERR("Can't open %s", G.termpath);
|
|
||||||
ERRX("Fatal error");
|
|
||||||
}
|
|
||||||
signal(SIGTERM, signals);
|
signal(SIGTERM, signals);
|
||||||
signal(SIGINT, signals);
|
signal(SIGINT, signals);
|
||||||
signal(SIGQUIT, signals);
|
signal(SIGQUIT, signals);
|
||||||
@@ -163,6 +159,10 @@ int main(int argc, char **argv){
|
|||||||
// react for USRx only in child
|
// react for USRx only in child
|
||||||
signal(SIGUSR1, signals);
|
signal(SIGUSR1, signals);
|
||||||
signal(SIGUSR2, signals);
|
signal(SIGUSR2, signals);
|
||||||
|
if(!term_open(G.termpath, G.serspeed, G.sertmout)){
|
||||||
|
LOGERR("Can't open %s", G.termpath);
|
||||||
|
ERRX("Fatal error");
|
||||||
|
}
|
||||||
runserver(G.isunix, G.node, G.maxclients);
|
runserver(G.isunix, G.node, G.maxclients);
|
||||||
LOGERR("Server error -> exit");
|
LOGERR("Server error -> exit");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ void runserver(int isunix, const char *node, int maxclients){
|
|||||||
if(bad) BadWeather = 1;
|
if(bad) BadWeather = 1;
|
||||||
else BadWeather = 0;
|
else BadWeather = 0;
|
||||||
}else{
|
}else{
|
||||||
if(tweather - tnow > WEATHER_LOST) BadWeather = 1; // lost weather IPC
|
if(tnow - tweather > WEATHER_LOST) BadWeather = 1; // lost weather IPC
|
||||||
}
|
}
|
||||||
if(poll_device()){
|
if(poll_device()){
|
||||||
tgot = tnow;
|
tgot = tnow;
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
badsky=1700
|
|
||||||
[ $# = 1 ] && badsky=$1
|
|
||||||
|
|
||||||
export http_proxy=""
|
|
||||||
|
|
||||||
Q="192.168.70.33:12345"
|
|
||||||
ANS=$(curl $Q 2>/dev/null)
|
|
||||||
retval=$?
|
|
||||||
[ $retval -ne "0" ] && exit $retval
|
|
||||||
[ "$ANS" = "No data" ] && exit 2
|
|
||||||
Rain=1
|
|
||||||
Clouds=0
|
|
||||||
Wind=100
|
|
||||||
eval $ANS
|
|
||||||
retval=0
|
|
||||||
clouds=$(echo "$Clouds" | sed 's/\..*//g')
|
|
||||||
wind=$(echo "$Wind" | sed 's/\..*//g')
|
|
||||||
[ $Rain -ne "0" ] && retval=1
|
|
||||||
[ $clouds -lt "$badsky" ] && retval=1
|
|
||||||
[ $wind -gt "15" ] && retval=1
|
|
||||||
echo "$ANS"
|
|
||||||
exit $retval
|
|
||||||
Reference in New Issue
Block a user