diff options
author | Dan McGee <dpmcgee@gmail.com> | 2011-11-16 01:25:08 -0600 |
---|---|---|
committer | Dan McGee <dpmcgee@gmail.com> | 2011-11-16 01:25:08 -0600 |
commit | 5b4ec0c382bfd394e9f35c94f424b43ba5d814f6 (patch) | |
tree | 0c640ca8b703f09a67de2cb331b8ba63198b64bf | |
parent | 83685c310ff3c7110b49aa34841873e963bcbec3 (diff) | |
download | onkyocontrol-5b4ec0c382bfd394e9f35c94f424b43ba5d814f6.tar.gz onkyocontrol-5b4ec0c382bfd394e9f35c94f424b43ba5d814f6.zip |
Write zone sleep status messages at 60-second intervals
This emulates what the normal sleep timer does on the receiver.
Signed-off-by: Dan McGee <dpmcgee@gmail.com>
-rw-r--r-- | command.c | 39 | ||||
-rw-r--r-- | onkyo.c | 39 | ||||
-rw-r--r-- | onkyo.h | 3 |
3 files changed, 64 insertions, 17 deletions
@@ -450,13 +450,31 @@ static int handle_sleep(struct receiver *rcvr, return cmd_attempt(rcvr, cmd, cmdstr); } +int write_fakesleep_status(struct receiver *rcvr, + struct timeval now, char zone) +{ + long mins; + time_t when; + char msg[BUF_SIZE]; + + if(zone == '2') + when = rcvr->zone2_sleep.tv_sec; + else if(zone == '3') + when = rcvr->zone3_sleep.tv_sec; + else + return - 1; + + mins = when > now.tv_sec ? (when - now.tv_sec + 59) / 60 : 0; + snprintf(msg, sizeof(msg), "OK:zone%csleep:%ld\n", zone, mins); + write_to_connections(rcvr, msg); + return 0; +} + static int handle_fakesleep(struct receiver *rcvr, const struct command *cmd, const char *arg) { struct timeval now; - long mins; char *test; - char msg[128]; char zone; gettimeofday(&now, NULL); @@ -466,14 +484,7 @@ static int handle_fakesleep(struct receiver *rcvr, return(-1); if(!arg || strcmp(arg, "status") == 0) { - time_t when = 0; - - if(zone == '2') - when = rcvr->zone2_sleep.tv_sec; - else if(zone == '3') - when = rcvr->zone3_sleep.tv_sec; - - mins = when > now.tv_sec ? (when - now.tv_sec + 59) / 60 : 0; + /* do nothing with the arg, we'll end up writing a message */ } else if(strcmp(arg, "off") == 0) { /* clear out any future receiver set sleep time */ if(zone == '2') { @@ -483,10 +494,9 @@ static int handle_fakesleep(struct receiver *rcvr, rcvr->zone3_sleep.tv_sec = 0; rcvr->zone3_sleep.tv_usec = 0; } - mins = 0; } else { /* otherwise we probably have a number */ - mins = strtol(arg, &test, 10); + long mins = strtol(arg, &test, 10); if(*test != '\0') { /* parse error, not a number */ return(-1); @@ -504,9 +514,8 @@ static int handle_fakesleep(struct receiver *rcvr, } } - snprintf(msg, sizeof(msg), "OK:zone%csleep:%ld\n", zone, mins); - write_to_connections(rcvr, msg); - return(0); + write_fakesleep_status(rcvr, now, zone); + return 0; } static int handle_memory(struct receiver *rcvr, @@ -270,8 +270,9 @@ static void show_status(void) r->power & MAIN_POWER ? "ON" : "off", r->power & ZONE2_POWER ? "ON" : "off", r->power & ZONE3_POWER ? "ON" : "off"); - printf("sleep: : zone2 (%ld) zone3 (%ld)\n", - r->zone2_sleep.tv_sec, r->zone3_sleep.tv_sec); + printf("sleep: : zone2 (%ld) zone3 (%ld) update (%ld)\n", + r->zone2_sleep.tv_sec, r->zone3_sleep.tv_sec, + r->next_sleep_update.tv_sec); printf("cmds sent : %lu\n", r->cmds_sent); printf("msgs received : %lu\n", r->msgs_received); @@ -956,6 +957,24 @@ int main(int argc, char *argv[]) r->zone3_sleep.tv_usec = 0; } } + /* if we still have sleep timers, we'll wake up at 60-second + * intervals to give an update on the virtual sleep timers */ + if(r->zone2_sleep.tv_sec || r->zone3_sleep.tv_sec) { + if(!r->next_sleep_update.tv_sec) { + /* set the next sleep update the first time, it isn't + * currently running */ + r->next_sleep_update = now; + r->next_sleep_update.tv_sec += 60; + } + diff_timeval(&r->next_sleep_update, &now, &diff); + if(diff.tv_sec >= 0 && diff.tv_usec > 0) { + timeoutval = min_timeval(&timeoutval, &diff); + } + } else { + /* clear any sleep update if we have no timers running */ + r->next_sleep_update.tv_sec = 0; + r->next_sleep_update.tv_usec = 0; + } /* check for write possibility if we have commands in queue */ if(r->queue) { @@ -1022,6 +1041,22 @@ int main(int argc, char *argv[]) if(r->queue != NULL && FD_ISSET(r->fd, &writefds)) { rcvr_send_command(r); } + /* do we need to send a sleep status update? */ + if(r->next_sleep_update.tv_sec) { + struct timeval diff; + gettimeofday(&now, NULL); + diff_timeval(&now, &r->next_sleep_update, &diff); + if(diff.tv_sec >= 0 && diff.tv_usec > 0) { + if(r->zone2_sleep.tv_sec > 0) + write_fakesleep_status(r, now, '2'); + if(r->zone3_sleep.tv_sec > 0) + write_fakesleep_status(r, now, '3'); + /* now that we've notified, schedule it again not 60 + * seconds from now, but 60 seconds absolute from when we + * should have notified */ + r->next_sleep_update.tv_sec += 60; + } + } r = r->next; } /* check to see if we have listeners ready to accept */ @@ -63,6 +63,7 @@ struct receiver { struct timeval last_cmd; struct timeval zone2_sleep; struct timeval zone3_sleep; + struct timeval next_sleep_update; struct cmdqueue *queue; struct receiver *next; }; @@ -84,6 +85,8 @@ void init_commands(void); void free_commands(void); int process_command(struct receiver *rcvr, const char *str); int is_power_command(const char *cmd); +int write_fakesleep_status(struct receiver *rcvr, + struct timeval now, char zone); /* util.c - trivial utility functions */ int xopen(const char *path, int oflag); |