earthimage documentation
earthimage plots an unprojected image base map of Earth.
Back to Climate Data Tools Contents
Contents
Syntax
earthimage earthimage('gray') earthimage('watercolor',rgbValues) earthimage('center',centerLon) earthimage(...,'bottom') h = earthimage(...)
Description
earthimage plots an image base map of Earth in unprojected coordinates.
earthimage('gray') plots the image in grayscale.
earthimage('watercolor',rgbValues) specifies the color of the ocean with a three-element [R G B] vector (e.g., [1 0 0] for red).
earthimage('center',centerLon) specifies a center longitude, which can be anything between -180 and 360. Default centerLon is 0.
earthimage(...,'bottom') places the earth image at the bottom of the graphical stack (beneath other objects that have already been plotted).
h = earthimage(...) returns a handle h of the plotted image.
Example 1: Simple
For a simple base map image, just type earthimage:
earthimage
You can then go about adding other layers to the base map with normal Matlab plotting functions, where x is used for longitudes and y is used for latitudes:
hold on borders('countries','color',0.5*[1 1 1]) xlabel 'degrees longitude' ylabel 'degrees latitude'
Example 2: Grayscale
For a grayscale image, specify 'gray':
figure
earthimage gray
Example 3: Transparent Ocean
To make the ocean transparent, specify 'watercolor','none':
earthimage('watercolor','none')
Example 4: Grayscale land with transparent ocean
Get grayscale land and transparent oceans like this:
earthimage('gray','watercolor','none')
Example 4: Colorful land with a black ocean
To specify a specific ocean color, enter the RGB values of the color you want the ocean to be. For example, plot make the ocean black by specifying the values [0 0 0] for 'watercolor':
earthimage('watercolor',[0 0 0])
Example 5: Grayscale land with a pink ocean
If you don't know the RGB values of your favorite color, use the rgb function instead:
earthimage('gray','watercolor',rgb('pink'))
Example 6: Centered on the Pacific
By default, the central longitude is 0 degrees, the Prime Meridian. But if you'd like the map to be centered on a different longitude, just specify the center longitude like this:
figure earthimage('center',120) xlabel 'longitude' ylabel 'latitude'
Author info
This function and supporting documentation were written by Chad A. Greene, for the Cimate Data Toolbox for Matlab, 2018.


The easiest way to make people think: "Wow, this app must be as good as Facebook!".
To create the default "button" add a class of uibutton
to any appropriate element. To create the blue variant include an additional class confirm
. To create the green variant include an additional class special
.
Button
<button class="uibutton" type="submit">Button</button>
<input class="uibutton" type="submit" value="Button">
To create larger buttons inclue an additional class of large
.
To created grouped buttons wrap them in an element, or use a list, given the class uibutton-group
.

Dashboard
Inbox
Account
Logout

Dashboard

Inbox

Account

Logout

To display a toolbar of buttons and grouped buttons, use a wrapping element given the class uibutton-toolbar
.

Mark as unread

Report spam
Delete

Unsubscribe

A range of icons can be added (only for links and buttons) by adding a class of icon
and any one of the provided icon classes:
New message
New message
| Class | Example |
|---|---|
.edit |
Edit post |
.add |
Add a photo |
.secure |
Private account |
.prev |
Back to messages |
.next |
Get more info |
Full support: Firefox 3.5+, Google Chrome, Safari 4+, IE 9+, Opera 11.10+.
Note: Some CSS3 enhancements are not supported in older versions of Opera and IE. The use of icons is not supported in IE 6 or IE 7.
Public domain: http://unlicense.org/


FIND YOUR EVENT
FREE
FOOD
EVENT TYPE
MORE
ENERGY LEVEL
1 (lowest)
2
3
4
5 (highest)
INDOOR/OUTDOOR
INDOOR
OUTDOOR
=
Visitors Allowed
SEARCH
You have not built your profile yet, please navigate to the "My Account" tab and submit a profile


#{extends 'main.html' /} #{set title:'Home' /} #{if helpers.Autority.isAdmin()}
View Application Info
Manage Contexts
Manage Users
Users
Products
Purchases
Types
Conditions


Technology: iPhone 7 Plus, Apple airpods, 2018 ASUS 15.6" Full HD High Performance Gaming Laptop
| Intel Quad Core i7-7700HQ | NVIDIA GeForce GTX 1050 4GB | 256GB M.2 SSD + 1TB HDD | 16GB DDR4 RAM | Back lit Keyboard
| Windows 10 Home , AMSCOPE-KIDS 30-180X 600x50mm Telescope (basic child's telescope), DIY Dobsonian cardboard
telescope he made with his kids.
Attitude: Inquisitive, always been interested in Space and space technology. He needs a low
budget hobby for himself and something he can do with his kids. He loves the idea of meeting up with local
professional astronomers, but has no direct network to make that happen.
Frustrations: Lack of inexpensive resources available to amateur stargazers. Doesn't enjoy
navigating clunky government websites to find cool data and information. This is why he doesn't use NASA's
website anymore.
Goals: Wants to spend quality time with his kids at an engaging educational event.
User Story: Avery wants to use this website to easily find local astronomers.
Description: Avery just found out his weekend is free after a client last minute cancelled
a meeting. He wants to find a legitimate event to attend.
Name of user and user role: Avery, astronomy hobbyist, parent
Interaction Flow
Avery googles "astronomy event albuquerque".
Scrolls through and clicks the link to our site.
Our server returns the splash page.
Avery sees a carousel with today's astronomy events, he clicks the arrow to navigate more quickly through
carousel.
Server is chillin' until....
Avery clicks an event he wants to get more info about.
Server returns automatic prompt to create account/sign in.
Avery creates his account because this website is sweet.
Server stores Avery's account information in user table and returns the event page.
Avery can now view specific event details and comment directly to event with questions.
Avery has a question! So he posts a comment in the event discussion and checks the box to be updated
when changes have been made to the event/someone comments back.
Server stores comment in comment table and adds comment to UI.
Avery sees comment closes website on work desktop to wait for a response as he drives home.
User Amanda comments back about event question.
Server stores comment in comment table, adds comment to UI and sends email alert to Avery's user email.
As Avery is driving home he receives an email update alert and opens it (while being stopped at a light).
He clicks link in email and navigates directly to thread in safari on his phone.
Server media queries the screen size and returns the event post and comments.
Avery reads when the star party will start and now has a cool astronomy event to attend with his kid.


Hardware overview
| Name: |
| Cores (threads): |
| NUMA: |
| Total memory: |
| Operating system: |
| Virtualized: |
Distances between NUMA nodes: |
Topology of a single NUMA node: |
Latency
These graphs show the pairwise IPC latency between cores.
Throughput
These graphs show the IPC throughput for continous communication between a pair of cores. The y-axis shows throughput in Gbps, and the x-axis different chunk sizes.
Legend:
This research is done by the NetOS group at the University of Cambridge Computer Laboratory. If you have any questions or would like to learn more, please contact us directly:
Email:
<EMAIL_ADDRESS>Postal address:
NetOS group
University of Cambridge Computer Laboratory
Willam Gates Building
15 JJ Thomson Avenue
Cambridge CB3 0FD, UK
Tel.: +44 1223 763683


During my work at IBM, I was tasked with working on an open-source tool called KUI. The product is a command line interface (CLI) that also has graphic user interface (GUI) features. I redesigned the tool's user experience, in order to make it more valuable to people. I also designed a way in which KUI would be integrated into IBM's flagship cloud management tool, IBM Multicloud Manager.
KUI is an open-source tool developed in IBM Research that meant to modernize the Terminal/CLI experience by adding GUI-like features, like charts, tables and and richer interactions. Though the tool had a lot of potential, it was lacking cohesive design and its supported features were not built in a human-centered way. I was tasked with improving the functionality and usability of the product, while keeping its core DNA of being a CLI that includes elements of modern graphic interfaces.
The existing open source KUI had the key functionality to visualize rich text using a terminal. However, it only had basic features that demonstrated the concept. My goal was to apply design thinking, in order to make the tool more useful and easier to use for its target personas.
The target personas for KUI are system administrators and application developers. Both personas use KUI to do their job, but they would use it in different ways. Application developers tend to work with one to a few applications, but need very detailed control, while system administrators typically worry about the health of many systems and apps.
Since I was tasked with integrating KUI into IBM Multicloud Manager (MCM), I mapped out the current journey that users had, while trying to do their work. This highlighted the many times people have to switch between a terminal and the MCM web application. This made an impression on me, as I thought this could be a potential area for improvement.
After assessing the current journey, I worked with the team (offering managers and developers) to define Hills, which are goals defined in a human-centered way. Hills help us align around our objectives and ensure that the team is in sync.
As I continued my work, I came up with a to-be user journey that showcased my target objective. A key property of my design was to reduce the friction that comes with switching back and forth between tools.
Before working on a prototype, I had to align with my development and offering (product) management partners. I wanted to get their buy in early, as that would ensure that I am not spending too much time on an idea that is not well received.
To get a good understanding of how KUI works in detail, I conducted a UX audit. I analyzed the functionality, interaction model, and visual language. My findings indicated that the tool can be quite powerful in combining a terminal and a graphic user interface effectively, but it lacked cohesion and a consistent design language.
I also looked around the web for other tools that try to combine CLI and graphic interfaces. I conducted a competitive analysis and explored potential ideas to draw inspiration from for my design.
Next, I sketched out concepts that I could use for my design. As I was brainstorming ideas, I kept an eye on the user journey that I had created. The sketches aimed to realize that journey, through an intuitive and clean design.
As I moved to higher fidelity in Sketch, I prototyped the key use cases, applied the IBM Carbon design language, and envisioned what integrating KUI inside of IBM Multicloud Manager (MCM) would look like. I built on top of the promise of KUI, but I ended up redesigning much of the interactions and visuals that it offered, in order to make it more consistent and easier to use.
After I finished the mid-fidelity prototype, I partnered with a UX researcher to conduct study, in order to test its usability. Below are some of the high-level insights that we gathered:
After collecting the insights from the study, I made some updates and collaborated with a visual designer to create a high-fidelity prototype. We tweaked the spacing, added colors and made sure that we are aligned to our guidelines around UI components and illustrations.
Our final design was delivered and presented to the team. It was well received and successfully implemented into MCM. As next steps, the team will observe how users are utilizing KUI and will strive to learn and improve the design. I believe that KUI can be further expanded to cover more use cases and provide more value to customers.


--- title: Simple Queue Package for R author: Roger Peng date: '2017-08-28' slug: simple-queue-package-for-r ---
I recently coded up a simple package that implements a file-based queue abstract data type. This package was needed for a different package that I’m working on involving parallel processing (more on that in the near future). Actually, this othe package is a project that I started almost nine years ago but was never able to get off the ground. I tried to implement a queue interface in the filehash package but it never served the purpose that I needed.
Recently, I came across Rich FitzJohn’s thor package, which provides an interface to the LMDB database, which is a light-weight key-value style database. When I saw this, I realized that it was exactly what I needed because it supports transactions with blocking. So if multiple processes attempt to write to the database at once, it will block the other processes untill the currently writing one is finished, and then move on to the next one.
The code for the queue
package is available on GitHub and can be installed in the usual way via devtools
:
devtools::install_github("rdpeng/queue")
The package just involves four functions:
enqueue()
: add an element to the queuedequeue()
: remove an element from the queue (and return it)peek()
: return the next element of the queue (but don’t remove it)is_empty()
: is the queue empty:There are also functions
create_Q
: create the queue and associated files on the diskinit_Q
: initialize a queue that has been previously createdEverything is implemented as S3 classes and methods. Queues are just sub-directories on the filesystem that contain some metadata for the underlying LMDB database.
You can create a queue with the create_Q()
function.
library(queue)
x <- create_Q("testq")
is_empty(x)
## [1] TRUE
You can then add arbitrary objects to the queue with enqueue()
. Behind the scenes, objects are serialize()
-ed.
enqueue(x, "hello")
enqueue(x, 1)
peek(x)
## [1] "hello"
Finally, you can remove an object from the front of the queue with dequeue()
.
obj <- dequeue(x)
obj
## [1] "hello"
peek(x)
## [1] 1
The implementation is pretty basic right now but the guts of it are there. I don’t plan to add any more features, but hopefully will round out the documentation and add some tests.


Created with Sketch.
Fjallraven Kanken
$86.00
Materials
Body: 100% Vinyl, Lining: 100% Polyethylene.
Add to Basket


This document defines the EPICS Version 4 communication protocol called "pvAccess." pvAccess is a high-performance network communication protocol for signal monitoring and scientific data services interconnect. It is designed to support the structured data types of the EPICS Version 4 "shared memory" data exchange system called pvData, for optimized interoperability of control system endpoints. It is a successor of EPICS Channel Access.
The connection setup requirements and individual message constructs of pvAccess are described. It is intended that sufficient detail is given for a reader to create an interoperable pvAccess implementation. The protocol and a reference implementation are being created by the EPICS Version 4 Working Group.
EPICS is a computer platform for building the control systems of large scientific instruments. For more information about the EPICS, please refer to the home page of the Experimental Physics and Industrial Control System.
This is the 19 April 2012 version of the pvAccess Protocol Specification. This version consititutes the first publication of the Second Public Working Draft. The Second Public Working Draft includes in particular support for unsigned integer, and material and revisions from the Invited Experts above. The Public Working Drafts are intended for the EPICS community to review and comment. Resulting comments will drive subsequent revisions of the specification and the EPICS Version 4 Working Group's reference implementation. It is expected that the next draft will be a Last Call draft, and be followed by publication of the specification.
The present implementation of pvAccess largely reflects the specification as written here. Another document will soon be written to track the status of the reference implementation with respect to the specification, showing what has yet to be implemented.
The terms MUST, MUST NOT, SHOULD, SHOULD NOT, REQUIRED, and MAY when highlighted (through style sheets, and in uppercase in the source) are used in accordance with RFC 2119 [RFC2119]. The term NOT REQUIRED (not defined in RFC 2119) indicates exemption.
In general the text in this document is intended to be "normative", which is to say it constitutes a formal specification of protocol itself. As such that text is concise, algorithmic, and describes the protocol systematically. Such text is in the default font of the document. The functional consequences of the specification so described, although not normative, may be important. Such non-normative text is in italics.
pvAccess is a high-performance network communication protocol. It is primarily designed for efficient signal monitoring and the data requirements of a service oriented architecture.
pvAccess is a successor of EPICS Channel Access bib:caref. It is the standard protocol of EPICS Version 4 (V4) when both endpoints of a channel are EPICS V4 agents. pvAccess can also connect EPICS V3 IOC Channel Access data to EPICS V4 user agents, using the EPICS V4 pvIOC module called CAV3.
TCP/IP is used for data transmission. UDP/IP is normally used for discovery, although discovery over TCP/IP is also allowed. The discovery mechanism allows the use of other implementations (e.g. UDP/IP for data transmission). The protocol itself supports IPv6, i.e. all addresses are IPv6 encoded.
Port numbers 5075 (tcp connection port, accepted by IANA) and 5076 (udp broadcast port) are used by default. These default connection ports SHOULD be used if free, otherwise a dynamically allocated port SHOULD be used as a fallback. pvAccess implementations SHOULD allow alternative default connection ports to be configured.
pvAccess was designed to support pvData bib:pvdatarefcpp, bib:pvdatarefjava. pvData is the control data interface of EPICS V4 endpoints, such as user agent software and EPICS V4 IOCs. Together with pvAccess, they support essentially a client-server shared memory system optimized for efficiency (optimal zero-copy etc) and control (PV locking, alarms etc). The protocol aims to send the minimum number of bits necessary to inform peers of changes in endpoint data values subject to performance considerations. That is, it combines CPU and wire data size considerations to optimize overall control network throughput. pvAccess supports segmented messages and thus allows the sending of large amounts of data using optimal buffer sizing. The maximum message size is not limited with respect to the send or receive buffer sizes. In practice, this means there is no need for a pvAccess equivalent of Channel Access' EPICS_CA_MAX_ARRAY_BYTES.
The pvAccess protocol definition consists of three major parts:
The goals of the pvAccess data encoding are simplicity and efficiency. In keeping with these goals, the encoding does not align primitive types on word boundaries and therefore eliminates the wasted space and additional complexity that alignment requires. The pvAccess data encoding simply produces a stream of contiguous bytes; in general message data does not contain padding bytes and an implementation MUST NOT try to align data on word boundaries.
However, arrays with an element type that is a number (including signed and unsigned integer types, and floating point types) are an exception. Such arrays MUST be aligned relative to the start of the message, so that the first element of the array (and thus all elements) have a byte offset (relative to the start of the message) that is divisible by the size (in bytes) of an element of the array. This MUST be done by inserting just enough bytes before the first element of the array. For instance, an array of float must be 4 byte aligned, which MUST be ensured by inserting up to three bytes before the array.
For connection-oriented communication (TCP/IP), the server MUST notify the client what byte order to use. Each message contains an endiannes flag in order to allow all the intermediates to forward data without requiring it to be unmarshaled (so that the intermediates can forward requests by simply copying blocks of binary data) and in order not to require a specific byte order for connection-less protocols (UDP/IP).
For clarity, this document separates user data (consisting of basic types, string, arrays, structures) from meta data, which exists only at the protocol level (Status, BitSet). Meta data can be of user data type, but not the other way around.
Many of the types involved in the data encoding, as well as several protocol message components, have an associated size (or "count"). Size values MUST always be a non-negative integer and encoded as follows:
Using this encoding to indicate size is significantly cheaper than always using a 32-bit (or even 64-bit) integer to store the size. This is especially true when marshalling sequences of short strings; counts of up to 254 require only a single byte instead of four. This comes at the expense of counts greater than 254, which require five bytes instead of four. However, for sequences or strings of length greater than 254, the extra byte is insignificant.
The basic types MUST be encoded as shown in Table 1. Signed integer types (byte, short, int, long) MUST be represented as two’s complement numbers. Floating point types (float, double) MUST use the IEEE-754 standard formats bib:ieee754wiki.
| Type | Encoding |
|---|---|
| boolean | A single byte with value non-zero value for true, zero for false. |
| byte | Signed 8-bit integer. |
| ubyte | Unsigned 8-bit integer. |
| short | Signed 16-bit integer. |
| ushort | Unsigned 16-bit integer. |
| int | Signed 32-bit integer. |
| uint | Unsigned 32-bit integer. |
| long | Signed 64-bit integer. |
| ulong | Unsigned 64-bit integer. |
| float | 32-bit float (IEEE-754 single-precision float). |
| double | 64-bit float (IEEE-754 double-precision float). |
Note on boolean encoding: a receiver MUST NOT assume that a boolean value of true is represented by any special non-zero number, nor that the same sender consistently uses the same number.
Arrays MUST be encoded as a size representing the number of elements in the array, followed by the elements encoded as specified for their type (as specified in these sections).
Strings are encoded as arrays of bytes. The actual content (the bytes in the array) MUST be a valid UTF-8 encoded string.
Particularly, this means that strings MUST be encoded as a size, followed by the string contents in a UTF-8 format as bytes. Size gives the number of bytes that follow it and not the number of UTF-8 characters. UTF-8 multi-byte characters MUST NOT be broken. An empty string MUST be encoded with a size of zero.
Implementations that internally use a zero byte or a zero character to indicate end-of-string SHOULD NOT include a terminating zero byte in the pvAccess string encoding. 'null' strings are not supported.
On the wire, pvAccess MUST transmit all strings as Unicode strings in UTF-8. Non-C++ bindings of the implementations SHOULD use strings in their language-native Unicode representation and convert automatically to and from UTF-8 for transmission, so applications can transparently use characters from non-English alphabets. However, for C++, how strings are represented inside a process depends on the platform as well as the mapping that is chosen for a particular string. The default mapping to is std::string.
Structures MUST be encoded by appending the data of all comprising fields in the order in which the fields have been defined. A structure can contain a structure for its field.
Given the following structure:
structure byte[] value [1,2,3] structure timeStamp long secondsPastEpoch 0x1122334455667788 int nanoSeconds 0xAABBCCDD int userTag 0xEEEEEEEE structure alarm int severity 0x11111111 int status 0x22222222 string message Allo, Allo!
The above would be serialized as illustrated below (when using big-endian byte order):
Hexdump [Serialized structure] size = 40 03 01 02 03 11 22 33 44 55 66 77 88 AA BB CC DD .... ."3D Ufw. .... EE EE EE EE 11 11 11 11 22 22 22 22 0B 41 6C 6C .... .... """" .All 6F 2C 20 41 6C 6C 6F 21 o, A llo!
BitSet is a data type that represents a finite sequence of bits.
BitSet is encoded as a byte array. Bits are serialized in groups of eight in ascending order (LSB to MSB). Serialization is size optimized to send only the least possible number of bytes that encode all the bits in the set.
Examples of BitSet serialization:
Hexdump [{}] size = 1 00 . Hexdump [{0}] size = 2 01 01 .. Hexdump [{1}] size = 2 01 02 .. Hexdump [{7}] size = 2 01 80 .. Hexdump [{8}] size = 3 02 00 01 ... Hexdump [{15}] size = 3 02 00 80 ... Hexdump [{55}] size = 8 07 00 00 00 00 00 00 80 .... .... Hexdump [{56}] size = 9 08 00 00 00 00 00 00 00 01 .... .... . Hexdump [{63}] size = 9 08 00 00 00 00 00 00 00 80 .... .... . Hexdump [{64}] size = 10 09 00 00 00 00 00 00 00 00 01 .... .... .. Hexdump [{65}] size = 10 09 00 00 00 00 00 00 00 00 02 .... .... .. Hexdump [{0, 1, 2, 4}] size = 2 01 17 .. Hexdump [{0, 1, 2, 4, 8}] size = 3 02 17 01 ... Hexdump [{8, 17, 24, 25, 34, 40, 42, 49, 50}] size = 8 07 00 01 02 03 04 05 06 .... .... Hexdump [{8, 17, 24, 25, 34, 40, 42, 49, 50, 56, 57, 58}] size = 9 08 00 01 02 03 04 05 06 07 .... .... . Hexdump [{8, 17, 24, 25, 34, 40, 42, 49, 50, 56, 57, 58, 67}] size = 10 09 00 01 02 03 04 05 06 07 08 .... .... .. Hexdump [{8, 17, 24, 25, 34, 40, 42, 49, 50, 56, 57, 58, 67, 72, 75}] size = 11 0A 00 01 02 03 04 05 06 07 08 09 .... .... ... Hexdump [{8, 17, 24, 25, 34, 40, 42, 49, 50, 56, 57, 58, 67, 72, 75, 81, 83}] size = 12 0B 00 01 02 03 04 05 06 07 08 09 0A .... .... ....
Each structure can (depending on message definition) have a BitSet instance defining what subset of that structure's fields have been serialized. This allows partial serialization of structures. That is, serializing only fields that have changed rather then the entire structure. Each node of a structure corresponds to one bit; if a bit is set then its corresponding field has been serialized, otherwise not. BitSet does not apply to array elements.
This example shows how bits of a BitSet are assigned to the fields of a structure:
bit# field 0 structure 1 structure timeStamp 2 long secondsPastEpoch 3 int nanoSeconds 4 int userTag 5 structure[] value structure org.epics.ioc.test.testStructure double value structure location double x double y structure org.epics.ioc.test.testStructure double value structure location double x double y 6 string factoryRPC 7 structure arguments 8 int size
The structure above requires a BitSet that contains 9 bits.
If the bit corresponding to a structure node is set, then all the fields of
that node MUST be serialized.
pvAccess defines a structure to inform endpoints about completion status. It is nominally defined as:
struct Status { byte type; // enum { OK = 0, WARNING = 1, ERROR = 2, FATAL = 3 } string message; string callTree; // optional (provides more context data about the error), can be empty };
In practice, since the majority of Status instances would be OK with no
message and no callTree, a special definition of Status SHOULD be used in the
common case that all three of these conditions are met; if Status is OK
and no message and no callTree would be sent, then the special type value of
-1
MAY be used, and in this case the string fields are omitted:
struct StatusOK { byte type = -1; };
Examples of Status serialization:
Hexdump [Status OK] size = 1 FF . Hexdump [WARNING, "Low memory", ""] size = 13 01 0A 4C 6F 77 20 6D 65 6D 6F 72 79 00 ..Lo w me mory . Hexdump [ERROR, "Failed to get, due to unexpected exception", (call tree)] size = 264 02 2A 46 61 69 6C 65 64 20 74 6F 20 67 65 74 2C .*Fa iled to get, 20 64 75 65 20 74 6F 20 75 6E 65 78 70 65 63 74 due to unex pect 65 64 20 65 78 63 65 70 74 69 6F 6E DB 6A 61 76 ed e xcep tion .jav 61 2E 6C 61 6E 67 2E 52 75 6E 74 69 6D 65 45 78 a.la ng.R unti meEx 63 65 70 74 69 6F 6E 0A 09 61 74 20 6F 72 67 2E cept ion. .at org. 65 70 69 63 73 2E 63 61 2E 63 6C 69 65 6E 74 2E epic s.ca .cli ent. 65 78 61 6D 70 6C 65 2E 53 65 72 69 61 6C 69 7A exam ple. Seri aliz 61 74 69 6F 6E 45 78 61 6D 70 6C 65 73 2E 73 74 atio nExa mple s.st 61 74 75 73 45 78 61 6D 70 6C 65 73 28 53 65 72 atus Exam ples (Ser 69 61 6C 69 7A 61 74 69 6F 6E 45 78 61 6D 70 6C iali zati onEx ampl 65 73 2E 6A 61 76 61 3A 31 31 38 29 0A 09 61 74 es.j ava: 118) ..at 20 6F 72 67 2E 65 70 69 63 73 2E 63 61 2E 63 6C org .epi cs.c a.cl 69 65 6E 74 2E 65 78 61 6D 70 6C 65 2E 53 65 72 ient .exa mple .Ser 69 61 6C 69 7A 61 74 69 6F 6E 45 78 61 6D 70 6C iali zati onEx ampl 65 73 2E 6D 61 69 6E 28 53 65 72 69 61 6C 69 7A es.m ain( Seri aliz 61 74 69 6F 6E 45 78 61 6D 70 6C 65 73 2E 6A 61 atio nExa mple s.ja 76 61 3A 31 32 36 29 0A va:1 26).
Introspection data describes the type of a user data item. It is not itself user data, but rather meta data. Introspection data appears in one of four forms: no introspection data (NULL_TYPE_CODE), or a full type description (FULL_TYPE_CODE), or a type identifier (ONLY_ID_TYPE_CODE), or both (FULL_WITH_ID_TYPE_CODE), according to table "Encoding of Introspection Data".
The sender MUST send introspection data, but is free to chose one of the above methods. Sending FULL_WITH_ID_TYPE_CODE defines the type identifier for subsequent sends using ONLY_ID_TYPE_CODE. Therefore, before sending ONLY_ID_TYPE_CODE, the sender MUST have previously sent at least one FULL_WITH_ID_TYPE_CODE with the same type identifier to the same receiver.
Since user data types can be arbitrarily complex, introspection data SHOULD be sent only once per type and receiver combination. The mapping of dynamically assigned type identifier (ID) to introspection data MUST be cached on the receiver side, and SHOULD be cached and re-used on the sender side. ID MUST be encoded as short and MUST be valid only within one connection. Moreover, IDs MUST be assigned only by the sender. The receiver MUST keep track of the IDs and use them to identify deserializations. Since communication is full-duplex this implies there MUST be two introspection registries per connection. The sender MAY override a previously assigned ID by simply assiging the ID to a new introspection data instance. Introspection registry size MUST be negotiated when each connection is established.
| Field Encoding | Name | Description |
|---|---|---|
| 0xFF | NULL_TYPE_CODE | No introspection data (also implies no data). |
| 0xFE + ID | ONLY_ID_TYPE_CODE | Serialization contains only an ID (that was assigned by one of the previous FULL_WITH_ID descriptions). |
| 0xFD + ID + FieldDesc | FULL_WITH_ID_TYPE_CODE | Serialization contains an ID (that can be used later, if cached) and full interface description. |
| 0xFC - 0xE0 | RESERVED | Reserved for future usage, MUST NOT be used. |
| FieldDesc (0xDF - 0x00) |
FULL_TYPE_CODE | Serialization contains only full interface description. |
Each instance of a Field introspection description (FieldDesc) MUST be encoded as a byte that consists of 2 nibbles (4-bits). The upper nibble (Most Significant Bits, MSBs) is used for the type selector and flags. The lower nibble (bits 7-5) is type dependent and used for size encoding.
| bit | Value | Description |
|---|---|---|
| 7-5 | 111 | reserved (MUST never be used) |
| 110 | reserved (MUST not be used) | |
| 101 | ||
| 100 | structure | |
| 011 | string | |
| 010 | floating-point | |
| 001 | integer | |
| 000 | boolean | |
| 4 | 1 | array flag |
| 0 | scalar flag | |
| 3-0 | type (bits 7-5) depended |
| bit | Value | Type Name |
|---|---|---|
| 3 | 1 | unsigned flag |
| 0 | signed flag | |
| 2-0 | 111 | reserved |
| 110 | ||
| 101 | ||
| 100 | ||
| 011 | long | |
| 010 | int | |
| 001 | short | |
| 000 | byte |
| bit | Value | Type Name | IEEE 754-2008 Name |
|---|---|---|---|
| 3 | reserved | ||
| 2-0 | 111 | reserved | |
| 110 | |||
| 101 | |||
| 100 | reserved | binary128 (Quadruple) | |
| 011 | double | binary64 (Double) | |
| 010 | float | binary32 (Single) | |
| 001 | reserved | binary16 (Half) | |
| 000 | reserved |
For all other types, bits 3-0 MUST be '0b0000'.
Structure and structureArray types REQUIRE more description. A structure REQUIRES a named array of Fields - size followed by one or more (field name, FieldDesc) pairs. StructureArray REQUIRES an introspection data of a structure defining an array element type.
| FieldDesc Encoding | Type | Description |
|---|---|---|
| 0bxxx0xxxx | scalar | Scalar. |
| 0bxxx1xxxx | scalarArray | Array of scalars. |
| 0b1000xxxx + (field name, FieldDesc)[] | structure | Structure. |
| 0b1001xxxx + structure FieldDesc | structureArray | Array of structures. |
Given the following structure, as may be expressed by a pvData Structure:
structure long secondsPastEpoch int nanoSeconds int userTag
The introspection description of the above structure is be encoded by pvAccess as the following:
Hexdump [Serialized structure IF] size = 45 FD 00 01 80 03 10 73 65 63 6F 6E 64 73 50 61 73 .... ..se cond sPas 74 45 70 6F 63 68 23 0B 6E 61 6E 6F 53 65 63 6F tEpo ch#. nano Seco 6E 64 73 22 07 75 73 65 72 54 61 67 22 nds" .use rTag "
Given the following structure, as may be expressed by a pvData Structure:
structure byte[] value structure timeStamp long secondsPastEpoch int nanoSeconds int userTag structure alarm int severity int status string message
The introspection description of the above structure would be encoded by pvAccess as the following:
Hexdump [Serialized structure IF] size = 105 FD 00 01 80 03 05 76 61 6C 75 65 30 09 74 69 6D .... ..va lue0 .tim 65 53 74 61 6D 70 FD 00 01 80 03 10 73 65 63 6F eSta mp.. .... seco 6E 64 73 50 61 73 74 45 70 6F 63 68 23 0B 6E 61 ndsP astE poch #.na 6E 6F 53 65 63 6F 6E 64 73 22 07 75 73 65 72 54 noSe cond s".u serT 61 67 22 05 61 6C 61 72 6D FD 00 02 80 03 08 73 ag". alar m... ...s 65 76 65 72 69 74 79 22 06 73 74 61 74 75 73 22 ever ity" .sta tus" 07 6D 65 73 73 61 67 65 60 .mes sage `
pvAccess uses the concept of a "channel" to denote a connection to a single named resource that resides on some server. Channels are subordinate to the TCP connection between a client and server: a channel can only be created if a TCP connection has already been established; likewise, if the TCP connection is terminated, then all subordinate channels are implicitly destroyed.
Each TCP connection has associated Quality of Service (QoS) parameters. Regardless of how many channels are handled by either client or server, each client and server pair MUST be connected with exactly one TCP connection for each QoS parameter value.
When establishing a TCP connection, a simple handshake MUST be performed. The client opens a TCP connection to the server and waits until the Connection Validation message is received. The server MUST initially send a Set byte order control message to notify the client about the byte order to be used for this TCP connection. After that the server MUST send the Connection Validation message. If the client correctly decodes messages it MUST respond with a Connection Validation response message. Now the connection is verified and the client may start sending requests. The client SHOULD keep the connection established until the last active channel gets destroyed. However, to optimize resource reallocation it MAY delay connection destruction.
Both parties MUST constantly monitor whether the connection is valid and not simply rely on TCP mechanisms. pvAccess achieves this by sending some small amount of data with a minimum period. If there is no send operation otherwise called within a predetermined period of time (SHOULD be 15 seconds), an echo message MUST be sent. In case of connection failure, TCP will report connection loss on send. If there is no response in in predetermined period of time, the connection SHOULD be marked as unresponsive. Echo message MUST be periodically sent until response is received or the connection is reported to be lost. If echo response is received and transport is marked as unresponsive, transport SHOUD be reported to be responsive.
When connection is terminated all related resources MUST be freed. On the server side all channels including their requests MUST be destroyed (this includes all serverChannelIDs). On the client side all channels and their requests MUST be put to disconnected state and searching for channels initiated. clientChannelIDs and requestIDs SHOULD be retained until channel or request are destroyed on client side. Once IDs are freed they MAY be recycled - used for other channels/requests in the future.
When disconnected client channels are found on the network and connection is re-established, channels are put back to connected state and all their requests re-initialized; in addition, monitors are re-started.
When a channel is instantiated by a client application, its state MUST be set to NEVER_CONNECTED state. This indicates that the channel is currently being connected for the first time. Connection proccess within the client MUST repetedly attempt to find a server hosting the channel by broadcasting or multicasting channel search requests. When a server response is received, the client MUST connect to the server responding to the search request using the protocol and address data from the search request response. If a connection has been already established by the client, it MUST be reused. A client API MAY also allow a user-specified server address; in this case, the searching process would be bypassed and the specified server address data used directly.
When connection is established and verified, the channel create request message MUST be sent by the server. When the client receives a channel create response message with success status, it MUST set the channel to CONNECTED state.
A channel MUST be in CONNECTED state to be able to accept channel related requests.
When the connection is lost, the channel state MUST be set to DISCONNECTED. In this state, clients MUST start the connection process as descibed above. On reconnect, the channel's state MUST be set back to CONNECTED.
A channel MAY be destroyed any time (in any state) and then its state MUST be set to DESTROYED. Once the channel is destroyed, it MUST NOT be used anymore.
Channel requests (get, put, get-put, RPC, process) have a state. When instantiated, they MUST be set to INIT state. A specific per request initialization message MUST be sent to the server. The request MUST NOT be used until successful initialization response is received from the server and put to READY state. If initialization fails, the client MUST be notified about failure and the request put to DESTROYED state.
Actual actions, e.g. get, MAY only be invoked when a request is in READY state. When one action is in progress, the request is put to REQUEST_IN_PROGRESS state and set back to READY state when ended. This implies that actions MUST NOT be run in parallel.
When connection is lost, a request MUST be put to DISCONNECTED state and automatically reinitialized when connection is reestablished (as if the request were newly instantiated).
A request MAY be destroyed any time (in any state) and then its state MUST be set to DESTROYED. Once the request is destroyed, it MUST NOT be used anymore.
This section is not intended to be normative. It is given only to help developers write agents that implement pvAccess optimally with respect to monitoring. This section does not describe the protocol itself.
A pvAccess implementation SHOULD implement flow control such that each endpoint should try to send as much monitoring data as it can subject to an upper limit calculated with respect to the amount of the other party's free receive buffer size. Were this limit to be reached, monitors would start pilling up in the monitors' circular buffer queues.
Usually flow control algorithms wait for congestion to occur before they are triggered. They are causal. However, due to the isolated nature of TCP connection - there are always only two parties involved - it is possible to predict congestions using the following algorithm:
Flow control is needed only to optimize subscription messages back to the client (i.e. monitors). For other messages TCP flow control is sufficient.
A pvAccess implementation SHOULD implement flow control such that each endpoint should try to send as much monitoring data as it can subject to an upper limit calculated with respect to the amount of the other party's free receive buffer size. Were this limit to be reached, monitors would start pilling up in the monitors' circular buffer queues.
The intention of flow control is to avoid having the following behavior, which typically results from pure TCP flow control:
Such situations as described above would result in monitors like the following (identified by their sequential number):
0 1 2 3 4 (buffers full) 7 8 9 10 11 12 (buffers full) 22 23 24 25 26 27 28 (buffers full)
Flow control can make this better:
0 1 2 3 4 (buffers full) 7 8 (buffers still full, but for less time since the server would send only as much as the client can handle) 10 11 (...) 14 15 (...) 18 19
The result is more fluid and up-to-date arrival of monitors, which overcomes the combined problems of slow processing and large buffers.
Requiring flow control (in addition to already existing monitor queues) would add complexity to the protocol's implementation. It needs to be decided whether the above flow control should be specified as part of the normative specification, or only suggested non-normatively. At present, it is only suggested.
pvAccess uses a broadcast/multicast channel discovery mechanism using UDP; search messages are usually sent to broadcast addresses and servers hosting searched channels respond with a message containing their server address and port. In addition pvAccess transparently supports multicast, if an address is a multicast address the implementation SHOULD transparently handle it. That is, it should join the multicast group in order to receive multicast messages.
Possible future addition: UDP congestion control should be added to the specification to prevent the possibility of poor implementations flooding a network with UDP search messages. Currently a simple and robust algorithm is used in the reference implementation. The optimality of the algorithm should to be verified and added to this specification.
The following table illustrates messages sent between a client and a server where the client issues a get request on a channel.
| Server | Client | |
|---|---|---|
| <---- | searchRequest (UDP broadcast/multicast) | |
| searchResponse (UDP unicast) | ----> | |
| TCP/IP connection established | ||
| setByteOrderControlMessage | ----> | |
| connectionValidationRequest | ----> | |
| <---- | connectionValidationResponse | |
| <---- | createChannelRequest | |
| createChannelResponse | ----> | |
| <---- | channelGetRequestInit | |
| channelGetResponseInit | ----> | |
| <---- | channelGetRequest | |
| channelGetResponse | ----> | |
| <---- | . . . | |
| . . . | ----> | |
| <---- | destroyRequest | |
| <---- | channelDestroyRequest | |
| channelDestroyResponse | ----> |
The pvAccess protocol uses two protocol message types:
Each message consists of a message header and, optionally a message payload that immediately follows the header. Messages MUST BE aligned on a 64-bit boundary.
Every implementation of the protocol which purports to support this specification version of the protocol, MUST also support all prior specification versions of the protocol. Every implementation of the protocol MUST clearly indicate the most recent specification version to which it is conformant, using the version URLs above.
Each protocol message has a fixed 8-byte header that MUST be encoded as if it were expressed by the following structure:
struct pvAccessHeader { byte magic; byte version; byte flags; byte messageCommand; int payloadSize; };
The semantics of these message header components are given in the following table.
| Member | Description |
|---|---|
| magic | pvAccess protocol magic code. This MUST always be valued 0xCA. |
| version | Protocol version. |
| flags | Message flags. |
| messageCommand | Message command (i.e. create, get, put, process, etc.). |
| payloadSize | Message payload size (non-aligned, in bytes). |
| bit | Value | Description |
|---|---|---|
| 0 | 0 | Application message. |
| 1 | Control message. | |
| 1,2,3 | Unused, MUST be 0. | |
| 5,4 | 00 | Not segmented message. |
| 01 | First messsage (of set of segmented messages). | |
| 10 | Last message (of set of segmented messages). | |
| 11 | Middle message (of set of segmented messages). | |
| 6 | Unused, MUST be 0. | |
| 7 | 0 | Little endian byte order. |
| 1 | Big endian byte order. |
Between two segmented messages of the same set there MUST NOT be any other application message than the segmented message of the same set. Control messages are allowed to be in-between.
Alignment offset MUST be preserved between segmented messages, i.e. if the last sent byte of a segmented message is misaligned by 6 bytes to the 64-bit aligned start of the message reference point, then the next segmented message needs to insert 6 padding bytes at the start of the next segmented message payload.
This section describes the message payloads for application messages. Each subsection describes a single message command (pvAccessHeader.messageCommand).
"request" means a message sent by a client, and "response" means a message sent by a server. Is this specifically in response to the client request? If so, as written "response" does not say that!
In order to understand specific application messages it is helpful to be familiar with the EPICS V4 pvAccess Programmers Reference.
Most application messages below relate to the management of process variable channels. A process variable, or PV, is a dynamical quantity and its associated local processing semantics, as understood by process control systems. pvAccess has been designed to specifically integrate with process control systems, particularly EPICS V4, to provide an efficient interconnect for systems involved in the exchange of PV related information. Agent systems connect to a process control computer (via pvAccess) hosting PVs, by opening a "Channel" to each PV of interest. A channel is the temporal connection between pvAccess agents, with respect to one process variable.
All application message MUST be sent over the data transmission transport unless explicitly specified. TCP/IP is the transport in the reference implementation. A response message MUST be sent over the same transport as that on which the request was received.
Servers MUST broadcast or multicast beacons over UDP. Beacons are be used to announce new servers and server restarts.
struct beaconMessage { short beaconSequenceId; long startupTimeSeconds; int startupTimeNanos; byte[16] serverAddressIPv6; short serverPort; string protocol; FieldDesc serverStatusIF; [if serverStatusIF != NULL_TYPE_CODE] PVField serverStatus; };
| Member | Description |
|---|---|
| beaconSequenceId | Beacon sequence ID (counter w/ rollover). Can be used to detect UDP routing problems. |
| startupTimeSeconds | Server startup time (POSIX time). |
| startupTimeNanos | Server startup time (nanoseconds part). |
| serverAddressIPv6 | Server IPv6 address (or IPv6 encoded IPv4 address). |
| serverPort | Server port (where server is listening). |
| protocol | Protocol name, "tcp" for standard pvAccess TCP/IP communication. |
| serverStatusIF | Optional server status Field description, NULL_TYPE_CODE MUST be used indicate absence of data. |
| serverStatus | Optional server data. |
When a pvAccess server is started it MUST start emitting beacons. Clients MUST monitor all beacons. A beacon received from an as yet unknown serverAddressIPv6 serverPort MUST be interpreted as indicating that a new server has come online. A beacon with the same serverAdddressIPv6:serverPort address as one already received but has different startupTime{Seconds,Nanos}, MUST be interpreted as indicating that the server was restarted. In both cases a client SHOULD boost searching of not yet found channels. A client MAY disconnect old connections or wait until connection loss is detected (on failed Echo message send).
Each server transport instance SHOULD emit its own beacons. For example, if a server is supporting data transmission over TCP/IP and UDP/IP then these SHOULD both emit beacons. If the instances are tightly coupled, i.e. they have the same lifecycle and share the same channels, then only one server MAY emit beacons.
Servers SHOULD synchronize their internal clocks using NTP or some other suitable time source before sending their first beacon.
Due to the fact that UDP does not guarantee delivery, a server MUST send several beacons to notify that it is alive (e.g. 15 beacons with 1Hz period). After a longer period it MAY stop sending them, however it is recommended that it SHOULD continue merely with a low rate (e.g. one beacon per minute) to report serverStatus.
Beacons SHOULD not used to report connection-valid status.
A "connection validation" message MUST be first application message sent from the server to a client when a TCP/IP connection is established. The message indicates that the server is ready to receive requests. The client MUST NOT send any messages on the connection until it has received a connection validation message from the server.
The purpose of the connection validation message is two-fold:
The connection validation message guarantees that a server is not in the middle of shutting down when the server's TCP/IP stack accepts an incoming connection, and so avoids the race condition.
The connection validation request and connection validation response messages are defined as follows:
struct connectionValidationRequest { int serverReceiveBufferSize; int serverReceiveSocketBufferSize; short serverIntrospectionRegistryMaxSize; }; struct connectionValidationResponse { int clientReceiveBufferSize; int clientReceiveSocketBufferSize; short clientIntrospectionRegistryMaxSize; short connectionQos; };
| Member | Description |
|---|---|
| serverReceiveBufferSize | Server receive buffer size in bytes. |
| serverReceiveSocketBufferSize | Server socket buffer size in bytes. |
| serverIntrospectionRegistryMaxSize | Maximum number of introspection registry entries server is able to handle. |
| Member | Description |
|---|---|
| clientReceiveBufferSize | Client receive buffer size in bytes. |
| clientReceiveSocketBufferSize | Client socket buffer size in bytes. |
| clientIntrospectionRegistryMaxSize | Maximum number of introspection registry entries client is able to handle. |
| connectionQoS | Connection QoS parameters. |
| bit | Description |
|---|---|
| 0-6 | Priority level [0-100]. |
| 7 | Unused, MUST be 0. |
| 8 | Low-latency priority. |
| 9 | Throughput priority. |
| 10 | Enable compression. |
| 11-15 | Unused, MUST be 0. |
Each Quality of Service (QoS) parameter value REQUIRES a separate TCP/IP connection. If the Low-latency priority bit is set, this indicates clients should attempt to minimize latency if they have the capacity to do so. If the Throughput priority bit is set, this indicates a client similarly should attempt to maximize throughput. How this is achieved is implementation defined. The Compression bit enables compression for the connection Which compression? From which support layer. A matter for a future version of the specification should be whether a streaming mode algorithm should be specified.
An Echo diagnostic message is usually sent to check if TCP/IP connection is still valid. It can also be broadcast over UDP/IP to get list of all servers in the subnet (note that UDP does not guarantee delivery).
struct echoRequest { byte[] somePayload; }; struct echoResponse { byte[] samePayloadAsInRequest; };
| Member | Description |
|---|---|
| somePayload | Arbitrary payload content, can be empty. |
| Member | Description |
|---|---|
| samePayloadAsInRequest | Same paylaod as in request message. |
A channel "search request" message SHOULD be sent over UDP/IP, however UDP congestion control SHOULD be implemented in this case. A server MUST accept this message also over TCP/IP.
struct searchRequest { int searchSequenceID; byte replyRequired; struct { int searchInstanceID; string channelName; } channels[]; };
| Member | Description |
|---|---|
| searchSequenceID | Search sequence ID (counter w/ rollover), can be used by congestion control algorithms. |
| replyRequired | 0x01 to force server to respond even if it does not host channel(s), 0x00 otherwise. |
| searchInstanceID | ID to be used to associate response with the following channel name. |
| channelName | Non-empty channel name, maximum length of 500 characters. |
The response to a search request is defined as messageCommand 0x04, see below.
A "search response" message MUST be sent as the response to a search request (0x03) message.
struct searchResponse { int searchSequenceID; boolean found; byte[16] serverAddressIPv6; short serverPort; string protocol; int[] searchInstanceIDs; };
| Member | Description |
|---|---|
| searchSequenceID | Search sequence ID, same as specified in search request. |
| found | Flag indicating whether response contains IDs of found or not found channels. |
| serverAddressIPv6 | Server IPv6 address (or IPv6 encoded IPv4 address). |
| serverPort | Server port (where server is listening). |
| protocol | Protocol name, "tcp" for standard pvAccess TCP/IP communication. |
| searchInstanceIDs | IDs, associated with names in the request, relevant to this response. |
A client MUST examine the protocol member field to verify it supports the given exchange protocol; if not, the search response is ignored.
A channel provides a communication path beween a client and a server hosted "process variable."
Each channel instance MUST be bound only to one connection.
struct createChannelRequest { struct { int clientChannelID; string channelName; } channels[]; }; struct createChannelResponse { int clientChannelID; int serverChannelID; Status status; [if status.type == OK | WARNING] short accessRights; };
| Member | Description |
|---|---|
| clientChannelID | Client generated channel ID. |
| channelName | Name of the channel to be created, non-empty and maximum length of 500 characters. |
| Member | Description |
|---|---|
| clientChannelID | Client generated channel ID, same as in request |
| serverChannelID | Server generated channel ID. |
| status | Completion status. |
| accessRights | Access rights (TBD). |
NOTE: A server MUST store the clientChannelID and respond back with its value in a destroyChannelMessage when channel destroy request is requested, see below. A client uses the serverChannelID value for all subsequent requests on the channel. Agents SHOULD NOT make any assumptions about how given IDs are generated. IDs MUST be unique within a connection and MAY be recycled after a channel is disconnected.
A "destroy channel" message is sent to a server to destroy a channel that was previously created (with a create channel message).
struct destroyChannelRequest { struct { int clientChannelID; int serverChannelID; } channels[]; }; struct destroyChannelResponse { struct { int clientChannelID; int serverChannelID; Status status; } channels[]; };
| Member | Description |
|---|---|
| clientChannelID | Client generated channel ID, same as in create request. |
| serverChannelID | Server generated channel ID, same as in create response. |
| Member | Description |
|---|---|
| clientChannelID | Client generated channel ID, same as in create request. |
| serverChannelID | Server generated channel ID, same as in create response. |
| status | Completion status. |
If the request (clientChannelID, serverChannelID) pair does not match, the server MUST respond with an error status. The server MAY break its response into several messages.
NOTE: A server MUST send this message to a client to notify the client about
server-side initiated channel destruction. Subsequently, a client MUST mark such
channels as disconnected. If the client's interest in the process variable continues,
it MUST start sending search request messages for the
channel.
A "channel get" set of messages are used to retrieve (get) data from the channel.
struct channelGetRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08 for INIT; FieldDesc pvRequestIF; PVField pvRequest; }; struct channelGetResponseInit { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] FieldDesc pvStructureIF; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | pvRequest Field description. |
| pvRequest | pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
| pvStructureIF | pvStructure (data container) Field description. |
After a get request is successfully initialized, the client can issue actual get request(s).
struct channelGetRequest { int serverChannelID; int requestID; byte subcommand = 0x40 for GET; additional 0x10 mask for DESTROY; }; struct channelGetResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] BitSet changedBitSet; [if status.type == OK | WARNING] PVField pvStructureData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x40 for GET, additional 0x10 mask for DESTROY. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| changedBitSet | Changed BitSet for pvStructureData. |
| pvStructureData | Data structure. |
NOTE: if the DESTROY mask is applied, the server MUST destroy request after get response and the client MUST do the same after it receives the response.
A "channel put" set of messages are used to set (put) data to the channel.
struct channelPutRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08; FieldDesc pvRequestIF; PVField pvRequest; }; struct channelPutResponseInit { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] FieldDesc pvPutStructureIF; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | pvRequest Field description. |
| pvRequest | pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
| pvPutStructureIF | pvPutStructure (data container) Field description. |
After a put request is successfully initialized, the client can issue actual put request(s) on the channel.
struct channelPutRequest { int serverChannelID; int requestID; byte subcommand = 0x00 for PUT; 0x10 mask for DESTROY; BitSet toPutBitSet; PVField pvPutStructureData; }; struct channelPutResponse { int requestID; byte subcommand; Status status; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x00 for PUT, additional 0x10 mask for DESTROY. |
| toPutBitSet | To-put BitSet for pvPutStructureData. |
| pvPutStructureData | Data to put structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
A "get-put" request retrieves the remote put structure. This MAY be used by user applications to show data that were set last time by the application.
struct channelGetPutRequest { int serverChannelID; int requestID; byte subcommand = 0x40; }; struct channelGetPutResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] PVField pvPutStructureData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x40. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| pvPutStructureData | Remote put data structure. |
A "channel put-get" set of messages are used to set (put) data to the channel and then immediately retrieve data from the channel. Channels are usually "processed" or "updated" by their host between put and get, so that the get reflects changes in the process variable's state.
struct channelPutGetRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08; FieldDesc pvRequestIF; PVField pvRequest; }; struct channelPutGetResponseInit { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] FieldDesc pvPutStructureIF; [if status.type == OK | WARNING] FieldDesc pvGetStructureIF; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | pvRequest Field description. |
| pvRequest | pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
| pvPutStructureIF | pvPutStructure (data container) Field description. |
| pvGetStructureIF | pvGetStructure (data container) Field description. |
After a put-get request is successfully initialized, the client can issue actual put-get request(s) on the channel.
struct channelPutGetRequest { int serverChannelID; int requestID; byte subcommand = 0x00 for PUT_GET; 0x10 mask for DESTROY; BitSet toPutBitSet; PVField pvPutStructureData; }; struct channelPutGetResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] PVField pvGetStructureData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x00 for PUT_GET, additional 0x01 mask for DESTROY. |
| toPutBitSet | To-put BitSet for pvPutStructureData. |
| pvPutStructureData | Data to put structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| pvGetStructureData | Get data structure. |
A "get-put" request retrieves the remote put structure. This MAY be used by user applications to show data that were set last time by the application.
struct channelGetPutRequest { int serverChannelID; int requestID; byte subcommand = 0x80; }; struct channelGetPutResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] PVField pvPutStructureData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x80. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| pvPutStructureData | Remote put data structure. |
A "get-get" request retrieves remote get structure. This MAY be used by user applications to show data that were retrieved last time.
struct channelGetGetRequest { int serverChannelID; int requestID; byte subcommand = 0x40; }; struct channelGetGetResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] PVField pvGetStructureData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x40. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| pvGetStructureData | Remote get data structure. |
The "channel monitor" set of messages are used to by client agents to indicate that they wish to be asynchronously informed of changes in the state or values of the process variable of a channel. The subscribe mechanism is employed.
struct channelMonitorRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08; FieldDesc pvRequestIF; PVField pvRequest; }; struct channelMonitorResponseInit { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] FieldDesc pvStructureIF; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | pvRequest Field description. |
| pvRequest | pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
| pvStructureIF | pvStructure (data container) Field description. |
The pvRequest structure SHOULD be used to specify monitor queue size and algorithm. How it may be used for those functions is not defined by pvAccess, and so would be implementation defined.
After monitor request is successfully initialized, the client can issue actual monitor request(s).
The following messages MUST be used to start (resume) or stop (suspend) monitoring and to destroy monitor request (subscription):
struct channelStartMonitorRequest { int serverChannelID; int requestID; byte subcommand = 0x44; };
struct channelStopMonitorRequest { int serverChannelID; int requestID; byte subcommand = 0x04; };
struct channelDestroyMonitorRequest { int serverChannelID; int requestID; byte subcommand = 0x10; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x44 for START, 0x04 for STOP, 0x10 for DESTROY. |
The response for monitor requests above has the following form:
struct channelMonitorResponse { int requestID; byte subcommand = 0x00; BitSet changedBitSet; PVField pvStructureData; BitSet overrunBitSet; };
| Member | Description |
|---|---|
| requestID | Request ID, same as in monitor init request message. |
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x00. |
| changedBitSet | Changed BitSet for pvStructureData. |
| pvStructureData | Data structure. |
| overrunBitSet | BitSet indicating overrun fields. |
A "channel array" set of messages are used to handle remote array values. Requests allow a client agent to: retrieve (get) and set (put) data from/to the array, and to change the array's length (number of valid elements in the array) and capacity.
struct channelArrayRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08; FieldDesc pvRequestIF; PVField pvRequest; }; struct channelArrayResponseInit { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] FieldDesc pvArrayIF; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | pvRequest Field description. |
| pvRequest | pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
| pvArrayIF | pvArray (data container) Field description. |
After an array request is successfully initialized, the client can issue actual array request(s).
struct channelGetArrayRequest { int serverChannelID; int requestID; byte subcommand = 0x40 mask for GET; 0x10 mask for DESTROY; int offset; int count; }; struct channelGetArrayResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] PVField pvArrayData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x40 for GET, additional 0x10 mask for DESTROY. |
| offset | Offset from the beginning of the array (if positive) or end of the array (if negative). |
| count | Number of elements requested, -1 means form offset to the end of the array. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| pvArrayData | Data array. |
struct channelPutArrayRequest { int serverChannelID; int requestID; byte subcommand = 0x00 mask for PUT; 0x10 mask for DESTROY; int offset; PVField pvArrayData; }; struct channelPutArrayResponse { int requestID; byte subcommand; Status status; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x00 for PUT, additional 0x10 mask for DESTROY. |
| offset | Offset from the beginning of the array (if positive) or end of the array (if negative) where to put given subarray. |
| pvArrayData | Subarray to be put. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
struct channelSetLengthRequest { int serverChannelID; int requestID; byte subcommand = 0x80 mask for SET_LENGTH; 0x10 mask for DESTROY; int length; int capacity; }; struct channelSetLengthResponse { int requestID; byte subcommand; Status status; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x40 for GET, additional 0x10 mask for DESTROY. |
| length | New length, -1 to keep old value. |
| capacity | New capacity, -1 to keep old value. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
A "destroy request" messages is used destroy any request instance, i.e. an instance with requestID.
// destroys any request with given requestID struct destroyRequest { int serverChannelID; int requestID; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in request init message. |
A "channel process" set of messages are used to indicate to the server that the computation actions associated with a channel should be executed. That is in the language of EPICS, the channel should be "processed".
struct channelProcessRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08; FieldDesc pvRequestIF; [if serverStatusIF != NULL_TYPE_CODE] PVField pvRequest; }; struct channelProcessResponseInit { int requestID; byte subcommand; Status status; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | Optional pvRequest Field description, NULL_TYPE_CODE is none. |
| pvRequest | Optional pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
After a process request is successfully initialized, the client can issue actual process request(s).
struct channelProcessRequest { int serverChannelID; int requestID; byte subcommand = 0x00 mask for PROCESS; 0x10 mask for DESTROY; }; struct channelProcessResponse { int requestID; byte subcommand; Status status; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x00 for PROCESS, additional 0x10 mask for DESTROY. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
A "get channel type introspection data" messages is used to retrieve a channel's type introspection data, i.e. a description of all the channel's fields and their data types.
struct channelGetFieldRequest { int serverChannelID; int requestID; string subFieldName; // entire record if empty }; struct channelGetFieldResponse { int requestID; Status status; [if status.type == OK | WARNING] FieldDesc subFieldIF; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subFieldName | Name of the subfield to get or entire record if empty. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| status | Completion status. |
| subFieldIF | Requested field introspection data. |
A "message" message is used by a server to provide to a client human readable text regarding the status of a specific request. This message MUST NOT be used to report request completion status.
struct message { int requestID; byte messageType; // info = 0, warning = 1, error = 2, fatalError = 3 string message; };
| Member | Description |
|---|---|
| requestID | Request ID. |
| messageType | Message type enum. |
| message | Message. |
The "channel RPC" set of messages are used to provide remote procedure call (RPC) support over pvAccess.
struct channelRPCRequestInit { int serverChannelID; int requestID; byte subcommand = 0x08; FieldDesc pvRequestIF; PVField pvRequest; }; struct channelRPCResponseInit { int requestID; byte subcommand; Status status; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Client generated request ID. |
| subcommand | 0x08 |
| pvRequestIF | pvRequest Field description. |
| pvRequest | pvRequest structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | 0x08, same as in request message. |
| status | Completion status. |
After a RPC request is successfully initialized, the client can issue actual RPC request(s).
struct channelRPCRequest { int serverChannelID; int requestID; byte subcommand = 0x00 mask for RPC; 0x10 mask for DESTROY; FieldDesc pvStructureIF; PVField pvStructureData; }; struct channelRPCResponse { int requestID; byte subcommand; Status status; [if status.type == OK | WARNING] FieldDesc pvResponseIF; [if status.type == OK | WARNING] PVField pvResponseData; };
| Member | Description |
|---|---|
| serverChannelID | Server generated channel ID, same as in create channel response. |
| requestID | Request ID, same as in init message. |
| subcommand | 0x00 for RPC, additional 0x10 mask for DESTROY. |
| pvStructureIF | pvStructureData Field description. |
| pvStructureData | Argument data structure. |
| Member | Description |
|---|---|
| requestID | Request ID, same as in request message. |
| subcommand | Same as in request message. |
| status | Completion status. |
| pvResponseIF | pvResponseDataField description. |
| pvResponseData | Response data structure. |
This section describes the message payloads for control messages. Each subsection describes a single message command (pvAccessHeader.messageCommand).
Control messages have no payload and are used internally by the protocol, for instance to handle byte order management and flow control.
The payload size field contains control message specific values.
Payload size field holds the value of total bytes sent. The client should respond with acknowledgment control message (0x01) as soon as possible.
Payload size field holds the acknowledge value of total bytes received. This must match the previously received marked value as described above.
The 7-th bit of a header flags field indicates the server's selected byte order for
the connection on which this message was received.
Client MUST encode all the messages sent via this connection using this byte
order.
The client's decoding byte order depends on payload size field value as follows:
| Payload Size Field Value | Meaning |
|---|---|
| 0x00000000 | Client MUST decode all the messages received via this connection using server's selected byte order. |
| 0xFFFFFFFF | Client MUST decode all the messages sent received this connection as indicated by each message byte order flag. |
This MUST be the first message sent by a server when connection is established. For connection-less protocols this message is not sent and byte order is determined per message using its byte order flag.
NOTE: this message is byte order independent.
Diagnostic/test echo message. Receiver should respond with Echo response (0x04) message with the same payload size field value.
Response to a echo request. Payload size field contains the same value as in request message.
The following are known items that should be specified in future revisions:


Source code for pyidwm.helper.Projection
# -*- coding: utf-8 -*-
from pyproj import Proj
from ..Config import Config
from ..Units import *
WGS84_PROJECTION = Proj("epsg:4326")
[docs]class Projection:
[docs] @staticmethod
def get_aeqd_wkt_proj(lon, lat, angle_mode=None):
"""
What we will need for real great circles in a GIS is something that preserves distances and angles.
We use an azimuthal equidistant projection which needs to be defined for a custom starting point.
:param lon: longitude of the starting point
:param lat: latitude of the starting point
:param angle_mode: units of the angles (degrees/radians)
:return:
"""
if angle_mode is None:
angle_mode = Config().angle_mode
lon = Angle.CONVERT(lon, angle_mode, Angle.DEGREES)
lat = Angle.CONVERT(lat, angle_mode, Angle.DEGREES)
projection_def = "+proj=aeqd +lat_0=%4.8f +lon_0=%4.8f +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs" \
% (lat, lon)
return projection_def
[docs] @staticmethod
def get_aeqd_proj(lon, lat, angle_mode=None):
"""
What we will need for real great circles in a GIS is something that preserves distances and angles.
We use an azimuthal equidistant projection which needs to be defined for a custom starting point.
:param lon: longitude of the starting point
:param lat: latitude of the starting point
:param angle_mode: units of the angles (degrees/radians)
:return:
"""
projection = Proj(Projection.get_aeqd_wkt_proj(lon, lat, angle_mode))
return projection


| Home > Documentation > Installing and running > Initial configuration > Changing the username and password |
The default administration user name and password for the Geronimo Administrative Console and command line deployment tool is system and manager respectively. You can change these defaults directly from the Administration Console by accessing Security -> Console Realm and change the user name and password from the Console Realm Users portlet.
Alternatively, you can make the same changes by editing the users.properties
and groups.properties
files, both located in the <geronimo_home>/var/security
directory.
Important
Access to the <geronimo_home>/var/security
directory should be appropriately secured. Different operating systems offer different alternatives to securing files and directories. Most cases would involve restricting permission to specific user groups.
Passwords in users.properties
file are encrypted by the server. Passwords can be changed using the Geronimo Administrative Console. They can also be changed using a text editor. While the server is stopped, simply edit the users.properties
file. The password(s) will be encrypted the next time the server is started.
To prevent potential security exposures, we strongly recommend you update the default user names and passwords on your system.
Open the <geronimo_home>/var/security/groups.properties
file and edit the contents of this file. Add any username that you require and save the file.
admin=user1,user2
Next, open the <geronimo_home>/var/security/users.properties
file. You can change the password for the existing system account and/or add new users. When adding a new user, the username has to be the same as the one added to the groups.properties
file.
user1=password1 user2=password2
In this example, two users have been added, user1 and user2 and the default system account has been deleted. Both user1 and user2 can access the console and the command line deployment tools.
Log into the Geronimo Administration Console and click on Users and Groups on the console navigation panel. This will display the Console Realm Users and Console Realm Groups portlets.
Visit the Administering security section for more details on all the security related settings.
| Bookmark this on Delicious Digg this | Privacy Policy - Copyright © 2003-2013, The Apache Software Foundation, Licensed under ASL 2.0. |


which District you prefer! Enjoy locally
Kasargod
Explore
Kannur
Explore
Waynad
Explore
Kozhikode
Explore
Malapuram
Explore
Palakkad
Explore
Thrissur
Explore
Ernakulam
Explore
Idukki
Explore
Kottayam
Explore
Alappuzha
Explore
Pathanamthitta
Explore
Kollam
Explore
Trivandrum
Explore
Back