Mercurial > code > home > repos > environment
diff environment.py @ 0:3c1bc3bc5a6c
pull out of homeauto/ project, and add skaffold/pipenv
author | drewp@bigasterisk.com |
---|---|
date | Thu, 31 Mar 2022 22:03:43 -0700 |
parents | |
children | 0f532eb91364 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/environment.py Thu Mar 31 22:03:43 2022 -0700 @@ -0,0 +1,110 @@ +#!/usr/bin/python +""" +return some rdf about the environment, e.g. the current time, +daytime/night, overall modes like 'maintenance mode', etc + +""" +import datetime + +import cyclone.web +from dateutil.relativedelta import FR, relativedelta +from dateutil.tz import tzlocal +from docopt import docopt +from rdflib import Literal, Namespace +from twisted.internet import defer, reactor, task + +from standardservice.logsetup import log, verboseLogging +from patchablegraph import (CycloneGraphEventsHandler, CycloneGraphHandler, PatchableGraph) + +from patch_cyclone import patch_sse +from rdfdoc import Doc +from twilight import isWithinTwilight + +patch_sse() + +ROOM = Namespace("http://projects.bigasterisk.com/room/") +DEV = Namespace("http://projects.bigasterisk.com/device/") + +# STATS = scales.collection( +# '/root', +# scales.PmfStat('update'), +# ) + + +# see pending fix in patchablegraph.py +class CycloneGraphEventsHandlerWithCors(CycloneGraphEventsHandler): + + def __init__(self, application, request, masterGraph, allowOrigins=None): + super().__init__(application, request, masterGraph) + self.allowOrigins = allowOrigins or [] + + def flush(self): + origin = self.request.headers.get('origin', None) + if origin and origin in self.allowOrigins: + self.set_header(b"Access-Control-Allow-Origin", origin.encode('utf8')) + self.set_header(b"Access-Control-Allow-Credentials", b"true") + return CycloneGraphEventsHandler.flush(self) + + +# @STATS.update.time() +def update(masterGraph): + stmt = lambda s, p, o: masterGraph.patchObject(ROOM.environment, s, p, o) + + now = datetime.datetime.now(tzlocal()) + + stmt(DEV.environment, ROOM.localHour, Literal(now.hour)) + stmt(DEV.environment, ROOM.localTimeToMinute, Literal(now.strftime("%H:%M"))) + + stmt(DEV.environment, ROOM.localTimeToSecond, Literal(now.strftime("%H:%M:%S"))) + + stmt(DEV.environment, ROOM.localDayOfWeek, Literal(now.strftime("%A"))) + stmt(DEV.environment, ROOM.localMonthDay, Literal(now.strftime("%B %e"))) + stmt(DEV.environment, ROOM.localDate, Literal(now.strftime("%Y-%m-%d"))) + + for offset in range(-12, 7): + d = now.date() + datetime.timedelta(days=offset) + if d == d + relativedelta(day=31, weekday=FR(-1)): + stmt(DEV.calendar, ROOM.daysToLastFridayOfMonth, Literal(offset)) + + stmt(DEV.calendar, ROOM.twilight, ROOM['withinTwilight'] if isWithinTwilight(now) else ROOM['daytime']) + + +def main(): + arg = docopt(""" + Usage: environment.py [options] + + -v Verbose + """) + verboseLogging(arg['-v']) + + masterGraph = PatchableGraph() + + class Application(cyclone.web.Application): + + def __init__(self): + handlers = [ + (r"/()", cyclone.web.StaticFileHandler, { + "path": ".", + "default_filename": "index.html" + }), + (r'/graph/environment', CycloneGraphHandler, { + 'masterGraph': masterGraph + }), + (r'/graph/environment/events', CycloneGraphEventsHandlerWithCors, { + 'masterGraph': masterGraph, + 'allowOrigins': ['http://localhost:8001'], + }), + (r'/doc', Doc), # to be shared + # (r'/stats/(.*)', StatsHandler, { + # 'serverName': 'environment' + # }), + ] + cyclone.web.Application.__init__(self, handlers, masterGraph=masterGraph) + + task.LoopingCall(update, masterGraph).start(1) + reactor.listenTCP(8080, Application()) + reactor.run() + + +if __name__ == '__main__': + main()