From 18f7ba2932fb4be47e01341b197a23c60caa8ca7 Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Thu, 24 Oct 2019 21:38:30 +1100 Subject: [PATCH] added more realtime-related stuff --- programs.cfg | 37 +++++++++++ realtime/OpenOS/etc/rc.d/realtime-relay.lua | 68 ++++++++++++++++++++ realtime/OpenOS/etc/rc.d/realtime-sync.lua | 70 +++++++++++++++++++++ realtime/OpenOS/usr/man/realtime-relay | 26 ++++++++ realtime/OpenOS/usr/man/realtime-sync | 28 +++++++++ realtime/README.md | 10 +++ 6 files changed, 239 insertions(+) create mode 100644 realtime/OpenOS/etc/rc.d/realtime-relay.lua create mode 100644 realtime/OpenOS/etc/rc.d/realtime-sync.lua create mode 100644 realtime/OpenOS/usr/man/realtime-relay create mode 100644 realtime/OpenOS/usr/man/realtime-sync create mode 100644 realtime/README.md diff --git a/programs.cfg b/programs.cfg index 97fcc71..b87ce6e 100644 --- a/programs.cfg +++ b/programs.cfg @@ -138,4 +138,41 @@ authors = "Izaya", repo = "tree/master/" }, + ["realtime"] = { + files = { + ["master/realtime/OpenOS/usr/lib/realtime.lua"] = "/lib", + ["master/realtime/OpenOS/usr/man/wolbeacon"] = "/man", + }, + name = "realtime", + description = "Real-time library for OpenOS", + authors = "Izaya", + repo = "tree/master/" + }, + ["realtime-sync"] = { + files = { + ["master/realtime/OpenOS/etc/rc.d/realtime-sync.lua"] = "//etc/rc.d", + ["master/realtime/OpenOS/usr/man/realtime-sync"] = "/man", + }, + dependencies = { + ["realtime"] = "" + }, + name = "realtime-sync", + description = "Internet-based real-time synchronisation daemon for OpenOS", + authors = "Izaya", + repo = "tree/master/" + }, + ["realtime-relay"] = { + files = { + ["master/realtime/OpenOS/etc/rc.d/realtime-relay.lua"] = "//etc/rc.d", + ["master/realtime/OpenOS/usr/man/realtime-relay"] = "/man", + }, + dependencies = { + ["realtime"] = "", + ["minitel"] = "" + }, + name = "realtime-relay", + description = "Minitel-based real-time synchronisation daemon for OpenOS", + authors = "Izaya", + repo = "tree/master/" + }, } diff --git a/realtime/OpenOS/etc/rc.d/realtime-relay.lua b/realtime/OpenOS/etc/rc.d/realtime-relay.lua new file mode 100644 index 0000000..082a2e9 --- /dev/null +++ b/realtime/OpenOS/etc/rc.d/realtime-relay.lua @@ -0,0 +1,68 @@ +local serial = require "serialization" +local computer = require "computer" +local realtime = require "realtime" +local minitel = require "minitel" +local event = require "event" +local timer, listener = false, false +local cfg = {} + +local startUptime = computer.uptime() + +cfg.host = "" +cfg.port = 37 +cfg.sync = false +cfg.frequency = 300 +cfg.offset = 0 + +local function saveConfig() + local f = io.open("/etc/realtime-relay.cfg","wb") + if not f then + return false + end + f:write(serial.serialize(cfg)) + f:close() +end +local function loadConfig() + local f = io.open("/etc/realtime-relay.cfg","rb") + if not f then + saveConfig() + return false + end + for k,v in pairs(serial.unserialize(f:read("*a"))) do + cfg[k] = v + end + f:close() +end + +local function updateTime() + startUptime = computer.uptime() + minitel.rsend(cfg.host,cfg.port,"rqtime",true) +end + +local function recvMsg(_,from,port,data) + if port == cfg.port and from == cfg.host then + epoch = tonumber(data) + if not epoch then return false end + local ut = (computer.uptime() - startUptime)/2 + realtime.update(epoch, ut, cfg.offset*60*60) + elseif port == cfg.port and not tonumber(data) then + minitel.rsend(from,port,realtime.time(true),true) + end +end + +function start() + loadConfig() + if not timer and cfg.sync then + timer = event.timer(cfg.frequency, updateTime, math.huge) + end + if not listener then + listener = event.listen("net_msg",recvMsg) + end + updateTime() +end +function stop() + event.cancel(timer) + timer = nil + event.ignore("net_msg",recvMsg) + listener = false +end diff --git a/realtime/OpenOS/etc/rc.d/realtime-sync.lua b/realtime/OpenOS/etc/rc.d/realtime-sync.lua new file mode 100644 index 0000000..351c472 --- /dev/null +++ b/realtime/OpenOS/etc/rc.d/realtime-sync.lua @@ -0,0 +1,70 @@ +local serial = require "serialization" +local component = require "component" +local computer = require "computer" +local realtime = require "realtime" +local event = require "event" +local timer = nil +local cfg = {} + +cfg.url = "https://google.com" +cfg.frequency = 300 +cfg.offset = 0 + +local function saveConfig() + local f = io.open("/etc/realtime-sync.cfg","wb") + if not f then + return false + end + f:write(serial.serialize(cfg)) + f:close() +end +local function loadConfig() + local f = io.open("/etc/realtime-sync.cfg","rb") + if not f then + saveConfig() + return false + end + for k,v in pairs(serial.unserialize(f:read("*a"))) do + cfg[k] = v + end + f:close() +end + +local function convertToEpoch(s) + p="%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+) GMT" + day,month,year,hour,min,sec=s:match(p) + months={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12} + month=months[month] + return os.time({day=day,month=month,year=year,hour=hour,min=min,sec=sec}) +end +local function updateTime() + local ut,rq = computer.uptime(), component.internet.request(cfg.url) + while true do + if rq.finishConnect() then + break + end + end + local _, _, headers = rq.response() + local date = headers.Date + if type(date) == "table" then + date=date[1] + end + realtime.update(convertToEpoch(date), ut, cfg.offset*60*60) + rq.close() +end + +function sync() + updateTime() + print(os.date("%Y-%m-%d %H:%M",realtime.time())) +end +function start() + loadConfig() + if not timer then + timer = event.timer(cfg.frequency, updateTime, math.huge) + end + sync() +end +function stop() + event.cancel(timer) + timer = nil +end diff --git a/realtime/OpenOS/usr/man/realtime-relay b/realtime/OpenOS/usr/man/realtime-relay new file mode 100644 index 0000000..973f716 --- /dev/null +++ b/realtime/OpenOS/usr/man/realtime-relay @@ -0,0 +1,26 @@ +# realtime-relay + +realtime relay daemon for OpenOS + +realtime-relay is both a Minitel realtime server and client; allowing both synchronisation with another machine, and other machines to synchronise with the local machine's clock. + +## Usage + +realtime-relay is implemented as an rc service, and as such, to start it one can use the usual rc commands: + + rc realtime-relay start + rc realtime-relay stop + rc realtime-relay enable + rc realtime-relay disable + +## Configuration + +realtime-relay includes a configuration file at */etc/realtime-relay.cfg*; as a Lua table. It contains the following fields: + +- **host**: The host to synchronise the local real-time clock with. +- **port**: The port to communicate with *host* on. +- **sync**: Whether to synchronise clocks with *host*. +- **frequency**: The time between automatic time synchronisations. +- **offset**: The offset time, in hours. + +By default, realtime-relay will only act as a server, as using it as a client requires both a *host* being set, and *sync* being enabled. diff --git a/realtime/OpenOS/usr/man/realtime-sync b/realtime/OpenOS/usr/man/realtime-sync new file mode 100644 index 0000000..caf0b15 --- /dev/null +++ b/realtime/OpenOS/usr/man/realtime-sync @@ -0,0 +1,28 @@ +# realtime-sync + +realtime synchronisation daemon for OpenOS + +realtime-sync uses the Date: header in HTTP responses, using the Internet card, to ascertain the current real time in UTC, and updates the realtime library with this information. + +## Usage + +realtime-sync is implemented as an rc service, and as such, to start it one can use the usual rc commands: + + rc realtime-sync start + rc realtime-sync stop + rc realtime-sync enable + rc realtime-sync disable + +Additionally, realtime-sync includes + + rc realtime-sync sync + +to force a re-synchronisation. + +## Configuration + +realtime-sync includes a configuration file at */etc/realtime-sync.cfg*; as a Lua table. It contains the following fields: + +- **url**: The URL to request to get the time. Pick one that returns UTC dates in the headers, or leave the default. +- **offset**: The timezone offset, in hours. For example, for AEDT, use 11. +- **frequency**: The time between automatic time synchronisations. diff --git a/realtime/README.md b/realtime/README.md new file mode 100644 index 0000000..b2ec815 --- /dev/null +++ b/realtime/README.md @@ -0,0 +1,10 @@ +# realtime for OpenComputers + +Given the lack of a good way to get the real-world time from an OpenComputers machine, the *realtime* library and protocol were created. + +## OpenOS +The realtime package for OpenOS includes: + +- The [realtime library](OpenOS/usr/man/realtime) itself, for OpenOS +- [realtime-sync](OpenOS/usr/man/realtime-sync), for synchronising with the real world +- [realtime-relay](OpenOS/usr/man/realtime-relay), for synchronising with another OpenComputers machine