Esempio n. 1
0
def sync(userdata, displayname):
	"""Send a synchronization signal to a device to correct time drift."""
	
	cursor   = userdata["cursor"]
	client   = userdata["client"]
	username = database.getusername(cursor, displayname)
	
	if username is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
	
	t = int(time.time())
	t = t - time.timezone if not time.daylight else t - time.altzone
	
	client.publish(username + "/admin", "time " + str(t), qos=1)
Esempio n. 2
0
def rename(userdata, displayname, newdisplayname):
	"""Change the public display name of a device."""
	
	cursor        = userdata["cursor"]
	configuration = userdata["configuration"]
	username      = database.getusername(cursor, displayname)
	
	if username is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
	
	if username == configuration["superuser"]:
		print("can't rename super user", file=sys.stderr)
		return
	
	if not database.rename(cursor, displayname, newdisplayname):
		print("can't rename the device, the new name may already be in use", file=sys.stderr)
		return
Esempio n. 3
0
def schedule(userdata, displayname, event):
	"""Add an operation to be performed represented in an event dictionary to a device's schedule."""
	
	cursor        = userdata["cursor"]
	client        = userdata["client"]
	configuration = userdata["configuration"]
	username      = database.getusername(cursor, displayname)
	
	if username is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
	
	if username == configuration["superuser"]:
		print("the schedule is for devices", file=sys.stderr)
		return
		
	cursor.execute("select type, status from profile where username = ?;", (username,))
	
	row = cursor.fetchone()
	
	if row is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
	
	stype  = row[0]
	status = row[1]
	
	if not _validcommand(stype, event.command, status):
		print("invalid command " + str(event.command) + " for type " + str(stype) +
		      " and status " + str(status), file=sys.stderr)
		return
		
	eventstr = str(event)
	
	if event.recurrent:
		eventstr = eventstr[:10] + "+" + eventstr[10:]
	else:
		eventstr = eventstr[:6] + "+" + eventstr[6:]
	
	client.publish(username + "/control", eventstr, qos=1)
	database.addscheduled(cursor, username, event)
Esempio n. 4
0
def delete(userdata, displayname):
	"""Remove the profile and credentials of a device from the database."""
	
	cursor        = userdata["cursor"]
	db            = userdata["database"]
	configuration = userdata["configuration"]
	username      = database.getusername(cursor, displayname)
	
	if username is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
	
	if username == configuration["superuser"]:
		print("can't delete super user", file=sys.stderr)
		return
	
	database.delprofile(cursor, displayname)
	
	db.commit()
	
	mqtthandlers.kickuser(configuration, username, configuration["devmqttpsk"])
Esempio n. 5
0
def execute(userdata, displayname, command):
	"""Send a signal to a device to execute a command.
	
	The command is first validated to check that the device can act on it, given its type.
	"""
	
	cursor   = userdata["cursor"]
	client   = userdata["client"]
	username = database.getusername(cursor, displayname)
	
	if username is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
		
	cursor.execute("select type, status from profile where username = ?;", (username,))
	
	row = cursor.fetchone()
	
	if row is None:
		print("can't find user " + shlex.quote(str(displayname)), file=sys.stderr)
		return
	
	stype  = row[0]
	status = row[1]
	
	if not _validcommand(stype, command, status):
		print("invalid command " + str(command) + " for type " + str(stype) +
		      " and status " + str(status), file=sys.stderr)
		return
	
	newstatus = _statustransform(stype, command, status)
	
	if newstatus is not None:
		database.setstatus(cursor, username, newstatus)
	
	# the next call should be qos 2 because it is the only operation
	# that may not be idempotent, but PubSubClient doesn't support it
	# (and it's too heavyweight anyway)
	client.publish(username + "/control", command, qos=1)