From a888b42eb62ac83ecdb262f10d3748c1528b21f0 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Wed, 4 Jun 2025 10:35:30 +0300 Subject: [PATCH] it works --- Daemons/domedaemon-astrosib/dome.c | 32 ++- Daemons/domedaemon-astrosib/dome.h | 7 +- .../domedaemon-astrosib.creator.user | 184 ++++++++++++++++++ Daemons/domedaemon-astrosib/main.c | 2 +- Daemons/domedaemon-astrosib/server.c | 51 ++++- 5 files changed, 264 insertions(+), 12 deletions(-) create mode 100644 Daemons/domedaemon-astrosib/domedaemon-astrosib.creator.user diff --git a/Daemons/domedaemon-astrosib/dome.c b/Daemons/domedaemon-astrosib/dome.c index 74dd609..e5a1638 100644 --- a/Daemons/domedaemon-astrosib/dome.c +++ b/Daemons/domedaemon-astrosib/dome.c @@ -150,10 +150,25 @@ static int runcmd(const char *cmd, const char *par){ // check current state and turn on/off relay if need static void chkrelay(){ + static dome_state_t oldstate = DOME_S_MOVING; + static double t0 = 0.; if(state != DOME_S_MOVING) return; if(dome_status.coverstate[0] == COVER_INTERMEDIATE || - dome_status.coverstate[1] == COVER_INTERMEDIATE) return; // still moving - // OK, we are on place - turn off motors' power + dome_status.coverstate[1] == COVER_INTERMEDIATE){ // still moving + oldstate = DOME_S_MOVING; + return; + } + DBG("state=%d, oldstate=%d", state, oldstate); + // OK, we are on place - turn off motors' power after 5 seconds + if(oldstate == DOME_S_MOVING){ // just stopped - fire pause + t0 = sl_dtime(); + oldstate = DOME_S_IDLE; + DBG("START 5s pause"); + return; + }else{ // check pause + if(sl_dtime() - t0 < POWER_STOP_TIMEOUT) return; + } + DBG("5s out -> turn off power"); char buf[128]; snprintf(buf, 127, "%s%d,%d", ASIB_CMD_RELAY, MOTRELAY_NO, MOTRELAY_OFF); if(serial_write(buf, buf, 128) && check_status()){ @@ -161,6 +176,7 @@ static void chkrelay(){ if(dome_status.relay[MOTRELAY_NO-1] == MOTRELAY_OFF){ DBG("OK state->IDLE"); state = DOME_S_IDLE; + oldstate = DOME_S_MOVING; } } } @@ -222,23 +238,23 @@ dome_state_t dome_poll(dome_cmd_t cmd, int par){ case DOME_CLOSE: if(!runcmd(ASIB_CMD_CLOSE, NULL)) goto ret; break; - case DOME_OPEN_ONE: + case DOME_OPEN_ONE: // due to bug in documentation, 0 - OPEN if(par < 1 || par > 2) goto ret; - snprintf(buf, 127, "%d 90", par); + snprintf(buf, 127, "%d,0", par-1); if(!runcmd(ASIB_CMD_MOVEONE, buf)) goto ret; break; - case DOME_CLOSE_ONE: + case DOME_CLOSE_ONE: // due to bug in documentation, 90 - CLOSE if(par < 1 || par > 2) goto ret; - snprintf(buf, 127, "%d 0", par); + snprintf(buf, 127, "%d,90", par-1); if(!runcmd(ASIB_CMD_MOVEONE, buf)) goto ret; break; case DOME_RELAY_ON: - if(par < 1 || par > 3) goto ret; + if(par < NRELAY_MIN || par > NRELAY_MAX) goto ret; snprintf(buf, 127, "%d,1", par); if(!runcmd(ASIB_CMD_RELAY, buf)) goto ret; break; case DOME_RELAY_OFF: - if(par < 1 || par > 3) goto ret; + if(par < NRELAY_MIN || par > NRELAY_MAX) goto ret; snprintf(buf, 127, "%d,0", par); if(!runcmd(ASIB_CMD_RELAY, buf)) goto ret; break; diff --git a/Daemons/domedaemon-astrosib/dome.h b/Daemons/domedaemon-astrosib/dome.h index 50bf17b..9fb9571 100644 --- a/Daemons/domedaemon-astrosib/dome.h +++ b/Daemons/domedaemon-astrosib/dome.h @@ -22,6 +22,9 @@ #define NRELAY_MIN 1 #define NRELAY_MAX 3 +// pause to clear power after stop - 5 seconds +#define POWER_STOP_TIMEOUT (5.) + // dome finite state machine state typedef enum{ DOME_S_IDLE, // idle, motors disabled @@ -43,13 +46,13 @@ typedef enum{ // cover states enum{ - COVER_INTERMEDIATE = 1, + COVER_INTERMEDIATE = 0, COVER_OPENED = 2, COVER_CLOSED = 3 }; typedef struct{ - int coverstate[2]; // north/south covers state (3 - closed, 2 - opened, 1 - intermediate) + int coverstate[2]; // north/south covers state (3 - closed, 2 - opened, 0 - intermediate) int encoder[2]; // encoders values float Tin; // temperatures (unavailable) float Tout; diff --git a/Daemons/domedaemon-astrosib/domedaemon-astrosib.creator.user b/Daemons/domedaemon-astrosib/domedaemon-astrosib.creator.user new file mode 100644 index 0000000..57966c2 --- /dev/null +++ b/Daemons/domedaemon-astrosib/domedaemon-astrosib.creator.user @@ -0,0 +1,184 @@ + + + + + + EnvironmentId + {cf63021e-ef53-49b0-b03b-2f2570cdf3b6} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + true + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + KOI8-R + false + 4 + false + 0 + 80 + true + true + 1 + 0 + false + false + false + 1 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + true + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 4 + true + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {91347f2c-5221-46a7-80b1-0a054ca02f79} + 0 + 0 + 0 + + /home/eddy/Docs/SAO/10micron/C-sources/domedaemon-astrosib + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + По умолчанию + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Развёртывание + Развёртывание + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + 0 + true + + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/Daemons/domedaemon-astrosib/main.c b/Daemons/domedaemon-astrosib/main.c index 530cdf3..903142c 100644 --- a/Daemons/domedaemon-astrosib/main.c +++ b/Daemons/domedaemon-astrosib/main.c @@ -110,5 +110,5 @@ int main(int argc, char **argv){ sl_tty_tmout(DEFAULT_SERTMOUT); server_run(type, G.node, serial); LOGERR("Unreacheable code reached!"); - return 0; + return 1; } diff --git a/Daemons/domedaemon-astrosib/server.c b/Daemons/domedaemon-astrosib/server.c index 31d2b8e..750de51 100644 --- a/Daemons/domedaemon-astrosib/server.c +++ b/Daemons/domedaemon-astrosib/server.c @@ -33,6 +33,10 @@ #define CMD_STATUS "status" #define CMD_STATUST "statust" #define CMD_RELAY "relay" +#define CMD_OPEN "open" +#define CMD_CLOSE "close" +#define CMD_STOP "stop" +#define CMD_HALF "half" // main socket static sl_sock_t *s = NULL; @@ -81,7 +85,6 @@ static sl_sock_hresult_e statusth(sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ c } // relay on/off static sl_sock_hresult_e relays(int Nrelay, int Stat){ - if(Nrelay < NRELAY_MIN|| Nrelay > NRELAY_MAX) return RESULT_BADKEY; dome_cmd_t cmd = Stat ? DOME_RELAY_ON : DOME_RELAY_OFF; if(DOME_S_ERROR == dome_poll(cmd, Nrelay)) return RESULT_FAIL; return RESULT_OK; @@ -89,6 +92,7 @@ static sl_sock_hresult_e relays(int Nrelay, int Stat){ static sl_sock_hresult_e relay(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){ char buf[128]; int N = item->key[sizeof(CMD_RELAY) - 1] - '0'; + if(N < NRELAY_MIN|| N > NRELAY_MAX) return RESULT_BADKEY; if(!req || !*req){ // getter dome_status_t dome_status; double lastt = get_dome_status(&dome_status); @@ -100,6 +104,46 @@ static sl_sock_hresult_e relay(sl_sock_t *c, sl_sock_hitem_t *item, const char * int Stat = *req - '0'; return relays(N, Stat); } +// dome open/close/stop +static sl_sock_hresult_e domecmd(dome_cmd_t cmd){ + if(DOME_S_ERROR == dome_poll(cmd, 0)) return RESULT_FAIL; + return RESULT_OK; +} +static sl_sock_hresult_e opendome(_U_ sl_sock_t *c, _U_ sl_sock_hitem_t *item, _U_ const char *req){ + 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){ + 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){ + return domecmd(DOME_STOP); +} +// half open/close +static sl_sock_hresult_e halfmove(sl_sock_t *c, sl_sock_hitem_t *item, const char *req){ + char buf[128]; + int N = item->key[sizeof(CMD_HALF) - 1] - '0'; + if(N < 1 || N > 2) return RESULT_BADKEY; + if(!req || !*req){ // getter + dome_status_t dome_status; + double lastt = get_dome_status(&dome_status); + if(sl_dtime() - lastt > STATUS_MAX_AGE) return RESULT_FAIL; + int s = dome_status.coverstate[N-1]; + int S = -1; + switch(s){ + case COVER_OPENED: S = 1; break; + case COVER_CLOSED: S = 0; break; + default: break; + } + snprintf(buf, 127, "%s=%d\n", item->key, S); + sl_sock_sendstrmessage(c, buf); + return RESULT_SILENCE; + } + int Stat = *req - '0'; + dome_cmd_t cmd = Stat ? DOME_OPEN_ONE : DOME_CLOSE_ONE; + green("\n\nstat=%d, cmd=%d, N=%d\n\n", Stat, cmd, N); + if(DOME_S_ERROR == dome_poll(cmd, N)) return RESULT_FAIL; + return RESULT_OK; +} // and all handlers collection static sl_sock_hitem_t handlers[] = { @@ -109,6 +153,11 @@ static sl_sock_hitem_t handlers[] = { {relay, CMD_RELAY "1", "turn on/off (=1/0) relay 1", NULL}, {relay, CMD_RELAY "2", "turn on/off (=1/0) relay 2", NULL}, {relay, CMD_RELAY "3", "turn on/off (=1/0) relay 3", NULL}, + {opendome, CMD_OPEN, "open dome", NULL}, + {closedome, CMD_CLOSE, "close dome", NULL}, + {stopdome, CMD_STOP, "stop moving", NULL}, + {halfmove, CMD_HALF "1", "open/close (=1/0) north half of dome", NULL}, + {halfmove, CMD_HALF "2", "open/close (=1/0) south half of dome", NULL}, {NULL, NULL, NULL, NULL} };