From 5cba8ff9f13155960a56532f3216a922c2367fbd Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 4 Jun 2022 11:11:35 -0400 Subject: [PATCH] #59 environment detector RTU --- rtu/startup.lua | 7 ++- supervisor/session/rtu.lua | 2 + supervisor/session/rtu/envd.lua | 100 ++++++++++++++++++++++++++++++++ supervisor/startup.lua | 2 +- 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 supervisor/session/rtu/envd.lua diff --git a/rtu/startup.lua b/rtu/startup.lua index 3c01df3..9257f08 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -20,11 +20,12 @@ local redstone_rtu = require("rtu.dev.redstone_rtu") local boiler_rtu = require("rtu.dev.boiler_rtu") local boilerv_rtu = require("rtu.dev.boilerv_rtu") local energymachine_rtu = require("rtu.dev.energymachine_rtu") +local envd_rtu = require("rtu.dev.envd_rtu") local imatrix_rtu = require("rtu.dev.imatrix_rtu") local turbine_rtu = require("rtu.dev.turbine_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "beta-v0.7.4" +local RTU_VERSION = "beta-v0.7.5" local rtu_t = types.rtu_t @@ -225,6 +226,10 @@ for i = 1, #rtu_devices do -- induction matrix multiblock (10.1+) rtu_type = rtu_t.induction_matrix rtu_iface = imatrix_rtu.new(device) + elseif type == "environmentDetector" then + -- advanced peripherals environment detector + rtu_type = rtu_t.env_detector + rtu_iface = envd_rtu.new(device) else local message = "init> device '" .. rtu_devices[i].name .. "' is not a known type (" .. type .. ")" println_ts(message) diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 5598e82..c45ea39 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -7,6 +7,7 @@ local util = require("scada-common.util") -- supervisor rtu sessions (svrs) local svrs_boiler = require("supervisor.session.rtu.boiler") local svrs_emachine = require("supervisor.session.rtu.emachine") +local svrs_envd = require("supervisor.session.rtu.envd") local svrs_redstone = require("supervisor.session.rtu.redstone") local svrs_turbine = require("supervisor.session.rtu.turbine") @@ -106,6 +107,7 @@ function rtu.new_session(id, in_queue, out_queue, advertisement) elseif u_type == RTU_UNIT_TYPES.SNA then -- @todo Mekanism 10.1+ elseif u_type == RTU_UNIT_TYPES.ENV_DETECTOR then + unit = svrs_envd.new(self.id, i, unit_advert, self.out_q) else log.error(log_header .. "bad advertisement: encountered unsupported RTU type") end diff --git a/supervisor/session/rtu/envd.lua b/supervisor/session/rtu/envd.lua new file mode 100644 index 0000000..ce398e4 --- /dev/null +++ b/supervisor/session/rtu/envd.lua @@ -0,0 +1,100 @@ +local comms = require("scada-common.comms") +local log = require("scada-common.log") +local types = require("scada-common.types") + +local unit_session = require("supervisor.session.rtu.unit_session") + +local envd = {} + +local RTU_UNIT_TYPES = comms.RTU_UNIT_TYPES +local MODBUS_FCODE = types.MODBUS_FCODE + +local TXN_TYPES = { + RAD = 1 +} + +local TXN_TAGS = { + "envd.radiation" +} + +local PERIODICS = { + RAD = 500 +} + +-- create a new environment detector rtu session runner +---@param session_id integer +---@param unit_id integer +---@param advert rtu_advertisement +---@param out_queue mqueue +function envd.new(session_id, unit_id, advert, out_queue) + -- type check + if advert.type ~= RTU_UNIT_TYPES.ENV_DETECTOR then + log.error("attempt to instantiate envd RTU for type '" .. advert.type .. "'. this is a bug.") + return nil + end + + local log_tag = "session.rtu(" .. session_id .. ").envd(" .. advert.index .. "): " + + local self = { + session = unit_session.new(unit_id, advert, out_queue, log_tag, TXN_TAGS), + periodics = { + next_rad_req = 0 + }, + ---@class envd_session_db + db = { + radiation = {}, + radiation_raw = 0 + } + } + + local public = self.session.get() + + -- PRIVATE FUNCTIONS -- + + -- query the radiation readings of the device + local function _request_radiation() + -- read input registers 1 and 2 (start = 1, count = 2) + self.session.send_request(TXN_TYPES.RAD, MODBUS_FCODE.READ_INPUT_REGS, { 1, 2 }) + end + + -- PUBLIC FUNCTIONS -- + + -- handle a packet + ---@param m_pkt modbus_frame + function public.handle_packet(m_pkt) + local txn_type = self.session.try_resolve(m_pkt.txn_id) + if txn_type == false then + -- nothing to do + elseif txn_type == TXN_TYPES.RAD then + -- radiation status response + if m_pkt.length == 2 then + self.db.radiation = m_pkt.data[1] + self.db.radiation_raw = m_pkt.data[2] + else + log.debug(log_tag .. "MODBUS transaction reply length mismatch (envd.radiation)") + end + elseif txn_type == nil then + log.error(log_tag .. "unknown transaction reply") + else + log.error(log_tag .. "unknown transaction type " .. txn_type) + end + end + + -- update this runner + ---@param time_now integer milliseconds + function public.update(time_now) + if not self.has_build and self.periodics.next_rad_req <= time_now then + _request_radiation() + self.periodics.next_rad_req = time_now + PERIODICS.RAD + end + + self.session.post_update() + end + + -- get the unit session database + function public.get_db() return self.db end + + return public +end + +return envd diff --git a/supervisor/startup.lua b/supervisor/startup.lua index bf17a08..32cc86e 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -13,7 +13,7 @@ local svsessions = require("supervisor.session.svsessions") local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "beta-v0.4.4" +local SUPERVISOR_VERSION = "beta-v0.4.5" local print = util.print local println = util.println