/* * Copyright 1996, 1997, 1998, 1999 by Daniel B. Suthers, * Pleasanton Ca. 94588 USA * E-MAIL dbs@tanj.com * * You may freely copy, use, and distribute this software, * in whole or in part, subject to the following restrictions: * * 1) You may not charge money for it. * 2) You may not remove or alter this copyright notice. * 3) You may not claim you wrote it. * 4) If you make improvements (or other changes), you are requested * to send them to me, so there's a focal point for distributing * improved versions. * */ /* * Original code written for the cp290 series by Larry Campbell, * 73 Concord Street, Maynard MA 01754 USA. (maynard!campbell) */ #include #include #include #include "x10.h" #include #include extern int tty; extern int sptty; extern char *wdays[]; extern int i_am_relay; extern int x10_housecode; extern int verbose; extern unsigned int jul(); /* ARGSUSED */ int c_setclock(argc, argv) char *argv[]; { unsigned char data[9]; unsigned char buf[3]; char msgbuf[1000]; unsigned int n; unsigned int clear; struct tm *tp; time_t dtime; int was_tm_isdst; extern int usage(), xwrite(), exread(), check4poll(), get_status(); char hc2char(); char RCSID[]= "@(#) $Id: setclock.c,v 1.12 2003/03/17 01:40:32 dbs Exp dbs $\n"; display(RCSID); /* Argc == 1 means use system time. * Argc == 2 means parse a date from the input or reset the clock. */ if (argc < 1 || argc > 3) if( argc != 7 ) usage(E_2MANY); clear = 0; dtime = time(NULL); tp = localtime(&dtime); if( argc == 2 ) { if( strcmp( "reset", argv[1]) == 0 ) { clear = 1; } } if( argc == 3) { /* must be date information. Load it in the structure * and then remake the structure with the right time. */ if( sscanf(argv[2], "%2d%2d%2d%2d", &tp->tm_mon, &tp->tm_mday, &tp->tm_hour, &tp->tm_min) != 4) { printf(" Bad argument. Expected %s %s MMDDhhmm\n", argv[0], argv[1]); return(-1); } tp->tm_mon -= 1; /* tm month is 0 relative */ was_tm_isdst = tp->tm_isdst; /* save the current DST flag */ dtime = mktime(tp); /* reset day of week, julian */ if( dtime < 1 ) { printf("An error was encountered parsing the input %s\n", argv[2]); return(-1); } /* we want absolute time, but mktime will reset the hour as necessary, * to match daylight savings. * we undo that here. */ if( tp->tm_isdst != was_tm_isdst) { if( was_tm_isdst == 0 ) { dtime -= 3600; /* subtract an hour*/ } else { dtime += 3600; /* add an hour*/ } tp = localtime(&dtime); } } data[0] = 0x9b; /* CM11A timer download code */ data[1] = tp->tm_sec ; data[2] = tp->tm_min + (((tp->tm_hour) %2) * 60 ) ; /* minutes 0 - 119 */ data[3] = tp->tm_hour / 2 ; /* hour / 2 0 - 11 */ data[4] = tp->tm_yday % 256 ; /* mantisa of julian date */ data[5] = ((tp->tm_yday / 256 ) << 7); /* radix of julian date */ data[5] |= (0x01 << (tp->tm_wday)); /* bits 0-6 = single bit mask day */ /* of week ( smtwtfs ) */ data[6] = (x10_housecode << 4); data[6] |= clear; if (verbose) { sprintf(msgbuf, "would send %0x %0x %0x %0x %0x %0x %0x\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6]); if( i_am_relay == 1 ) syslog(LOG_ERR, msgbuf); else fprintf(stderr, msgbuf); } (void) xwrite(tty, (char *) data, 7); n = exread(sptty, buf, 1, 1); /* if( n == 1 ) { printf( "sum = %0x, returned = %0x\n", chksum(data,7), buf[0]); } */ if( argc == 2 || argc == 3 ) { check4poll(0,1); /* zero means to discard data */ get_status(); if( clear == 0) { if( i_am_relay != 1 ) (void) fprintf(stderr, "CM11A clock set to %s, %d:%02d\n", wdays[tp->tm_wday], tp->tm_hour, tp->tm_min); } else { if( i_am_relay != 1 ) (void) printf("CM11A house code set to %c\n", hc2char( x10_housecode)); } } return(0); }