Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

started implementing alarm logics

* small bugfixes
  • Loading branch information...
commit c14d2f1280d34a4c771f0f5e882e7409fffb22a9 1 parent b5fca41
@poelzi authored
Showing with 160 additions and 31 deletions.
  1. +3 −1 TODO
  2. +22 −11 db/alarm.py
  3. +114 −12 db/models.py
  4. +13 −4 settings.py
  5. +8 −3 tools/ez_chronos.py
View
4 TODO
@@ -1,3 +1,5 @@
• fix hero weather proxy
• make it translatable
-• unittests
+• unittests
+• allow the uberclockd to act as wireless update server
+• add command line tool to control server via rpc
View
33 db/alarm.py
@@ -13,12 +13,12 @@ def register(self, program):
"""
Register a new alarm clock program
"""
- if not program.nid:
- raise ValueError, "program id (nid) is not set"
- if program.nid in self.programs and self.programs[program.nid] != program:
- raise ValueError, "program id (nid) already exists"
+ if not program.key:
+ raise ValueError, "program id (key) is not set"
+ if program.key in self.programs and self.programs[program.key] != program:
+ raise ValueError, "program id (key) already exists"
- self.programs[program.nid] = program
+ self.programs[program.key] = program
def list_programs(self):
"""
@@ -32,15 +32,18 @@ def choices_programs(self):
Return a choices list used in django
"""
rv = []
- for program in self.programs.iteritems():
- rv.append((program.nid, program))
+ for key,program in self.programs.iteritems():
+ rv.append((key, program))
return rv
- def is_valid_program_id(self, nid):
+ def is_valid_program(self, key):
for program in self.programs.iteritems():
- if program.nid == nid:
+ if program.key == key:
return True
+ def get_program(self, key):
+ return self.programs.get(key, self.programs["basic"] )
+
def create_session(self, user_name, program):
pass
@@ -85,8 +88,9 @@ class BaseAlarm(object):
Base Class for all alarm logics
"""
# numeric id. must be unique and change never
- nid = None
- title = None
+ key = None
+ name = None
+ short_name = None
def __init__(self, manager, session):
self.manager = manager
@@ -110,3 +114,10 @@ def feed(self, entry):
Feed one new Entry into the Alarm program.
"""
pass
+
+class BasicAlarm(BaseAlarm):
+ key = "basic"
+ name = "Basic Alarm"
+ short_name = "basic"
+
+manager.register(BasicAlarm)
View
126 db/models.py
@@ -24,6 +24,17 @@
RF_ID_BIT_LENGHT = 3
+def get_user_or_default(user=None):
+ if user and isinstance(user, User):
+ return user
+ try:
+ return User.objects.get(username=user)
+ except User.DoesNotExist:
+ try:
+ return User.objects.get(username=settings.DEFAULT_USER)
+ except User.DoesNotExist:
+ return None
+
class Detector(models.Model):
"""
Device which messures the sleep state
@@ -36,6 +47,58 @@ class Detector(models.Model):
def __repr__(self):
return '<Detector %s >' %self.ident
+class UserProgramManager(models.Manager):
+ def get_program_for_user(self, user, id_):
+ obj, created = self.get_or_create(user = user, users_id = id_,
+ defaults = {
+ "user":user, "users_id":id_,
+ "alarm_key":settings.DEFAULT_ALARM
+ })
+ if created:
+ obj.save()
+ return obj
+
+ def get_users_default(self, user):
+ res = self.filter(user=user).order_by("-default", "users_id")
+ if not res:
+ return None
+ return res[0]
+
+class UserProgram(models.Model):
+ """
+ Maps a alarm program to user and his choosen id
+ """
+ user = models.ForeignKey(User, null=True, db_index=True)
+ users_id = models.IntegerField(null=False, db_index=True)
+ default = models.BooleanField(default=False)
+ alarm_key = models.CharField(null=False, max_length=30, choices=alarm.manager.choices_programs)
+ rname = models.CharField(max_length=30, null=True, blank=True)
+ short_name = models.CharField(max_length=5, null=True, blank=True)
+
+ settings = models.TextField()
+
+ objects = UserProgramManager()
+
+ class Meta:
+ unique_together = (("user", "users_id"),)
+
+ def _get_name(self):
+ if self.rname:
+ return self.rname
+ return alarm.manager.get_program(self.alarm_key).name
+
+ def _set_name(self, val):
+ self.rname = val
+
+ name = property(_get_name, _set_name)
+
+ @property
+ def program_class(self):
+ return alarm.manager.get_program(self.alarm_key)
+
+ def __unicode__(self):
+ return u"%s of %s" %(self.name, self.user)
+
class WakeupTime(models.Model):
"""
User saved wakeup times for shortcuts
@@ -94,7 +157,7 @@ class Session(models.Model):
stop = models.DateTimeField("Stop", null=False, auto_now_add=True, editable=False)
user = models.ForeignKey(User, null=True)
detector = models.ForeignKey(Detector, null=True)
- program = models.IntegerField("Program", default=0, choices=alarm.manager.choices_programs)
+ program = models.ForeignKey(UserProgram, null=True)
wakeup = models.DateTimeField("Wakeup", null=True)
rating = models.IntegerField("Rating", null=True)
deleted = models.BooleanField("Deleted", default=False)
@@ -103,14 +166,39 @@ class Session(models.Model):
new = models.BooleanField("Session has not yet run", default=False)
objects = SessionManager()
+
# Do we need this ?
#alone = models.BooleanField("Alone", null=True, default=True, help_text="Sleeping with someone else in the bed")
+# def __init__(self, *args, **kwargs):
+# if not "user" in kwargs:
+# if "detector" in kwargs:
+# kwargs["user"] = get_user_or_default(kwargs["device"].default_user)
+# else:
+# kwargs["user"] =
+# if not "program" in kwargs:
+# self.kwargs["program"] = UserProgram.objects.get_users_default(kwargs["user"])
+#
+# return super(Session, self).__init__(*args, **kwargs)
+
def save(self, *args, **kwargs):
super(Session, self).save(*args, **kwargs)
self.learndata
@property
+ def get_user(self):
+ if self.user:
+ return self.user
+ if self.detector and self.detector.default_user:
+ # we set self.user here, so changes to a detector will not change
+ # old sessions
+ self.user = self.detector.default_user
+ return self.user
+ # fallback to default user
+ self.user = get_user_or_default()
+ return self.user
+
+ @property
def learndata(self):
if not self.id:
raise ValueError, "Session Object not saved"
@@ -246,8 +334,11 @@ def smpl_0x03(self, data):
try:
session = Session.objects.get_active_session(rf_id)
except Session.DoesNotExist:
- logging.warning("Session id sent which is not active. Creating a new Session")
- session = Session(start=now, stop=now, rf_id=rf_id)
+ logging.warning("Session id %s sent which is not active. Creating a new Session" %rf_id)
+ user=get_user_or_default(None)
+ program=UserProgram.objects.get_users_default(user)
+ session = Session(start=now, stop=now, rf_id=rf_id,
+ user=user, program=program)
session.save()
logging.debug("%s S:%2d C:%2d %6d %s" %(session.id, rf_id, counter, var, "#"*max(min((var/500), 80),1)))
@@ -264,9 +355,11 @@ def smpl_0x04(self, data):
print "04", repr(data)
mdata = self.get_smpl_data(data)
ident = "0x%02x%02x" %(ord(mdata[0]), ord(mdata[1]))
- device, created = Detector.objects.get_or_create(ident=ident, defaults={"name": "eZ430 OpenChronos",
+ device, created = Detector.objects.get_or_create(ident=ident,
+ defaults={"name": "eZ430 OpenChronos",
"ident": ident,
"typ": DETECTOR_TYPES[0][0],
+ "user": get_user_or_default(None),
})
if created:
device.save()
@@ -283,22 +376,31 @@ def smpl_0x04(self, data):
# we have an active session running
active_session = session
+ # find program
+ program_id = ord(mdata[2])
+ user = get_user_or_default(device.default_user)
+ program = UserProgram.objects.get_program_for_user(user, program_id)
+
+
if not active_session:
rf_id = Session.objects.get_new_rf_id()
- program = ord(mdata[2])
- if not alarm.manager.is_valid_program_id(program):
- program = 0
- active_session = Session(start=now, stop=now, detector=device, user=device.default_user,
- rf_id=rf_id, program=program)
+
+ active_session = Session(start=now, stop=now, detector=device,
+ rf_id=rf_id,
+ user=user,
+ program=program)
active_session.save()
- logging.info("Send Session ID: %s" %(active_session.rf_id))
+
+ logging.info("Send Session ID: %s (user:%s program:%s)" %(active_session.rf_id, active_session.user, active_session.program))
data = [SIMPLICITI_PHASE_CLOCK_START_RESPONSE, active_session.rf_id]
self.send_smpl_data(data)
# we shall not do anything until the clock reads out the
# session data
- time.sleep(0.030)
+ for x in xrange(10):
+ self.send_smpl_data(data, wait=False)
+ time.sleep(0.050)
def smpl_0x10(self, data):
"""
@@ -309,7 +411,7 @@ def smpl_0x10(self, data):
# empty buffer
self.read_sync_data()
# read old data
- for x in xrange(1000):
+ for x in xrange(100):
self.send_smpl_data([ez_chronos.SYNC_AP_CMD_GET_STATUS], wait=False)
time.sleep(0.020)
if self.get_sync_buffer_status():
View
17 settings.py
@@ -1,6 +1,11 @@
# Django settings for uberclock project.
-import os.path
+import os, os.path
+
+CONFIG_PATH = os.path.expanduser("~/.uberclock")
+
+if not os.path.exists(CONFIG_PATH):
+ os.mkdir(CONFIG_PATH)
DEVELOPMENT_MODE = False
DEBUG = True
@@ -122,6 +127,9 @@
SERVER_LISTEN = '0.0.0.0'
SERVER_PORT = 8000
+DEFAULT_USER = 'user'
+DEFAULT_ALARM = 'basic'
+
CLOCK_SESSION_TIMEOUT = 60*5
PISTON_STREAM_OUTPUT = True
@@ -133,11 +141,12 @@
'default' : '<embed width="800" height="480" quality="high" bgcolor="#FFFFFF" wmode="transparent" name="virtualchumby" type="application/x-shockwave-flash" src="http://www.chumby.com/virtualchumby_noskin.swf" FlashVars="_chumby_profile_url=http%3A%2F%2Fwww.chumby.com%2Fxml%2Fvirtualprofiles%2FE8E34C1E-726B-11DF-BA50-001B24F07EF4&amp;baseURL=http%3A%2F%2Fwww.chumby.com" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>'
}
-import os
-if not os.path.exists(os.path.expanduser("~/.uberclock")):
- os.mkdir(os.path.expanduser("~/.uberclock"))
+# load user config file
+if os.path.exists(os.path.join(CONFIG_PATH, "settings.py")):
+ execfile(os.path.join(CONFIG_PATH, "settings.py"), globals())
+# load current dir config file
try:
from settings_local import *
except ImportError:
View
11 tools/ez_chronos.py
@@ -107,7 +107,7 @@ def __init__(self, stream):
#self._nullread()
self.debug = False
self.sync()
- print self.dstr(self.send_read(BM_GET_PRODUCT_ID, [0x00, 0x00, 0x00, 0x00]))
+ #self.send_smpl_data([], wait=False)
#def
#def _nullread(self):
@@ -158,7 +158,7 @@ def send(self, cmd_, data=None):
res = array.array('B', [0xFF, cmd_, ln])
self.last_cmd = (cmd_, ln)
if self.debug:
- if self.debug >= 2:
+ if self.debug >= 3:
print "send:" + self.dstr(res.tostring())
else:
if res.tostring() not in ('\xff\x08\x07\x00\x00\x00\x00', '\xff\x32\x04\x00'):
@@ -217,6 +217,11 @@ def reset(self):
def start_ap(self):
self.send_read(BM_START_SIMPLICITI)
+ for i in xrange(10):
+ res = self.send_read(BM_GET_SIMPLICITIDATA, [0x00, 0x00, 0x00, 0x00])
+ print self.dstr(res)
+ res = self.send_read(BM_GET_STATUS, [0x00])
+ print self.dstr(res)
def stop_ap(self):
#The start access point command needs to come before the stop access point command
@@ -321,7 +326,7 @@ def handle_smpl_data(self, data):
if self.debug > 3:
print "got no data"
else:
- if self.debug >= 2:
+ if self.debug >= 1:
print "handle", self.dstr(data)
if hasattr(self, "smpl_%s" %"0x%0.2X" %ord(data[3])):
getattr(self, "smpl_%s" %"0x%0.2X" %ord(data[3]))(data)
Please sign in to comment.
Something went wrong with that request. Please try again.