From 9c3f67c71f1ec6adf3da8b88a8e0374612099b39 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 3 Oct 2024 18:38:49 +0200 Subject: [PATCH] Refactoring. --- app/dmapi.f90 | 32 +++++++++++++++++--------------- app/dmplot.f90 | 6 +++--- app/dmweb.f90 | 5 +++-- src/dm_config.f90 | 8 ++++---- src/dm_html.f90 | 28 ++++++++++------------------ src/dm_sensor.f90 | 42 ++++++++++++++++++++++++++---------------- src/dm_target.f90 | 2 +- 7 files changed, 64 insertions(+), 59 deletions(-) diff --git a/app/dmapi.f90 b/app/dmapi.f90 index 51668e2..0acc646 100644 --- a/app/dmapi.f90 +++ b/app/dmapi.f90 @@ -59,21 +59,23 @@ program dmapi call dm_init() ! Add routes. - routes = [ cgi_route_type('', route_root), & - cgi_route_type('/', route_root), & - cgi_route_type('/beat', route_beat), & - cgi_route_type('/beats', route_beats), & - cgi_route_type('/log', route_log), & - cgi_route_type('/logs', route_logs), & - cgi_route_type('/node', route_node), & - cgi_route_type('/nodes', route_nodes), & - cgi_route_type('/observ', route_observ), & - cgi_route_type('/observs', route_observs), & - cgi_route_type('/sensor', route_sensor), & - cgi_route_type('/sensors', route_sensors), & - cgi_route_type('/target', route_target), & - cgi_route_type('/targets', route_targets), & - cgi_route_type('/timeseries', route_timeseries) ] + routes = [ & + cgi_route_type('', route_root), & + cgi_route_type('/', route_root), & + cgi_route_type('/beat', route_beat), & + cgi_route_type('/beats', route_beats), & + cgi_route_type('/log', route_log), & + cgi_route_type('/logs', route_logs), & + cgi_route_type('/node', route_node), & + cgi_route_type('/nodes', route_nodes), & + cgi_route_type('/observ', route_observ), & + cgi_route_type('/observs', route_observs), & + cgi_route_type('/sensor', route_sensor), & + cgi_route_type('/sensors', route_sensors), & + cgi_route_type('/target', route_target), & + cgi_route_type('/targets', route_targets), & + cgi_route_type('/timeseries', route_timeseries) & + ] ! Read environment variables. rc = dm_env_get('DM_DB_BEAT', db_beat, n) diff --git a/app/dmplot.f90 b/app/dmplot.f90 index e86040a..62ad4ae 100644 --- a/app/dmplot.f90 +++ b/app/dmplot.f90 @@ -12,7 +12,7 @@ program dmplot integer, parameter :: APP_MINOR = 9 integer, parameter :: APP_PATCH = 3 - character(len=*), parameter :: X_LABEL = 'Time' + character(len=*), parameter :: APP_X_LABEL = 'Time' type :: app_type !! Application settings. @@ -105,7 +105,7 @@ integer function create_plot(app) result(rc) ! Create plot. rc = create_graph(dps, app%terminal, path, app%background, app%foreground, app%font, & - app%title, app%width, app%height, X_LABEL, app%response) + app%title, app%width, app%height, APP_X_LABEL, app%response) end block plot_block if (rc == E_DB_NO_ROWS) then @@ -149,8 +149,8 @@ integer function read_args(app) result(rc) dm_lua_version(.true.) // ' ' // & dm_db_version(.true.) - rc = E_NOT_FOUND if (.not. found) then + rc = E_NOT_FOUND call dm_error_out(rc, 'Gnuplot not found') return end if diff --git a/app/dmweb.f90 b/app/dmweb.f90 index 608918a..e009dce 100644 --- a/app/dmweb.f90 +++ b/app/dmweb.f90 @@ -70,6 +70,7 @@ program dmweb character(len=*), parameter :: APP_JS_PATH = APP_CSS_PATH !! Path to JavaScript directory. character(len=*), parameter :: APP_TITLE = 'DMPACK' !! HTML title and heading. integer, parameter :: APP_DB_TIMEOUT = DB_TIMEOUT_DEFAULT !! SQLite 3 busy timeout in mseconds. + integer, parameter :: APP_NROUTES = 19 !! Total number of routes. integer, parameter :: APP_PLOT_TERMINAL = PLOT_TERMINAL_SVG !! Plotting backend. logical, parameter :: APP_READ_ONLY = .false. !! Default database access mode. real(kind=r8), parameter :: APP_MAP_LAT = 51.1642292_r8 !! Default map view latitude. @@ -87,7 +88,7 @@ program dmweb logical :: has_tile_url = .false. ! Map tile URL passed. logical :: read_only = APP_READ_ONLY ! Open databases in read-only mode. - type(cgi_route_type) :: routes(19) + type(cgi_route_type) :: routes(APP_NROUTES) type(cgi_router_type) :: router ! Initialise DMPACK. @@ -738,7 +739,7 @@ subroutine route_map(env) ! GET REQUEST. ! ------------------------------------------------------------------ if (len_trim(tile_url) == 0) then - call html_error('No tile map URL provided in environment variable DM_TILE_URL.', error=E_EMPTY) + call html_error('Missing Environment Variable', error=E_EMPTY) return end if diff --git a/src/dm_config.f90 b/src/dm_config.f90 index 79703af..4797117 100644 --- a/src/dm_config.f90 +++ b/src/dm_config.f90 @@ -3,11 +3,11 @@ module dm_config !! Module for loading Lua-based configuration files. !! - !! The following configuration file `myapp.config` is given as an example - !! for a program `myapp`: + !! The following configuration file `myapp.conf` is given as an example for + !! a program `myapp`: !! !! ```lua - !! -- myapp.config + !! -- myapp.conf !! myapp = { !! database = "observ.sqlite", !! node = "dummy-node", @@ -25,7 +25,7 @@ module dm_config !! logical :: verbose !! type(config_type) :: config !! - !! rc = dm_config_open(config, 'myapp.config', 'myapp') + !! rc = dm_config_open(config, 'myapp.conf', 'myapp') !! !! if (dm_is_ok(rc)) then !! call dm_config_get(config, 'database', database) diff --git a/src/dm_html.f90 b/src/dm_html.f90 index e980659..fd8330f 100644 --- a/src/dm_html.f90 +++ b/src/dm_html.f90 @@ -1440,18 +1440,13 @@ function dm_html_sensor(sensor) result(html) type(sensor_type), intent(inout) :: sensor !! Sensor type. character(len=:), allocatable :: html !! Generated HTML. - integer :: type - - type = sensor%type - if (.not. dm_sensor_type_valid(type)) type = SENSOR_TYPE_NONE - html = H_TABLE // H_TBODY // & H_TR // H_TH // 'ID' // H_TH_END // & H_TD // H_CODE // dm_html_encode(sensor%id) // H_CODE_END // H_TD_END // H_TR_END // & H_TR // H_TH // 'Node' // H_TH_END // & H_TD // H_CODE // dm_html_encode(sensor%node_id) // H_CODE_END // H_TD_END // H_TR_END // & H_TR // H_TH // 'Type' // H_TH_END // & - H_TD // trim(SENSOR_TYPE_NAMES(type)) // H_TD_END // H_TR_END // & + H_TD // dm_sensor_type_name(sensor%type) // H_TD_END // H_TR_END // & H_TR // H_TH // 'Name' // H_TH_END // & H_TD // dm_html_encode(sensor%name) // H_TD_END // H_TR_END // & H_TR // H_TH // 'Serial Number' // H_TH_END // & @@ -1483,7 +1478,7 @@ function dm_html_sensors(sensors, prefix) result(html) character(len=*), intent(in), optional :: prefix !! Link address prefix. character(len=:), allocatable :: html !! Generated HTML. - integer :: i, t + integer :: i logical :: is_anchor type(anchor_type) :: anchor @@ -1504,9 +1499,6 @@ function dm_html_sensors(sensors, prefix) result(html) H_TR_END // H_THEAD_END // H_TBODY do i = 1, size(sensors) - t = sensors(i)%type - if (.not. dm_sensor_type_valid(t)) t = SENSOR_TYPE_NONE - html = html // H_TR // H_TD // dm_itoa(i) // H_TD_END if (is_anchor) then @@ -1518,14 +1510,14 @@ function dm_html_sensors(sensors, prefix) result(html) html = html // H_TD // dm_html_encode(sensors(i)%id) // H_TD_END end if - html = html // H_TD // dm_html_encode(sensors(i)%node_id) // H_TD_END // & - H_TD // dm_html_encode(sensors(i)%name) // H_TD_END // & - H_TD // trim(SENSOR_TYPE_NAMES(t)) // H_TD_END // & - H_TD // dm_html_encode(sensors(i)%sn) // H_TD_END // & - H_TD // dm_html_encode(sensors(i)%meta) // H_TD_END // & - H_TD // dm_ftoa(sensors(i)%x) // H_TD_END // & - H_TD // dm_ftoa(sensors(i)%y) // H_TD_END // & - H_TD // dm_ftoa(sensors(i)%z) // H_TD_END // & + html = html // H_TD // dm_html_encode(sensors(i)%node_id) // H_TD_END // & + H_TD // dm_html_encode(sensors(i)%name) // H_TD_END // & + H_TD // dm_sensor_type_name(sensors(i)%type) // H_TD_END // & + H_TD // dm_html_encode(sensors(i)%sn) // H_TD_END // & + H_TD // dm_html_encode(sensors(i)%meta) // H_TD_END // & + H_TD // dm_ftoa(sensors(i)%x) // H_TD_END // & + H_TD // dm_ftoa(sensors(i)%y) // H_TD_END // & + H_TD // dm_ftoa(sensors(i)%z) // H_TD_END // & H_TR_END end do diff --git a/src/dm_sensor.f90 b/src/dm_sensor.f90 index 9de55f4..58847c2 100644 --- a/src/dm_sensor.f90 +++ b/src/dm_sensor.f90 @@ -26,13 +26,15 @@ module dm_sensor integer, parameter, public :: SENSOR_TYPE_GNSS = 9 !! GNSS sensor. integer, parameter, public :: SENSOR_TYPE_LEVEL = 10 !! Level sensor. integer, parameter, public :: SENSOR_TYPE_MEMS = 11 !! MEMS sensor. - integer, parameter, public :: SENSOR_TYPE_LAST = 11 !! Never use this. + integer, parameter, public :: SENSOR_TYPE_CAMERA = 12 !! IP camera or webcam. + integer, parameter, public :: SENSOR_TYPE_LAST = 12 !! Never use this. integer, parameter, public :: SENSOR_TYPE_NAME_LEN = 7 !! Max. length of sensor type name. character(len=*), parameter, public :: SENSOR_TYPE_NAMES(SENSOR_TYPE_NONE:SENSOR_TYPE_LAST) = [ & - character(len=SENSOR_TYPE_NAME_LEN) :: 'none', 'virtual', 'system', 'fs', 'process', 'network', & - 'multi', 'meteo', 'rts', 'gnss', 'level', 'mems' & + character(len=SENSOR_TYPE_NAME_LEN) :: & + 'none', 'virtual', 'system', 'fs', 'process', 'network', 'multi', 'meteo', 'rts', & + 'gnss', 'level', 'mems', 'camera' & ] !! Array of sensor type names. type, public :: sensor_type @@ -62,6 +64,7 @@ module dm_sensor public :: dm_sensor_equals public :: dm_sensor_type_from_name + public :: dm_sensor_type_name public :: dm_sensor_type_valid public :: dm_sensor_out public :: dm_sensor_valid @@ -96,9 +99,9 @@ pure elemental logical function dm_sensor_equals(sensor1, sensor2) result(equals end function dm_sensor_equals pure elemental integer function dm_sensor_type_from_name(name) result(type) - !! Returns format enumerator from given name. + !! Returns type enumerator from given name. use :: dm_string, only: dm_to_lower - character(len=*), intent(in) :: name !! Format name. + character(len=*), intent(in) :: name !! Sensor type name. character(len=SENSOR_TYPE_NAME_LEN) :: name_ @@ -128,11 +131,26 @@ pure elemental integer function dm_sensor_type_from_name(name) result(type) type = SENSOR_TYPE_LEVEL case (SENSOR_TYPE_NAMES(SENSOR_TYPE_MEMS)) type = SENSOR_TYPE_MEMS + case (SENSOR_TYPE_NAMES(SENSOR_TYPE_CAMERA)) + type = SENSOR_TYPE_CAMERA case default type = SENSOR_TYPE_NONE end select end function dm_sensor_type_from_name + pure function dm_sensor_type_name(type) result(name) + !! Returns name of given type enumerator as allocatable string. + integer, intent(in) :: type !! Sensor type enumerator `SENSOR_TYPE_*`. + character(len=:), allocatable :: name !! Sensor type name. + + if (.not. dm_sensor_type_valid(type)) then + name = 'invalid' + return + end if + + name = trim(SENSOR_TYPE_NAMES(type)) + end function dm_sensor_type_name + pure elemental logical function dm_sensor_type_valid(type) result(valid) !! Returns `.true.` if `type` is valid sensor type. The type !! `SENSOR_TYPE_NONE` is a valid type. @@ -164,17 +182,9 @@ subroutine dm_sensor_out(sensor, unit) unit_ = stdout if (present(unit)) unit_ = unit - write (unit_, '("sensor.id: ", a)') trim(sensor%id) - write (unit_, '("sensor.node_id: ", a)') trim(sensor%node_id) - - write (unit_, '("sensor.type: ")', advance='no') - - if (dm_sensor_type_valid(sensor%type)) then - write (unit_, '(a)') trim(SENSOR_TYPE_NAMES(sensor%type)) - else - write (unit_, '("invalid")') - end if - + write (unit_, '("sensor.id: ", a)') trim(sensor%id) + write (unit_, '("sensor.node_id: ", a)') trim(sensor%node_id) + write (unit_, '("sensor.type: ")') dm_sensor_type_name(sensor%type) write (unit_, '("sensor.name: ", a)') trim(sensor%name) write (unit_, '("sensor.sn: ", a)') trim(sensor%sn) write (unit_, '("sensor.meta: ", a)') trim(sensor%meta) diff --git a/src/dm_target.f90 b/src/dm_target.f90 index 9e19b28..46cd975 100644 --- a/src/dm_target.f90 +++ b/src/dm_target.f90 @@ -126,7 +126,7 @@ subroutine dm_target_out(target, unit) write (unit_, '("target.id: ", a)') trim(target%id) write (unit_, '("target.name: ", a)') trim(target%name) write (unit_, '("target.meta: ", a)') trim(target%meta) - write (unit_, '("target.state: ", i0)') target%state + write (unit_, '("target.state: ", a)') dm_target_state_name(target%state) write (unit_, '("target.x: ", 1pg0.12)') target%x write (unit_, '("target.y: ", 1pg0.12)') target%y write (unit_, '("target.z: ", 1pg0.12)') target%z