How to match IVR data with Call Centre Data by datetime - date

I have two systems IVR and Call Centre. The first call comes to IVR then routed to the Call Centre.
Not all calls go to Call Centre, some are contained in IVR itself.
I need to match IVR and Call Centre and get call centre data which comes after IVR and which close too.
Example of IVR Data:
ivrdate = as.POSIXct(c("9/1/21 9:03","9/1/21 9:54", "9/1/21 9:59","9/1/21 10:05",
"9/1/21 10:34","9/1/21 10:41","9/1/21 10:42","9/1/21 11:09"
), format = "%m/%d/%y %H:%M")
Callcenterdate<-as.POSIXct(c("9/1/21 9:04","9/1/21 9:57","9/1/21 10:03",
"9/1/21 10:34","9/1/21 11:10"),format = "%m/%d/%y %H:%M")
Desired output:

Related

how to download precipitation data for latitude-longitude coordinates from NOAA in R

I'm trying to download precipitation data for a list of latitude-longitude coordinates in R. I've came across this question which gets me most of the way there, but over half of the weather stations don't have precipitation data. I've pasted code below up to this point.
I'm now trying to figure out how to only get data from the closest station with precipitation data, or run a second function on the sites with missing data to get data from the second closest station. However, I haven't been able to figure out how to do this. Any suggestions or resources that might help?
`
library(rnoaa)
# load station data - takes some minutes
station_data <- ghcnd_stations() %>% filter(element == "PRCP")
# add id column for each location (necessary for next function)
sites_df$id <- 1:nrow(sites_df)
# retrieve all stations in radius (e.g. 20km) using lapply
stations <- lapply(1:nrow(sites_df),
function(i) meteo_nearby_stations(sites_df[i,],lat_colname = 'Lattitude',lon_colname = 'Longitude',radius = 20,station_data = station_data)[[1]])
# pull data for nearest stations - x$id[1] selects ID of closest station
stations_data <- lapply(stations,function(x) meteo_pull_monitors(x$id[1], date_min = "2022-05-01", date_max = "2022-05-31", var = c("prcp")))
stations_data`
# poor attempt its making me include- trying to rerun subset for second closest station. I know this isn't working but don't know how to get lapply to run for a subset of a list, or understand exactly how the function is running to code it another way
for (i in c(1,2,3,7,9,10,11,14,16,17,19,20)){
stations_data[[i]] <- lapply(stations,function(x) meteo_pull_monitors(x$id[2], date_min = "2022-05-01", date_max = "2022-05-31", var = c("prcp")))
}

Pymodbus: write_coil also writes in discrete input register?

I have a question regarding the pymodbus module and its functionality. My server works just fine, as well as the implemented datastore, I guess.
Here is the code for my server and datastore:
import asyncio
from pymodbus.datastore import (ModbusSequentialDataBlock,ModbusServerContext,ModbusSlaveContext,)
from pymodbus.server import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.version import version
def run_full_sync_server():
print("Creating sequential Datastore.")
# Creating continuing Datablock without gaps.
datablock = ModbusSequentialDataBlock(0, [0]*20) # Initializing starting address and registers with value 0 each
print("Creating slave Context.")
# Creating one slave context. Allows the server to respond to slave context with its unit id.
slave_context = ModbusSlaveContext(
di=datablock, # 'di' - Discrete Input Initializer
co=datablock, # 'co' - Coils Initializer
hr=datablock, # 'hr' - Holding Register Initializer
ir=datablock, # 'ir' - Input Registers Initializer
unit=1, # SlaveID
zero_mode=False
)
print("Creating Server Identity.")
# Creates Server Information.
identity = ModbusDeviceIdentification(
info_name={
"VendorName": "XXX",
"ProductCode": "ModbusKassow",
"VendorUrl": "XXX",
"ProductName": "Synchronous Py",
"ModelName": "Pymodbus Server",
"MajorMinorRevision": version.short(),
}
)
print("Starting Server.")
server_context = ModbusServerContext(slaves=slave_context, single=True)
server = StartTcpServer(context=server_context, identity=identity, address=("0.0.0.0", 502))
#return server
if name == "main":
asyncio.create_task(run_full_sync_server())
I am working with spyder atm, therfore I need a seperate instance for asyncio to get the server running.
As for writing coils/registers, there are some functions given from the module, but whenever I use the function
write_coil
the exact values appear in my discrete inputs datastore (run the script two times).
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('127.0.0.1', port=502)
discrete_inputs = client.read_discrete_inputs(0, 14) # start reading from address 0
discrete_inputs.setBit(3, 1) # set address 3 to value 1
discrete_inputs.setBit(1,1)
print(discrete_inputs.getBit(0))
print(discrete_inputs.getBit(1))
print(discrete_inputs.bits[:])
print()
client.write_coil(10, True)
client.write_coil(12, True)
client.write_coil(15, True)
reading_coil = client.read_coils(0, 14) # start reading from address 1
print(reading_coil.bits[:])
I thought that the discrete inputs and discrete coils were seperate datastores because they were initialized seperately?
Also, why does the
discrete_inputs.bits[:]
returns a list of only 16 bool values because in the server script I initialized the datastore with a list of 20 values?
Whenever I run the script twice, my coil values will appear in the discrete input datastore:
[False, True, False, True, False, False, False, False, False, False, True, False, True, False, False, False]
I know that each register/coil can only store 16 bits, which corresponds to the list of 16 values I get from the read function.
I tried the code above and were expecting that the datastores were seperately.
Also I was assuming that maybe I am only writing in one register, because I get exactly 16bits returned.
If that's the case however, I do not know how to access the other coil addresses.
Edit: code formatting
I thought that the discrete inputs and discrete coils were separate datastores because they were initialized separately?
They are; but you are creating a single store and then assigning that same store to each element. Try something like (showing two ways of accomplishing this):
datablock = ModbusSequentialDataBlock(0, [0]*20)
datablock2 = ModbusSequentialDataBlock(0, [0]*20)
slave_context = ModbusSlaveContext(
di=datablock, # 'di' - Discrete Input Initializer
co=ModbusSequentialDataBlock(0, [0]*20), # 'co' - Coils Initializer
hr=datablock2, # 'hr' - Holding Register Initializer
ir=ModbusSequentialDataBlock(0, [0]*20), # 'ir' - Input Registers Initializer
unit=1, # SlaveID
zero_mode=False
)
I know that each register/coil can only store 16 bits, which corresponds to the list of 16 values I get from the read function.
I think you may be confusing the Modbus protocol and the PyModbus implementation. A Modbus coil is one bit (The PyModbus datastore may end up storing that one bit in a 16-bit variable but that is an implementation detail).
As per the docs:
The coils in the response message are packed as one coil per bit of the data field.
Status is indicated as 1= ON and 0= OFF. The LSB of the first data byte contains the output addressed in the query. The other coils follow toward the high order end of this byte, and from low order to high order in subsequent bytes.
If the returned output quantity is not a multiple of eight, the remaining bits in the final data byte will be padded with zeros (toward the high order end of the byte). The Byte Count field specifies the quantity of complete bytes of data.
You are requesting 14 registers (client.read_discrete_inputs(0, 14)) so the output will be rounded up to 2 bytes (16 bits).

PyGears reordering bits

I would like to reorder bits before sending it to another module. I would like to make gear that will take 2 inputs pixel and weight and output called reordered should be:
reordered[0] = {pixel[0],weight[0]}
reordered[1] = {pixel[1],weight[1]}
Below is a picture that explains desired gear:
I made the assumption that both pixels and weights are coming as one interface thus I group it. This module should look something like this:
#datagear
def reorder( din: Queue[Tuple['pixel', 'weight']] ) -> Array[Queue[Tuple['pixel.data', 'weight.data']], 3]:
pixel = din.data[0]
weight = din.data[1]
return (
((pixel[0], weight[0]), din.eot),
((pixel[1], weight[1]), din.eot),
((pixel[2], weight[2]), din.eot),
)
Datagear is generally used for handling data and reordering it.
But please have in mind that if Pixel and Weight were two interfaces additional logic would be generated for synchronization of these two interfaces.

Large inaccuracies with Ruby Geocoder and/or OpenStreetMap

I'm using the geocoder gem in rails to get latitude & longitude for addresses and then display them in OpenStreetMap.
When I search for my old address:
>> results = Geocoder.search("1000 Mount Curve Ave E, Altadena, CA 91001")
I get:
>> results.first.coordinates
=> [34.1976645, -118.1278219]
Mount Curve Address Discrepancy
Those coordinates are perhaps a thousand feet off. (See image.) The resulting accurate coordinates from Google Maps are [34.200503,-118.1310407].
I've tried another address and it was much farther off, perhaps a mile. (1346 E Woodbury Rd, Pasadena, CA 91104)
I've tried yet another address, and it was pretty much dead-accurate. (922 E Brockton Ave, Redlands, CA 92374)
Does anyone know what might be causing these inaccuracies and how to get accurate results consistently?
Because of the inaccuracies and/or limitations with OSM/Nominatim, I switched to Google maps service. At the top of my controller I added:
require 'google_maps_service'
And in my controller's show routine I ended up with this, which yields accurate results:
source = Property.find(params[:id])
#property = PropertyDecorator.new(source)
gmaps = GoogleMapsService::Client.new(key: '[removed, put in your own key here]')
results = gmaps.geocode("#{#property.address1} #{#property.address2}")
if results[0] == nil
#lat = 0
#lng = 0
else
#lat = results[0][:geometry][:location][:lat]
#lng = results[0][:geometry][:location][:lng]
end

pseudocode about registers and clients

I have projects that requires to simulate a market with 3 registers. Every second an amount of clients come to the registers and we assume that each clients takes 4 seconds to the register before he leaves. Now lets suppose that we get an input of all the customers and their arriving time: e.x: 0001122334455 which means that 3 customers enter at second 0, 2 at second 1 etc. What i need to find is the total time which need to serve all the customers now matter how many they are and also to find the average waiting time at the store.
Can someone come up with a pseudocode for this problem?
while(flag){
while(i<A.length-1){
if(fifo[tail].isEmpty()) fifo[tail].put(A[i] +4);
else{
temp= fifo[tail].peek();
fifo[tail].put(A[i]-temp+4);
i++;
}
if(tail == a-1){
tail=0;
}else tail++;
if(i>3){
for(int q =0; q<a; q++){
temp = fifo[q].peek();
if(temp==i){
fifo[q].get();
}
}
}
}
}
where A is the array which contains all the customers as numbers as required from the input, and fifo is the array of the registers with the get , put and peek(get the tail but not remove it) methods. I have no clue though how to find the total time an the average waiting time