I am refocusing this question because I have fixed most the problems except one. I have a Shiny App that uses serial data from a COM to populate reactiveValues. I need to build a DataTable/Dataframe from this reactive Value. X = Time, Y = dBm(ry). I do not know how to give a minimal reproducible model of this app. I know that I can read data from the COM and convert it to dBm without issue.
How do I get plotly to update with a set number of rows in the Datatable ? Is that possible for now I am taking the plotly points from the reactivevalues rv$m, but sometimes this produces NA which I don't want in the plot.
This is a a screen shot of what my App.
My code which is rather lengthy scroll down to the bottom as that is where I am having trouble and is as follows:
#install.packages("DT")
library(shiny)
library(serial)
library(broom)
#1 library(tidyverse)
library(DT)
library(zoo)
library(reshape2)
#install.packages("broman")
library(broman)
library(remotes)
#install.packages("gtools")
library(binaryLogic)
library(gtools)
#install.packages("R.utils")
require(R.utils)
#install.packages("BMS")
library("BMS")
#remotes::install_github("skgrange/threadr")
library(threadr)
library(plotly)
options(digits=4)
#options(shiny.sanitize.errors = TRUE)
LUT <-read.delim("E:/Signalfoxdata/ActiveSF/LUT_for_log_files_2.csv", sep=",", header=TRUE)
conn <-(serialConnection(name="Prolific USB-to-Serial Comm Port(Com3)",
port="COM3",
mode="9600,n,8,1",
newline=0,
translation="lf",
handshake = 'xonxoff')
)
open(conn)
captureRxData <-function(x){
x <-gsub("[^0-9$]","", x)
x_cleaned <- read.fwf(textConnection(x), widths=rep(2, nchar(x)[1]), colClasses = 'character', header=FALSE)
x_temp <- x_cleaned
x_temp[] <-lapply(x_cleaned,function(x) LUT$Value[match(x, LUT$Hex)])
ifelse(ncol(x_temp)>59,
x_temp <-x_temp%>%
select(V1:V60),
x_temp <-x_temp%>%
select(V1:ncol(x_temp)))
x_hex <- data.frame(sapply(split.default(x_temp, ceiling(seq_along(x_temp)/4)),
function(y) do.call(paste0, y)))
colnames(x_hex)<-NULL
x_dec<-sapply(x_hex, hex2dec)
dBm_out <-as.vector( (-69.0 +0.0149*(x_dec)))
dBm_mean <-mean(dBm_out)
if(length(dBm_mean)>0){
return(round(dBm_mean,4))
}else{
return(dBm_mean ="na")
}
}
this_table=data.frame(time=0,dBm=0)
ui <- fluidPage(
titlePanel("SignalFox Data Stream"),
fluidRow(
column(4,
hr(),
textInput("comm", "Name of Comm", value="Com3"),
textOutput("serial"),
#actionButton("goButton", "Go!", class = "btn-success"),
hr()
),
column(4,
tableOutput("Table"),
hr())
),
mainPanel(
plotlyOutput("myPlot"),
na.omit( DTOutput("shiny_table"))
) ,
)
server <- function(input, output, session) {
comm <-reactive(
as.character(input$comm)
)
conn <-(serialConnection(name="Prolific USB-to-Serial Comm Port(Com3)",
port="COM3",
mode="9600,n,8,1",
newline=0,
translation="lf",
handshake = 'xonxoff')
)
error_clock<- reactive({
error_clock <-proc.time()
error_clock
})
serialRead <-reactive({
invalidateLater(750, session)
tryCatch(
expr = {
read.serialConnection(conn)
},
error = function(e){
message('Caught an error!')
flush(conn)
#read.serialConnection(conn)
invalidateLater(1000, session)
read.serialConnection(conn)
# proc.time()-error_clock
},
warning = function(w){
message('Caught an warning!')
flush(conn)
invalidateLater(750, session)
read.serialConnection(conn)
open(conn)
}
)
})
time1 <-reactive({
ptm <-Sys.time()
for(i in 1:15)
if(!is.na(serialRead())){
ptm}else{
ptm<-NULL}
ptm
format(.POSIXct(ptm), "%H:%M:%OS3")
#as.numeric(format(Sys.time(), "%OS3"))
})
# output$serial <- renderText({
# serial <-if(str_detect(serialRead(),"rxDone", negate=TRUE)){
# print("Retrieving Power")}else{
# na.omit( captureRxData(serialRead()))
# }
# })
dBm1<-reactive({
if(str_detect(serialRead(),"xdata:", negate=FALSE)){
mean(na.omit( captureRxData(serialRead())))}else{
serialRead<-"na"}
})
rv <-na.omit(reactiveValues())
observeEvent(dBm1(),{
if(!is.numeric(dBm1())){
return(NULL)}else{
rv$m<- rbind(m=data.frame(x=time1(),y=dBm1()))
}
})
output$Table <- renderTable(cbind(time=time1(), dBm=dBm1()))
this_table <- reactiveVal(this_table)%>%
na.omit()
observeEvent(rv$m, {
if(is.na(dBm1())|is.na(time1())){
t= rbind(data.frame(time = NULL,
dBm= NULL), this_table()) }else{
t= rbind(data.frame(time = time1(),
dBm= na.omit(dBm1())), this_table())
}
this_table(na.omit(t))
})
output$shiny_table <- renderDT({
datatable(na.omit(this_table()), options = list(dom = 't'))
})
output$myPlot <- renderPlotly({
plot_ly() %>% add_markers(data=na.omit(rv$m),x=~time1(),y=~dBm1() )
})
}
shinyApp(ui,server)
Thanks In advance,