diff --git a/Control/Makefile b/Control/Makefile
index cd4cc45526f0b7a9fb7cb38002be7c6354fe53db..a5d645ef165584191a8c97105d6508465127ba04 100644
--- a/Control/Makefile
+++ b/Control/Makefile
@@ -63,7 +63,7 @@ OPT = s
 # If there is more than one source file, append them above, or modify and
 # uncomment the following:
 
-SRC = main.c door.c power_monitor.c ../common/adc.c status_output.c keystore.c cardreader_interface.c random.c ../common/sha1/sha1.c ../common/i2c_master.c ../common/transport/transport.c shell/shell.c shell/readline.c
+SRC = main.c door.c power_monitor.c ../common/adc.c status_output.c keystore.c cardreader_interface.c random.c ds1307.c log.c ../common/sha1/sha1.c ../common/i2c_master.c ../common/transport/transport.c shell/shell.c shell/readline.c
 
 # List Assembler source files here.
 # Make them always end in a capital .S.  Files ending in a lowercase .s
@@ -146,12 +146,13 @@ LDFLAGS += -lm
 # to get a full listing.
 #
 
-AVRDUDE_PROGRAMMER = stk500v2
-#AVRDUDE_PROGRAMMER = usbtiny
+#AVRDUDE_PROGRAMMER = stk500v2
+#AVRDUDE_PROGRAMMER = dragon_isp
+AVRDUDE_PROGRAMMER = usbtiny
 # AVRDUDE_PROGRAMMER = USBasp
 
-#AVRDUDE_PORT = usb		# programmer connected to USB port
-AVRDUDE_PORT = /dev/ttyUSB0	# programmer connected to serial device
+AVRDUDE_PORT = usb		# programmer connected to USB port
+#AVRDUDE_PORT = /dev/ttyUSB0	# programmer connected to serial device
 #AVRDUDE_PORT = lpt1		# programmer connected to parallel port
 
 AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex $(FUSE_BITS)
diff --git a/Control/door.c b/Control/door.c
index 5c6317af8c4b6cbfc2279ae1036f1706611827f3..479fa57e526367400d807693a36593f38460c35e 100644
--- a/Control/door.c
+++ b/Control/door.c
@@ -1,10 +1,24 @@
 #include "door.h"
+#include "log.h"
 
 uint8_t door_read_pin_status(void);
 uint8_t door_update_status(uint8_t sensor_status);
 uint8_t is_alarm_status(uint8_t door_status);
 
-char* status_names[] = {"Unlocked", "Locked", "Open", "Alarm wire open", "Alarm", "Unlocking...", "Locking..."};
+char status_unlocked[]  PROGMEM = "Unlocked";
+char status_locked[]    PROGMEM = "Locked";
+char status_open[]      PROGMEM = "Open";
+char status_alarm_cut[] PROGMEM = "Alarm wire open";
+char status_alarm[]     PROGMEM = "Alarm";
+char status_unlocking[] PROGMEM = "Unlocking...";
+char status_locking[]   PROGMEM = "Locking...";
+char* status_names[] PROGMEM = {status_unlocked,
+                                status_locked,
+                                status_open,
+                                status_alarm_cut,
+                                status_alarm,
+                                status_unlocking,
+                                status_locking};
 
 volatile uint8_t door_status;
 
@@ -47,6 +61,7 @@ void door_tick(void){
 		if (door_command_wait_timeout == 0){
 			
 			printf_P(PSTR("Error: Door command timeout\n"));
+			log_append(LOG_EVENT_DOOR_COMMAND_TIMEOUT, 0);
 			
 			//TODO: Retry (and turn keymatic power on if currently off)
 			
@@ -85,6 +100,10 @@ uint8_t door_update_status(uint8_t sensor_status){
 	
 	if (is_alarm_status(new_door_status)) new_door_status |= DOOR_STATUS_ALARM;
 	
+	if (new_door_status & DOOR_STATUS_ALARM){
+		log_append( (door_status & DOOR_STATUS_ALARM) ? LOG_EVENT_ALARM_CHANGED : LOG_EVENT_ALARM_RAISED, 0);
+	}
+	
 	return new_door_status;
 }
 
@@ -170,6 +189,8 @@ uint8_t lock_checked(void){
 uint8_t door_clear_alarm(void){
 	if (is_alarm_status(door_status)) return 0;
 	
+	log_append(LOG_EVENT_ALARM_DISABLED, 0);
+	
 	door_status &= (uint8_t)~DOOR_STATUS_ALARM;
 	return 1;
 }
@@ -193,10 +214,10 @@ void door_write_status(void){
 		if (status & (1 << i)){
 			if (c) printf_P(PSTR(","));
 			c++;
-			printf(status_names[i]);
+			printf_P((PGM_P)pgm_read_word(&(status_names[i])));
 		}
 	}
 	
 	if (status == 0) printf_P(PSTR("Unknown"));
-	printf_P(PSTR("\n"));
+// 	printf_P(PSTR(" "));
 }
diff --git a/Control/main.c b/Control/main.c
index 7e23bd48354796bf9d238faad6a1109d857f87f8..8df594bd64126ed02e67b160b55a0eabb3fd6344 100644
--- a/Control/main.c
+++ b/Control/main.c
@@ -5,6 +5,7 @@
 #include <avr/wdt.h>
 #include <avr/sleep.h>
 
+
 #include "../common/simple_timer.h"
 
 #include "door.h"
@@ -17,7 +18,7 @@
 
 #include "cardreader_interface.h"
 #include "keystore.h"
-
+#include "log.h"
 
 #define POWER_SWITCH_TIME 200 //2s
 #define POWER_SWITCH_DONE 0xFF
@@ -35,6 +36,7 @@ void tick(void){
 	power_tick();
 	status_tick();
 	cardreader_tick();
+	shell_tick();
 	
 	if (power_switch_time != 0 && power_switch_time != POWER_SWITCH_DONE && power_switch_time != POWER_SWITCH_BOOTUP){
 		power_switch_time--;
@@ -47,8 +49,8 @@ ISR(PCINT0_vect){
 
 void sleep(void){
 	wdt_disable();
-	set_sleep_mode(SLEEP_MODE_IDLE);
-	sleep_mode();
+// 	set_sleep_mode(SLEEP_MODE_IDLE);
+// 	sleep_mode();
 	wdt_enable(WDTO_8S);
 }
 
@@ -82,6 +84,7 @@ int main(void){
 	keystore_init();
 	printf_P(PSTR("Keystore initialized\n"));
 	
+	//log_append(LOG_EVENT_STARTUP, 0);
 	
 	shell_show_welcome_prompt();
 	
@@ -105,6 +108,7 @@ int main(void){
 			status_update(1, 0); //door status update
 		}
 		
+		power_process();
 		power_status = power_get_status();
 		if (power_status != last_power_status){
 			last_power_status = power_status;
diff --git a/Control/power_monitor.c b/Control/power_monitor.c
index ce070c0fcdd09c5ea6fb1cc7c87179aeb4d77a38..52036e2b292e9865d338692f66f4a0184ed2a0da 100644
--- a/Control/power_monitor.c
+++ b/Control/power_monitor.c
@@ -1,4 +1,5 @@
 #include "power_monitor.h"
+#include "log.h"
 
 #define POWER_BATT_POLL_INTERVAL 100  //100*10ms = 1sec
 volatile uint8_t power_batt_update_timer = 0;
@@ -27,9 +28,22 @@ void power_tick(void){
 	}
 }
 
-uint8_t power_get_status(void){
+void power_process(void){
 	if (power_batt_shutdown_disable_timer == 0){ //Only check of AC pin if we don't pull it up ourself
-		SET_BIT(power_status, POWER_STATUS_AC_ON,  (POWER_PIN & (1 << POWER_PIN_AC_ON)) != 0);
+
+		//Check AC Status
+		uint8_t ac = (POWER_PIN & (1 << POWER_PIN_AC_ON)) != 0;
+		if (ac)	{ //AC On
+			if ((power_status & POWER_STATUS_AC_ON) == 0){ //Was off
+				log_append(LOG_EVENT_AC_RETURN, main_batt_voltage);
+				power_status |= POWER_STATUS_AC_ON;
+			}
+		} else { //AC off 
+			if ((power_status & POWER_STATUS_AC_ON) != 0){ //was on
+				log_append(LOG_EVENT_AC_FAIL, main_batt_voltage);
+				power_status &= ~POWER_STATUS_AC_ON;
+			}
+		}
 	}
 	
 	if (power_batt_update_timer == 0){
@@ -37,6 +51,9 @@ uint8_t power_get_status(void){
 		power_update_batt_voltage();
 	}
 	
+}
+
+uint8_t power_get_status(void){
 	return power_status;
 }
 
@@ -49,17 +66,32 @@ void power_disable_battery_shutdown(void){
 
 void power_enable_battery_shutdown(void){
 	//Float AC pin high to disable USV low battery shutdown
-// 	POWER_DDR  &= ~(1 << POWER_PIN_AC_ON);
-// 	POWER_PORT &= ~(1 << POWER_PIN_AC_ON);
-// 	power_batt_shutdown_disable_timer = 0;
+	POWER_DDR  &= ~(1 << POWER_PIN_AC_ON);
+	POWER_PORT &= ~(1 << POWER_PIN_AC_ON);
+	power_batt_shutdown_disable_timer = 0;
 }
 
 void power_update_batt_voltage(void){
 	main_batt_voltage = ADC_read_voltage(POWER_PIN_MAIN_BATTERY_VOLTAGE, 1420);
 	keymatic_batt_voltage = ADC_read_voltage(POWER_PIN_KEYMATIC_BATTERY_VOLTAGE, 507);
 	
-	SET_BIT(power_status, POWER_STATUS_MAIN_BATT_LOW, main_batt_voltage < 1100);
-	SET_BIT(power_status, POWER_STATUS_KEYMATIC_BATT_LOW, keymatic_batt_voltage < 300);
+	if (main_batt_voltage < POWER_MAIN_BATT_LOW_VOLTAGE){
+		if ((power_status & POWER_STATUS_MAIN_BATT_LOW) == 0){
+			log_append(LOG_EVENT_MAIN_BATTERY_LOW, main_batt_voltage);
+			power_status |= POWER_STATUS_MAIN_BATT_LOW;
+		}
+	} else {
+		power_status &= ~POWER_STATUS_MAIN_BATT_LOW;
+	}
+	
+	if (keymatic_batt_voltage < POWER_KEYMATIC_BATT_LOW_VOLTAGE){
+		if ((power_status & POWER_STATUS_KEYMATIC_BATT_LOW) == 0){
+			log_append(LOG_EVENT_KEYMATIC_BATTERY_LOW, keymatic_batt_voltage);
+			power_status |= POWER_STATUS_KEYMATIC_BATT_LOW;
+		}
+	} else {
+		power_status &= ~POWER_STATUS_KEYMATIC_BATT_LOW;
+	}
 }
 
 void power_write_status(void){
@@ -79,5 +111,5 @@ void power_write_status(void){
 	}
 	if (power_status & POWER_STATUS_KEYMATIC_BATT_LOW) printf_P(PSTR(", LOW!"));
 	
-	printf_P(PSTR(")\n"));
+	printf_P(PSTR(")"));
 }
diff --git a/Control/power_monitor.h b/Control/power_monitor.h
index 612db5026a91235ec9c2123a907e472560498062..f21703dff4c22d6cba2560c744a240cc94d4f59d 100644
--- a/Control/power_monitor.h
+++ b/Control/power_monitor.h
@@ -20,8 +20,11 @@
 
 #define SET_BIT(x, b, v) {if (v) {x |= (b);} else {x &= ~(b);};}
 
+#define POWER_MAIN_BATT_LOW_VOLTAGE     1100  //*10mv
+#define POWER_KEYMATIC_BATT_LOW_VOLTAGE 300   //*10mv
 
 void power_init(void);
+void power_process(void);
 void power_tick(void);
 
 uint8_t power_get_status(void);
diff --git a/Control/status_output.c b/Control/status_output.c
index 6311073ee30b37cee6773b7dff29b8aa715ec164..27291a45e10655b5155a7565f2e333571bcdbbed 100644
--- a/Control/status_output.c
+++ b/Control/status_output.c
@@ -61,8 +61,8 @@ void status_update(uint8_t door_status_changed, uint8_t power_status_changed){
 	led_blink_fraction = (power_status & POWER_STATUS_AC_ON) ? (LED_BLINK_INTERVAL / 2) : (LED_BLINK_INTERVAL / 16); 
 	status_set_leds(power_status, door_status);
 	
-	if (door_status_changed) door_write_status();
-	if (power_status_changed) power_write_status();
+	if (door_status_changed)  {door_write_status(); printf_P(PSTR("\n"));}
+	if (power_status_changed) {power_write_status(); printf_P(PSTR("\n"));}
 }
 
 void status_process(){