Skip to content

Commit

Permalink
Minor updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
interkosmos committed Mar 5, 2024
1 parent 587f777 commit ace147a
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 62 deletions.
14 changes: 8 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ jobs:
with:
submodules: recursive

- name: Configure System (Linux)
if: contains(matrix.os, 'ubuntu')
run: |
sudo sysctl fs.mqueue.msg_max=100
sudo sysctl fs.mqueue.msgsize_max=16384
- name: Install Dependencies (Linux)
if: contains(matrix.os, 'ubuntu')
run: |
Expand All @@ -53,6 +47,14 @@ jobs:
sudo make install
/usr/local/bin/sqlite3 --version
- name: Configure System (Linux)
if: contains(matrix.os, 'ubuntu')
run: |
sudo sysctl fs.mqueue.msg_max=100
sudo sysctl fs.mqueue.msgsize_max=16384
alias gnuplot="gnuplot-nox"
gnuplot --version
- name: Build and Test (Linux)
if: contains(matrix.os, 'ubuntu')
run: |
Expand Down
16 changes: 8 additions & 8 deletions guide/guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ $ dmbackup --database /var/dmpack/observ.sqlite --backup /tmp/observ.sqlite
=== dmbeat [[dmbeat]]

The *dmbeat* program is a heartbeat emitter that sends <<data-beat,heartbeats>>
or handshakes via HTTP POST to a remote <<dmapi>> service. The heartbeat
or handshakes via HTTP POST to a remote <<dmapi>> service. The heartbeat
messages include time stamp, system uptime, and last connection error. The
server may inspect this data to check if a client is still running and has
network access. The RPC endpoint is expected at
Expand Down Expand Up @@ -916,8 +916,9 @@ $ cp /usr/local/share/dmpack/feed.xsl /var/www/
....

If `/var/www/` is served by a web server, feed readers can subscribe to the
feed. Furthermore, we may translate feed and style sheet into a single HTML
document `feed.html`, using an arbitrary XSLT processor, for instance:
feed. To update the feed periodically, add *dmfeed* to <<Cron,crontab>>.
Furthermore, we may translate feed and style sheet into a single HTML document
`feed.html`, using an arbitrary XSLT processor, for instance:

....
$ xsltproc --output feed.html /var/www/feed.xsl /var/www/feed.xml
Expand Down Expand Up @@ -1615,10 +1616,10 @@ $ dmplot --node dummy-node --sensor dummy-sensor --target dummy-target \
--terminal pngcairo --output /tmp/plot.png
....

Output the plot directly to terminal, with the configuration loaded from file:
Output the plot directly to terminal, using the configuration in `dmplot.conf`:

....
$ dmplot --name dmplot -node --config dmplot.conf --terminal sixelgd
$ dmplot --name dmplot --config dmplot.conf --terminal sixelgd
....

The `sixelgd` format requires a terminal emulator with Sixel support, such as
Expand Down Expand Up @@ -4577,9 +4578,8 @@ MAILTO=/dev/null
....

The shell script `mkreport.sh` must have the execution bits set. Update the
script to your configuration.

Furthermore, we can update an Atom XML feed of logs with <<dmfeed>>:
script to your configuration. Furthermore, we can update an Atom XML feed of
logs with <<dmfeed>>:

[source,crontab]
....
Expand Down
149 changes: 102 additions & 47 deletions src/dm_geocom.f90
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,28 @@ module dm_geocom
!! and given more memorable names. Function names do not contain a sub-system
!! prefix.
!!
!! References to the official API are made in the procedure descriptions.
!! The following example opens the TTY `/dev/ttyUSB0` at 115,200 baud and
!! sends a beep request to the instrument:
!!
!! ```fortran
!! integer :: grc ! GeoCOM return code.
!! integer :: rc ! DMPACK return code.
!! integer :: grc ! GeoCOM return code.
!! integer :: rc ! DMPACK return code.
!!
!! type(geocom_class) :: geocom ! GeoCOM object.
!!
!! call geocom%open('/dev/ttyUSB0', TTY_B115200, nretries=1, error=rc)
!! if (dm_is_error(rc)) stop
!! call geocom%open('/dev/ttyUSB0', GEOCOM_COM_BAUD_115200, retries=1, error=rc)
!!
!! if (dm_is_error(rc)) then
!! dm_error_out(rc)
!! stop
!! end if
!!
!! grc = geocom%beep_normal()
!! print '(i0, ": ", a)', grc, geocom%message()
!!
!! call geocom%close()
!! ```
use :: dm_error
use :: dm_file
use :: dm_geocom_api
use :: dm_geocom_error
use :: dm_geocom_type
Expand All @@ -40,38 +45,43 @@ module dm_geocom
!! GeoCOM class for TTY access and GeoCOM API handling through the
!! public methods.
private
integer :: rc = E_NONE !! Last DMPACK return code.
integer :: grc = GRC_OK !! Last GeoCOM return code.
logical :: verbose = .true. !! Print error messages to stderr.
type(request_type) :: request !! Last request.
type(tty_type) :: tty !! TTY type for serial connection to sensor.
contains
! Public class methods.
procedure, public :: close => geocom_close
procedure, public :: code => geocom_code
procedure, public :: message => geocom_message
procedure, public :: open => geocom_open
procedure, public :: send => geocom_send
procedure, public :: close => geocom_close
procedure, public :: code => geocom_code
procedure, public :: error => geocom_error
procedure, public :: message => geocom_message
procedure, public :: open => geocom_open
procedure, public :: send => geocom_send

! Public GeoCOM-specific methods.
procedure, public :: beep_alarm => geocom_beep_alarm
procedure, public :: beep_normal => geocom_beep_normal
procedure, public :: beep_off => geocom_beep_off
procedure, public :: beep_on => geocom_beep_on
procedure, public :: null => geocom_null
end type geocom_class

! Private procedures.
private :: geocom_close
private :: geocom_code
private :: geocom_error
private :: geocom_last_request
private :: geocom_message
private :: geocom_open
private :: geocom_send

! Private GeoCOM procedures.
! private :: geocom_abort_download()
! private :: geocom_abort_list()
private :: geocom_beep_alarm
private :: geocom_beep_normal
private :: geocom_beep_off
private :: geocom_beep_on
private :: geocom_null
contains
! **************************************************************************
! PUBLIC METHODS.
Expand All @@ -83,20 +93,26 @@ integer function geocom_code(this) result(grc)
grc = this%grc
end function geocom_code

function geocom_message(this, grc) result(str)
integer function geocom_error(this) result(rc)
!! Returns last DMPACK return code.
class(geocom_class), intent(inout) :: this !! GeoCOM object.

rc = this%rc
end function geocom_error

function geocom_message(this, grc) result(message)
!! Returns message associated with given GeoCOM return code `grc` as
!! allocatable string. If no return code is passed, the one in the
!! GeoCOM object is used instead.
class(geocom_class), intent(inout) :: this !! GeoCOM object.
integer, intent(in), optional :: grc !! GeoCOM return code.
character(len=:), allocatable :: str !! Last return code message.
class(geocom_class), intent(inout) :: this !! GeoCOM object.
integer, intent(in), optional :: grc !! GeoCOM return code.
character(len=:), allocatable :: message !! Last return code message.

if (present(grc)) then
str = dm_geocom_error_message(grc)
return
message = dm_geocom_error_message(grc)
else
message = dm_geocom_error_message(this%grc)
end if

str = dm_geocom_error_message(this%grc)
end function geocom_message

subroutine geocom_close(this)
Expand All @@ -106,6 +122,16 @@ subroutine geocom_close(this)
if (dm_tty_connected(this%tty)) call dm_tty_close(this%tty)
end subroutine geocom_close

subroutine geocom_last_request(this, request)
!! Returns the last request sent to the sensor in `request`. If no
!! request has been sent, the derived type is uninitialised and the time
!! stamp has the default value.
class(geocom_class), intent(inout) :: this !! GeoCOM object.
type(request_type), intent(out) :: request !! Last request sent to sensor.

request = this%request
end subroutine geocom_last_request

subroutine geocom_open(this, path, baud_rate, retries, error)
!! Opens TTY connection to robotic total station.
!!
Expand All @@ -124,6 +150,8 @@ subroutine geocom_open(this, path, baud_rate, retries, error)
!! * `E_EXIST` if the TTY is already connected.
!! * `E_INVALID` if baud rate is invalid.
!! * `E_NOT_FOUND` if path does no exist.
use :: dm_file, only: dm_file_exists

class(geocom_class), intent(inout) :: this !! GeoCOM object.
character(len=*), intent(in) :: path !! Path of TTY.
integer, intent(in) :: baud_rate !! Baud rate value.
Expand All @@ -134,7 +162,7 @@ subroutine geocom_open(this, path, baud_rate, retries, error)

i = 0
retries_ = 0
if (present(retries)) retries_ = retries
if (present(retries)) retries_ = max(0, retries)

tty_block: block
rc = E_INVALID
Expand All @@ -153,7 +181,6 @@ subroutine geocom_open(this, path, baud_rate, retries, error)
baud = TTY_B57600
case (GEOCOM_COM_BAUD_115200)
baud = TTY_B115200
continue
case default
exit tty_block
end select
Expand All @@ -165,90 +192,108 @@ subroutine geocom_open(this, path, baud_rate, retries, error)
if (dm_tty_connected(this%tty)) exit tty_block

do
! Try to open TTY.
if (i > retries_) exit
rc = dm_tty_open(this%tty, path, baud, TTY_BYTE_SIZE8, TTY_PARITY_NONE, TTY_STOP_BITS1)

! Try to open TTY.
rc = dm_tty_open(tty = this%tty, &
path = path, &
baud_rate = baud, &
byte_size = TTY_BYTE_SIZE8, &
parity = TTY_PARITY_NONE, &
stop_bits = TTY_STOP_BITS1)
if (dm_is_ok(rc)) exit
call dm_sleep(1)

! Re-try in 3 seconds.
i = i + 1
call dm_sleep(3)
end do
end block tty_block

this%rc = rc
if (present(error)) error = rc
end subroutine geocom_open

subroutine geocom_send(this, request, error)
!! Sends request to configured TTY.
use :: dm_regex
use :: dm_time

class(geocom_class), intent(inout) :: this !! GeoCOM object.
type(request_type), intent(inout) :: request !! Request to send.
integer, intent(out), optional :: error !! DMPACK error code

integer :: grc, rc

this%grc = GRC_UNDEFINED
this%request = request

tty_block: block
! Prepare request.
request%timestamp = dm_time_now()

rc = E_IO
if (.not. dm_tty_connected(this%tty)) exit tty_block

! Set initial response errors.
rc = dm_request_set_response_error(request, E_INCOMPLETE)
if (dm_is_error(rc)) exit tty_block

! Send request to sensor.
rc = dm_tty_write(this%tty, this%request, flush=.true.)
rc = dm_tty_write(this%tty, request, flush=.true.)
if (dm_is_error(rc)) exit tty_block

! Read response from sensor.
rc = dm_tty_read(this%tty, request)
if (dm_is_error(rc)) exit tty_block

! Parse raw response and extract response values.
rc = dm_regex_request(request)
if (dm_is_error(rc)) exit tty_block

! Get GeoCOM return code from response.
call dm_request_get(request, 'grc', grc, error=rc)
call dm_request_get(request, 'grc', grc, status=rc)
if (dm_is_ok(rc)) this%grc = grc
end block tty_block

this%rc = rc
this%request = request

if (present(error)) error = rc
end subroutine geocom_send

! **************************************************************************
! PUBLIC GEOCOM METHODS.
! **************************************************************************
integer function geocom_beep_alarm(this) result(grc)
!! BMM_BeepAlarm
!!
!! Sends request to output an alarm signal (triple beep).
class(geocom_class), intent(inout) :: this !! GeoCOM object.
type(request_type) :: request

type(request_type) :: request

call dm_geocom_api_request_beep_alarm(request)
call this%send(request)
grc = this%grc
end function geocom_beep_alarm

integer function geocom_beep_normal(this) result(grc)
!! BMM_BeepNormal
!!
!! Sends request to output an alarm signal (single beep).
class(geocom_class), intent(inout) :: this !! GeoCOM object.
type(request_type) :: request

type(request_type) :: request

call dm_geocom_api_request_beep_normal(request)
call this%send(request)
grc = this%grc
end function geocom_beep_normal

integer function geocom_beep_off(this) result(grc)
!! IOS_BeepOff
!!
!! Sends request to stop an active beep signal.
class(geocom_class), intent(inout) :: this !! GeoCOM object.
type(request_type) :: request

type(request_type) :: request

call dm_geocom_api_request_beep_off(request)
call this%send(request)
grc = this%grc
end function geocom_beep_off

integer function geocom_beep_on(this, intensity) result(grc)
!! IOS_BeepOn
!!
!! Sends request to start a continuous beep signal of given intensity.
!!
!! The optional intensity must be between 0 and 100. If no intensity
!! is passed, the default (`GEOCOM_IOS_BEEP_STDINTENS`) is used.
class(geocom_class), intent(inout) :: this !! GeoCOM object.
integer, intent(in), optional :: intensity !! Intensity of beep.

Expand All @@ -262,4 +307,14 @@ integer function geocom_beep_on(this, intensity) result(grc)
call this%send(request)
grc = this%grc
end function geocom_beep_on

integer function geocom_null(this) result(grc)
class(geocom_class), intent(inout) :: this !! GeoCOM object.

type(request_type) :: request

call dm_geocom_api_request_null(request)
call this%send(request)
grc = this%grc
end function geocom_null
end module dm_geocom
2 changes: 1 addition & 1 deletion src/dm_geocom_api.f90
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ pure subroutine dm_geocom_api_request_get_face(request)
!! The instrument returns the following responses:
!!
!! * `grc` – GeoCOM return code.
!! * `face` – Telescope face (`TMC_FACE`).
!! * `face` – Telescope face (`GEOCOM_TMC_FACE`).
!!
!! | Property | Values |
!! |----------------|--------------------------------------------------|
Expand Down

0 comments on commit ace147a

Please sign in to comment.