Hi all,
First post here, i have just received a Raspberry Pi, 3 x emonTx V3 and GLCD.
The property has 3 phase incoming and we have a 3 phase solar 7kW inverter.
I want to be able to monitor each of the 3 phases coming in to the property, each of the 3 phases on the inverter, lighting, oven, garage, pool, power outlets and hot water.
Can someone point me in the correct direction as to how this should be set up as far as sketches go?
Thanks
Grant
Re: What i can monitor
First question: do you have any genuine 3-phase loads (i.e. motors), or are they all single-phase loads connected to one of three phases?
Second question - what is your system voltage (phase-neutral)?
Third - Do you have 3 ac adapters?
Fourth - How are the loads that you want to individually measure split across the three phases?
Depending on the answers to those, I suspect the most simple and accurate way for you is to use one emonTx per phase, running the "continuous" sketch. The three TX's won't report their results synchronously, so you'll get 3 sets of 4 readings going to both your RPi and to your GLCD. (No, the GLCD gets its data direct from the emonTx's by default). You'll need to modify your GLCD sketch to listen to all 3 emonTx's, and maybe combine some of the values. You cannot get too ambitious in the GLCD, memory is extremely limited.
First alternative: It should be possible to send the data back from your RPi to the GLCD - Paul (PB66) might be able to confirm that, and what processing can be done in the RPi
Second alternative: If you don't have two infeeds + 2 separate loads per phase, then you've got to do some fiddles to shift the voltage waveform to be synchronous with the load on the 'other' phase. That will need a new sketch (a merge of the 'continuous' and 'three-phase').
I don't want to go any further until you've thought about that.
Re: What i can monitor
Thanks Robert,
1. I have no 3 phase loads.
2. 240v (new Zealand)
3. yes have three ac adaptors
4.
phase 1 - hot water
Phase 2 - Oven & Pool
Phase 3 - everything else.
Re: What i can monitor
In that case, my main proposal will give you the 3 nett grid connection powers/energies, the 3 PV infeed powers/energies, then separately Oven, Pool and the option of splitting everything else into two groups. Note that you can uprate the 4th input on your emonTx V3 by adding a parallel resistor to the existing burden, should you need to, and if "everything else" is on separate feeds, then provided it's physically possible you can put several wires through the CT and get the total current that way. (They must be the same phase of course, else you get the vector sum, which isn't what you want.) You will have a spare input on the Phase 1 emonTx, it sounds as if you're happy with that.
Alternative 2 looks to be dead. We'll prod Paul if you're keen to look at Alternative 1. The GLCD gets the time by that route anyway, and its sketch will almost certainly need some work done, depending on how much detail you want to display on it.
Re: What i can monitor
Sending data out over RFM from emonHub is possible. The current version only sends the time update for glcd (there is also a "hack" to add PacketGen) but this is a big part of current developments and will hopefully be widely implemented in the not too distant future.
We could in the mean time add a very simple "PacketGen like hack" to "fetch" the data you need from emonCMS and broadcast it, this may add a couple of seconds to the responsiveness but it will also allow the data from 3 phases to be sent to glcd via 1 payload rather than 3 so should help with the limited resources at the glcd end.
Aligning the data of the 3 phases maybe something you want to consider, not just for the glcd display but for the whole project, Maybe you also could use the glcd transmission from emonHub to trigger or align the 3 emonTx's.
Happy to chip in where I can if needed
Paul
Re: What i can monitor
I haven't looked at Robin's 'continuous' sketch with a view to synchronising the totals, presumably the 3 emonTx's are close together and I'd have favoured extending MartinR's "full-fat" serial comms solution - where the master synchronises and requests data from the others and only itself transmits, in preference to receiving synchronising commands by radio. But that'll need developing, Martin did 'discretesampling', not continuous.
Re: What i can monitor
Unfortunately I²C isn't an (easy) option with the emonTx v3 as A4 and A5 are already used.
Shame really as I already have a working I²C set-up where the Pi is the master and a number of emonTx v2 based boards are "polled". The method I use is possibly the closest we will achieve to absolute identical timing as the Pi broadcasts a calculations trigger and then collects the payloads one after the other during the interval.
It reminds me of school and written exams, the Pi screams "times up, pens down" and then goes about collecting "the exam papers" at it's own pace. Do they still use pen and paper in exams these days?
Paul
Re: What i can monitor
Hi Guys,
This is all new to me so please be patient.
Thanks for your responses. I'm thinking that i get the correct data out of the system before I start playing around with getting the GLCD running.
Photo attached of the three emonTx's installed, ignore the labels on them as they are now incorrect.
As you can see from those labels in the photo, that was how i have planed to monitor the power and have them set up.
What we are saying now is I can only monitor circuits on the emonTx that are on the same phase?
Node10: CT1=Grid1, CT2=PV2, CT3=Hotwater
Node11: CT1=Grid2, CT2=PV2, CT3=Lights, CT4=Garage
Node12: CT1=Grid3, CT2=PV3, CT3=Oven, CT4=Pool
Do the AC adapters need to be powered from there own phase also?
Re: What i can monitor
They do indeed need to be on the same phase as the current clamps, effectively each emonTx is specific to one phase only.
Re: What i can monitor
Thanks,
So i have some work to do, I'll add three power points to allow the AC adaptors to be connected to each of there own phases.
and to ensure i can use all the inputs from the emonTx's, I'll shift something from Phase 2, lighting perhaps,(everything else) to Phase 1 which currently has only the hot water.
I'll upload MartinR's "full-fat" sketch and see what results i get.
Re: What i can monitor
Good to see another Kiwi on here pushing the boundaries ;). Welcome from ChCh.
Re: What i can monitor
Thanks for the welcome from Waikanae, Wellington.
Re: What i can monitor
I'm locked out again.
Re: What i can monitor
Hi there,
best regards from Germany to all Kiwis out there... I love NZ... ;-)
@pb66: I am also heavily interested in sending data from emoncms to an emonGLCD. Could you point me in the right direction what to do to transmit a feed value via emonHub? How to implement this "PacketGen like hack"?
Thank you very much
Matthias
Re: What i can monitor
"I'll upload MartinR's "full-fat" sketch and see what results i get."
I don't advise that! It is for the emonTx V2, therefore all the I/O pin numbers will be different, the radio is probably different and might need a different JeeLib, and there are problems with the serial data connection as Paul points out.
The reason for suggesting that each emonTx deals with one phase only was accuracy. The AC adapter is both a power supply AND a voltage measurement. The emonTx 3-phase sketch makes an educated guess at the voltage of the 2nd & 3rd phases - see the comments in the sketch for the details and the side effects. Keeping one emonTx per phase removes all those errors/guesses.
Re: What i can monitor
@Matthias, Sure, if you want to start a thread with some details we can see if we can throw something together, it will be just a hard-coded "hack" though, a better solution is in the pipework.
Paul
Re: What i can monitor
Hi All,
So I have now installed the three power points one on each phase.
I have left the default emonTx sketch on each of the emonTx's.
I have not yet replaced the labels on each of the emonTx's, so they are incorrect still.
So i have been watching the PV outputs, they do not appear to be correct, the inverter is saying its producing 213Wand the emonTx's are saying 154W.
Re: What i can monitor
[Hopefully, normal service is resumed, and I can answer now!]
Something's not right there. Is it just the PV inputs, or is everything wrong by the same factor?
First, are you on the right phase? And have you checked the calibration? The numbers don't appear to have the right relationship for just one problem (like phase, where I'd expect a factor of cos(120°), and it's far too far out to be a straightforward calibration discrepancy, so I don't have an immediate solution, and some detective work is required.
What ac adapters are you using (what is the output voltage at what mains input voltage?), which CTs are you using?
Is the 3.3 V d.c. on your emonTx's roughly right?
Re: What i can monitor
Not sure about anything of the other inputs, as I'm not sure how to messure them.
What I'm doing is adding the 3 PV outputs that are being measured by the three emonTx from the input display of emoncms and comparing there total to what the inverter is telling me. see attached.
Is this the correct way of checking it?
How can i check what is on each Phase and compare it to the inputs on emoncms?
I'll double check to ensure i have each clip on the correct wire,the board is a mess so its hard to locate the correct one.
I'm using the CT's purchased from open energy store.
The adaptor is one someone suggested on the forums http://www.jaycar.co.nz/productView.asp?ID=MP3027&form=CAT2&SUBCATID=100... the output voltage from the AC adpator later today,the mains input is 240ish volts.I'll get teh specifications from the packaging tonight.
Re: What i can monitor
"What I'm doing is adding the 3 PV outputs that are being measured by the three emonTx from the input display of emoncms and comparing there total to what the inverter is telling me. see attached."
That should be the correct way, what we need to know is whether all are wrong by the same proportion, or whether one or more is wrong by different amounts. Can your inverter tell you the output per phase? That there is a big spread of values makes me a little suspicious.
If you are not using the "shop" adapter, you certainly need to check and most probably adjust the calibration. (That link does not tell me any details of the adapter sufficient for me to calculate a coefficient. If you can measure the actual mains voltage and the actual output voltage of the adapter, then it's possible to get the exact value. Alternatively, you could simply tweak the coefficients until all 3 emonTx's read the same mains voltage as your meter/the inverter. And yes, I would expect them to be fractionally different.)
We can worry about the power when we have the voltage correct.
Re: What i can monitor
Not sure if the inverter is able to tell me per phase will try and find out.
Yeah, not able to use the shop adaptor as there is no version for a NZ outlet. I'll get the specifications from the packaging and measure the input and output voltages.
Re: What i can monitor
Here are the calculations I use to scale/calibrate my EmonTX sketch (using the same adaptor from Jaycar). Even with the measured output voltage I still have to scale my readings by a factor of about 2.6 to get something accurate. But it has been running fine like this for quite a few months and seems to be very stable/consistent.
Calibrating after a full months data will hopefully improve things more - I just calibrated a few days ago after getting my monthly bill and comparing to what I measured. Will check again in a months time...
Re: What i can monitor
It's helpful of you, Ben, but it isn't definitive because ordinary component tolerances come into play, in the voltage regulator and resistors tolerances as well as the adapter tolerance and regulation. It's all spelled out in Building Blocks. So Grant, apart from having an emonTx rather than the Shield, will need to tweak his calibration constants in any case.
Re: What i can monitor
Yep - agree - was more just showing the steps I went thru and how much of a scale factor I had to apply in order to get accurate results. Hope I haven't confused the issue... :S
Re: What i can monitor
Hey sumnerboy, i was confused before you posted anything.
Ok, I have had a look at the building blocks calibration page and are confused now.
Phase 1 - Mains = 243.2 - AC output = 11.49
Phase 2 - Mains = 245.3 - AC output = 11.65
Phase 3 Mains = 244.6 - AC output = 11.59
Re: What i can monitor
OK, we can use those values to calculate your voltage calibration constants. First, the ratios aren't the same (manufacturing tolerances, as I said!). Second, the numbers I'm going to give you do not take into account the resistor tolerances in your emonTx, nor the tolerance of the voltage regulator which is used as the reference.
The voltage calibration constants are:
Phase 1: 243.2 × 13 ÷ 11.49 = 275.161
Phase 2: 245.3 × 13 ÷ 11.65 = 273.725
Phase 3: 244.6 × 13 ÷ 11.59 = 274.357
(13 is the voltage divider ratio = (120k + 10k) ÷ 10k)
Those aren't vastly different to the default values, so don't expect to see a massive change in the numbers.
Re: What i can monitor
I have the new sketch's in place on the emonTx's, so at least the readings are close enough for now.
Are there any good instructions on emoncms and setting up inputs & feeds etc, I have some working however they probably need some tweaking.
GLCD is the next thing i have loaded up the SolarPV sketch and this appears to be working however of course its only for one phase.
Is it possible to pull the readings for the GLCD from the feeds in emoncms?
Re: What i can monitor
"Is it possible to pull the readings for the GLCD from the feeds in emoncms?"
It should be possible - Paul's answered that in outline above.
Failing that, and bearing in mind memory in the GLCD is limited, you could try modifying that. Here's what you need to do in outline:
Add two extra instances of PayloadTX (one for each emonTx - let's call them emontx1, emontx2, emontx3).
Replicate the code that checks and stores the emonTx data: "if (node_id == emonTx_nodeID)..." once for each emonTx (3 node ID's required).
Finally, you'll need change "power_calculations()" to add up the three phases. Doing it this way will update the power and the display each time a set of data comes in - this may not be your choice and you might want to look at treating one phase as "master" and updating only when that sends the data.
You'll need to have lines like "consuming = emontx1.power1 + emontx2.power1 + emontx3.power1;", etc.
Re: What i can monitor
As Robert, points out there is more than one way to do it, with pro's and con's to both. If the glcd's limited memory is able to cope with the extra code it maybe a more permanent solution as a "emonHub hack" to retrieve data from emoncms could get "broken" by future emonhub updates.
However following the earlier suggestions Matthias(McFly) started this thread How to send feed data from emoncms to emonGLCD?, He has implemented and shared a working solution that could work for you too.
Paul
Re: What i can monitor
Thanks for the replies I'll have a play around and post the results.
Re: What i can monitor
So hopefully I have got something together I'll try it tonight.
Is there anyway to include an external temperature reading from either underground weather or PVoutput both sites have the temp from my weather station?
I guess the best way of doing this would be to get the temperature on to the emoncms server, which for me is local, and grab it from there that way any network issues that are outside me control will not be effected.
I'm not using the temperature senor on the emonTx, I have a prefect temperature sitting on my roof, just a matter on how to get it back to the GLCD.
Re: What i can monitor
I see no reason why you shouldn't be able to get another value, depending on what you have already you could possibly get the external temp and append it to the same payload as the feed values,
The only concern is holding up emonhub if the network is slow or a website is down etc, more elaborate code could be used to run the requests in a separate thread.
Paul
Re: What i can monitor
ok, so i have made some progress, I thought...
this is the edited sketch i'm now using and mostly it is working.with the exception of a couple of cases which i'll explain after the sketch. I have highlighted the lines I have either added or edited to include all 3 phases.
//------------------------------------------------------------------------------------------------------------------------------------------------
#define RF69_COMPAT 0 // set to 1 to use RFM69CW
#include <JeeLib.h> // make sure V12 (latest) is used if using RFM69CW
#include <JeeLib.h>
#include <GLCD_ST7565.h>
#include <avr/pgmspace.h>
GLCD_ST7565 glcd;
#include <OneWire.h> // http://www.pjrc.com/teensy/td_libs_OneWire.html
#include <DallasTemperature.h> // http://download.milesburton.com/Arduino/MaximTemperature/ (3.7.2 Beta needed for Arduino 1.0)
#include <RTClib.h> // Real time clock (RTC) - used for software RTC to reset kWh counters at midnight
#include <Wire.h> // Part of Arduino libraries - needed for RTClib
RTC_Millis RTC;
//--------------------------------------------------------------------------------------------
// RFM12B Settings
//--------------------------------------------------------------------------------------------
#define MYNODE 20 // Should be unique on network, node ID 30 reserved for base station
#define RF_freq RF12_433MHZ // frequency - match to same frequency as RFM12B module (change to 868Mhz or 915Mhz if appropriate)
#define group 210 // network group, must be same as emonTx and emonBase
//---------------------------------------------------
// Data structures for transfering data between units
//---------------------------------------------------
typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms
PayloadTX emontx1;
PayloadTX emontx2;
PayloadTX emontx3;
typedef struct { int temperature; } PayloadGLCD;
PayloadGLCD emonglcd;
//---------------------------------------------------
// emonGLCD SETUP
//---------------------------------------------------
//#define emonGLCDV1.3 // un-comment if using older V1.3 emonGLCD PCB - enables required internal pull up resistors. Not needed for V1.4 onwards
const int SolarPV_type=1; // Select solar PV wiring type - Type 1 is when use and gen can be monitored seperatly. Type 2 is when gen and use can only be monitored together, see solar PV application documentation for more info
const int maxgen=7000; // peak output of soalr PV system in W - used to calculate when to change cloud icon to a sun
const int PV_gen_offset=50; // When generation drops below this level generation will be set to zero - used to force generation level to zero at night
const int greenLED=6; // Green tri-color LED
const int redLED=9; // Red tri-color LED
const int LDRpin=4; // analog pin of onboard lightsensor
const int switch1=15; // Push switch digital pins (active low for V1.3, active high for V1.4)
const int switch2=16;
const int switch3=19;
//---------------------------------------------------
// emonGLCD variables
//---------------------------------------------------
int hour = 12, minute = 0;
double usekwh = 0, genkwh = 0;
double use_history[7], gen_history[7];
int cval_use, cval_gen;
byte page = 1;
//---------------------------------------------------
// Temperature Sensor Setup
//---------------------------------------------------
#define ONE_WIRE_BUS 5 // temperature sensor connection - hard wired
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
double temp, maxtemp,mintemp;
//--------------------------------------------------------------------------------------------
// Flow control
//--------------------------------------------------------------------------------------------
unsigned long last_emontx; // Used to count time from last emontx update
unsigned long last_emonbase; // Used to count time from last emontx update
boolean last_switch_state, switch_state;
unsigned long fast_update, slow_update;
//--------------------------------------------------------------------------------------------
// Setup
//--------------------------------------------------------------------------------------------
void setup()
{
delay(500); //wait for power to settle before firing up the RF
rf12_initialize(MYNODE, RF_freq,group);
delay(100); //wait for RF to settle befor turning on display
glcd.begin(0x19);
glcd.backLight(200);
sensors.begin(); // start up the DS18B20 temp sensor onboard
sensors.requestTemperatures();
temp = (sensors.getTempCByIndex(0)); // get inital temperture reading
mintemp = temp; maxtemp = temp; // reset min and max
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
#ifdef emonGLCDV1.3 //enable internal pull up resistors for push switches on emonGLCD V1.3 (old)
pinMode(switch1, INPUT); pinMode(switch2, INPUT); pinMode(switch2, INPUT);
digitalWrite(switch1, HIGH); digitalWrite(switch2, HIGH); digitalWrite(switch3, HIGH);
#endif
}
//--------------------------------------------------------------------------------------------
// Loop
//--------------------------------------------------------------------------------------------
void loop()
{
if (rf12_recvDone())
{
if (rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) // and no rf errors
{
int node_id = (rf12_hdr & 0x1F);
if (node_id == 10) {emontx1 = *(PayloadTX*) rf12_data; last_emontx = millis();}
if (node_id == 11) {emontx2 = *(PayloadTX*) rf12_data; last_emontx = millis();}
if (node_id == 12) {emontx3 = *(PayloadTX*) rf12_data; last_emontx = millis();}
if (node_id == 15)
{
RTC.adjust(DateTime(2013, 1, 1, rf12_data[1], rf12_data[2], rf12_data[3]));
last_emonbase = millis();
}
}
}
//--------------------------------------------------------------------------------------------
// Display update every 200ms
//--------------------------------------------------------------------------------------------
if ((millis()-fast_update)>200)
{
fast_update = millis();
DateTime now = RTC.now();
int last_hour = hour;
hour = now.hour();
minute = now.minute();
if (SolarPV_type==1){
usekwh += (emontx1.power1 + emontx2.power1 + emontx3.power1 * 0.2) / 3600000;
genkwh += (emontx1.power2 + emontx2.power2 + emontx3.power2 * 0.2) / 3600000;
}
if (SolarPV_type==2){
usekwh += ((emontx1.power1 + emontx1.power2) * 0.2) / 3600000;
genkwh += (emontx1.power2 * 0.2) / 3600000;
}
if (last_hour == 23 && hour == 00)
{
int i; for (i=6; i>0; i--) gen_history[i] = gen_history[i-1];
genkwh = 0;
for(i=6; i>0; i--) use_history[i] = use_history[i-1];
usekwh = 0;
}
gen_history[0] = genkwh;
use_history[0] = usekwh;
if (SolarPV_type==1){
cval_use = cval_use + (emontx1.power1 + emontx2.power1 + emontx3.power1 - cval_use)*0.50;
cval_gen = cval_gen + (emontx1.power2 + emontx2.power2 + emontx3.power2 - cval_gen)*0.50;
}
if (SolarPV_type==2){
cval_use = cval_use + ((emontx1.power1 + emontx1.power2) - cval_use)*0.50;
cval_gen = cval_gen + ((emontx1.power2 + emontx2.power2 + emontx3.power2) - cval_gen)*0.50;
}
if (cval_gen<PV_gen_offset) cval_gen=0; //set generation to zero when generation level drops below a certian level (at night) eg. 20W
last_switch_state = switch_state;
switch_state = digitalRead(switch1);
if (!last_switch_state && switch_state) { page += 1; if (page>4) page = 1; }
if (page==1)
{
draw_solar_page(cval_use, usekwh, cval_gen, maxgen, genkwh, temp, mintemp, maxtemp, hour,minute, last_emontx, last_emonbase);
glcd.refresh();
}
/*else if (page==2)
{
draw_power_page( "POWER" ,cval_use, "USE", usekwh);
draw_temperature_time_footer(temp, mintemp, maxtemp, hour,minute);
glcd.refresh();
}
else if (page==3)
{
draw_power_page( "SOLAR" ,cval_gen, "GEN", genkwh);
draw_temperature_time_footer(temp, mintemp, maxtemp, hour,minute);
glcd.refresh();
}*/
else if (page==2)
{
draw_history_page(gen_history, use_history);
}
int LDR = analogRead(LDRpin); // Read the LDR Value so we can work out the light level in the room.
int LDRbacklight = map(LDR, 0, 1023, 50, 250); // Map the data from the LDR from 0-1023 (Max seen 1000) to var GLCDbrightness min/max
LDRbacklight = constrain(LDRbacklight, 0, 255); // Constrain the value to make sure its a PWM value 0-255
if ((hour > 22) || (hour < 5)) glcd.backLight(0); else glcd.backLight(LDRbacklight);
int PWRleds= map(cval_use-cval_gen, 0, maxgen, 0, 255); // Map importing value from (LED brightness - cval3 is the smoothed grid value - see display above
if (PWRleds<0) PWRleds = PWRleds*-1; // keep it positive
PWRleds = constrain(PWRleds, 0, 255); // Constrain the value to make sure its a PWM value 0-255
if (cval_gen>PV_gen_offset) {
if (cval_gen > cval_use) { //show green LED when gen>consumption cval are the smooth curve values
analogWrite(redLED, 0);
analogWrite(greenLED, PWRleds);
} else { //red if consumption>gen
analogWrite(greenLED, 0);
analogWrite(redLED, PWRleds);
}
} else { //Led's off at night and when solar PV is not generating
analogWrite(redLED, 0);
analogWrite(greenLED, 0);
}
}
if ((millis()-slow_update)>10000)
{
slow_update = millis();
sensors.requestTemperatures();
double rawtemp = (sensors.getTempCByIndex(0));
if ((rawtemp>-20) && (rawtemp<50)) temp=rawtemp; //is temperature withing reasonable limits?
if (temp > maxtemp) maxtemp = temp;
if (temp < mintemp) mintemp = temp;
emonglcd.temperature = (int) (temp * 100); // set emonglcd payload
rf12_sendNow(0, &emonglcd, sizeof emonglcd); //send temperature data via RFM12B using new rf12_sendNow wrapper -glynhudson
rf12_sendWait(2);
}
}
So this mostly works as per the images labeled correct, what i cant explain is the images labeled FAILED
Re: What i can monitor
You've actually got a "Type 2" installation, according to what you wrote earlier, but the maths you're doing is for a Type 1. So you're doing the wrong sums.
Re: What i can monitor
That was stupid, thanks, have been using the wrong modified sketch.
Re: What i can monitor
Yeah, been there, done that. My favourite is to edit one sketch, load a different copy and wonder why the change hasn't done anything.
Re: What i can monitor
Thanks all for your help, the system is up and running fairly well at the moment, just a few tweaks to make so it's producing what i want it to.


The public key. More...
#include <keys.h>
Public Member Functions | |
| PubKey () | |
| This constructor thorws run-time error if activeContext=nullptr. More... | |
| PubKey (const Context &_context) | |
| PubKey (const PubKey &other) | |
| Copy constructor. More... | |
| virtual | ~PubKey ()=default |
| Default destructor. More... | |
| virtual void | clear () |
| Clear all public-key data. More... | |
| bool | operator== (const PubKey &other) const |
| bool | operator!= (const PubKey &other) const |
| const Context & | getContext () const |
| long | getPtxtSpace () const |
| bool | keyExists (long keyID) const |
| double | getSKeyBound (long keyID=0) const |
| The size of the secret key. More... | |
| bool | isReachable (long k, long keyID=0) const |
| Is it possible to re-linearize the automorphism X -> X^k See Section 3.2.2 in the design document (KeySwitchMap) More... | |
| void | setKeySwitchMap (long keyId=0) |
| Compute the reachability graph of key-switching matrices See Section 3.2.2 in the design document (KeySwitchMap) More... | |
| long | getKSStrategy (long dim) const |
| get KS strategy for dimension dim dim == -1 is Frobenius More... | |
| void | setKSStrategy (long dim, int val) |
| set KS strategy for dimension dim dim == -1 is Frobenius More... | |
| long | Encrypt (Ctxt &ciphertxt, const NTL::ZZX &plaintxt, long ptxtSpace, bool highNoise) const |
| long | Encrypt (Ctxt &ciphertxt, const zzX &plaintxt, long ptxtSpace, bool highNoise) const |
| void | CKKSencrypt (Ctxt &ciphertxt, const NTL::ZZX &plaintxt, double ptxtSize=1.0, double scaling=0.0) const |
| void | CKKSencrypt (Ctxt &ciphertxt, const zzX &plaintxt, double ptxtSize=1.0, double scaling=0.0) const |
| virtual long | Encrypt (Ctxt &ciphertxt, const NTL::ZZX &plaintxt, long ptxtSpace=0) const |
| virtual long | Encrypt (Ctxt &ciphertxt, const zzX &plaintxt, long ptxtSpace=0) const |
| template<typename Scheme > | |
| long | Encrypt (Ctxt &ciphertxt, const Ptxt< Scheme > &plaintxt, long ptxtSpace=0) const |
| Encrypts a plaintext into a ciphertext. More... | |
| bool | isCKKS () const |
| bool | isBootstrappable () const |
| void | reCrypt (Ctxt &ctxt) const |
| void | thinReCrypt (Ctxt &ctxt) const |
| friend | void ::helib::writePubKeyBinary (std::ostream &str, const PubKey &pk) |
| friend | void ::helib::readPubKeyBinary (std::istream &str, PubKey &pk) |
| void | hackPtxtSpace (long p2r) |
| template<> | |
| long | Encrypt (Ctxt &ciphertxt, const Ptxt< BGV > &plaintxt, long ptxtSpace) const |
| template<> | |
| long | Encrypt (Ctxt &ciphertxt, const Ptxt< CKKS > &plaintxt, UNUSED long ptxtSpace) const |
Find key-switching matrices | |
| const std::vector< KeySwitch > & | keySWlist () const |
| const KeySwitch & | getKeySWmatrix (const SKHandle &from, long toID=0) const |
| Find a key-switching matrix by its indexes. If no such matrix exists it returns a dummy matrix with toKeyID==-1. More... | |
| const KeySwitch & | getKeySWmatrix (long fromSPower, long fromXPower, long fromID=0, long toID=0) const |
| bool | haveKeySWmatrix (const SKHandle &from, long toID=0) const |
| bool | haveKeySWmatrix (long fromSPower, long fromXPower, long fromID=0, long toID=0) const |
| const KeySwitch & | getAnyKeySWmatrix (const SKHandle &from) const |
| Is there a matrix from this key to any base key? More... | |
| bool | haveAnyKeySWmatrix (const SKHandle &from) const |
| const KeySwitch & | getNextKSWmatrix (long fromXPower, long fromID=0) const |
| Get the next matrix to use for multi-hop automorphism See Section 3.2.2 in the design document. More... | |
Static Public Member Functions | |
| static long | ePlusR (long p) |
Friends | |
| class | SecKey |
| std::ostream & | operator<< (std::ostream &str, const PubKey &pk) |
| std::istream & | operator>> (std::istream &str, PubKey &pk) |
Detailed Description
The public key.
Constructor & Destructor Documentation
◆ PubKey() [1/3]
| helib::PubKey::PubKey | ( | ) |
This constructor thorws run-time error if activeContext=nullptr.
◆ PubKey() [2/3]
|
explicit |
◆ PubKey() [3/3]
| helib::PubKey::PubKey | ( | const PubKey & | other | ) |
Copy constructor.
◆ ~PubKey()
|
virtualdefault |
Default destructor.
Member Function Documentation
◆ CKKSencrypt() [1/2]
| void helib::PubKey::CKKSencrypt | ( | Ctxt & | ciphertxt, |
| const NTL::ZZX & | plaintxt, | ||
| double | ptxtSize = 1.0 , |
||
| double | scaling = 0.0 |
||
| ) | const |
◆ CKKSencrypt() [2/2]
| void helib::PubKey::CKKSencrypt | ( | Ctxt & | ciphertxt, |
| const zzX & | plaintxt, | ||
| double | ptxtSize = 1.0 , |
||
| double | scaling = 0.0 |
||
| ) | const |
◆ clear()
|
virtual |
Clear all public-key data.
Reimplemented in helib::SecKey.
◆ Encrypt() [1/7]
| long helib::PubKey::Encrypt | ( | Ctxt & | ciphertxt, |
| const NTL::ZZX & | plaintxt, | ||
| long | ptxtSpace, | ||
| bool | highNoise | ||
| ) | const |
Encrypts plaintext, result returned in the ciphertext argument. When called with highNoise=true, returns a ciphertext with noise level approximately q/8. For BGV, ptxtSpace is the intended plaintext space, which cannot be co-prime with pubEncrKey.ptxtSpace. The returned value is the plaintext-space for the resulting ciphertext, which is GCD(ptxtSpace, pubEncrKey.ptxtSpace). For CKKS, ptxtSpace is a bound on the size of the complex plaintext elements that are encoded in ptxt (before scaling), it is assumed that they are scaled by context.alMod.encodeScalingFactor(). The returned value is the same as the argument ptxtSpace.
◆ Encrypt() [2/7]
|
virtual |
Reimplemented in helib::SecKey.
◆ Encrypt() [3/7]
| long helib::PubKey::Encrypt | ( | Ctxt & | ciphertxt, |
| const Ptxt< BGV > & | plaintxt, | ||
| long | ptxtSpace | ||
| ) | const |
◆ Encrypt() [4/7]
| long helib::PubKey::Encrypt | ( | Ctxt & | ciphertxt, |
| const Ptxt< CKKS > & | plaintxt, | ||
| UNUSED long | ptxtSpace | ||
| ) | const |
◆ Encrypt() [5/7]
◆ Encrypt() [6/7]
| long helib::PubKey::Encrypt | ( | Ctxt & | ciphertxt, |
| const zzX & | plaintxt, | ||
| long | ptxtSpace, | ||
| bool | highNoise | ||
| ) | const |
◆ Encrypt() [7/7]
|
virtual |
Reimplemented in helib::SecKey.
◆ ePlusR()
|
static |
◆ getAnyKeySWmatrix()
Is there a matrix from this key to any base key?
◆ getContext()
| const Context & helib::PubKey::getContext | ( | ) | const |
◆ getKeySWmatrix() [1/2]
Find a key-switching matrix by its indexes. If no such matrix exists it returns a dummy matrix with toKeyID==-1.
◆ getKeySWmatrix() [2/2]
| const KeySwitch & helib::PubKey::getKeySWmatrix | ( | long | fromSPower, |
| long | fromXPower, | ||
| long | fromID = 0 , |
||
| long | toID = 0 |
||
| ) | const |
◆ getKSStrategy()
| long helib::PubKey::getKSStrategy | ( | long | dim | ) | const |
get KS strategy for dimension dim dim == -1 is Frobenius
◆ getNextKSWmatrix()
| const KeySwitch & helib::PubKey::getNextKSWmatrix | ( | long | fromXPower, |
| long | fromID = 0 |
||
| ) | const |
Get the next matrix to use for multi-hop automorphism See Section 3.2.2 in the design document.
◆ getPtxtSpace()
| long helib::PubKey::getPtxtSpace | ( | ) | const |
◆ getSKeyBound()
| double helib::PubKey::getSKeyBound | ( | long | keyID = 0 | ) | const |
The size of the secret key.
◆ hackPtxtSpace()
|
inline |
◆ haveAnyKeySWmatrix()
| bool helib::PubKey::haveAnyKeySWmatrix | ( | const SKHandle & | from | ) | const |
◆ haveKeySWmatrix() [1/2]
| bool helib::PubKey::haveKeySWmatrix | ( | const SKHandle & | from, |
| long | toID = 0 |
||
| ) | const |
◆ haveKeySWmatrix() [2/2]
| bool helib::PubKey::haveKeySWmatrix | ( | long | fromSPower, |
| long | fromXPower, | ||
| long | fromID = 0 , |
||
| long | toID = 0 |
||
| ) | const |
◆ isBootstrappable()
| bool helib::PubKey::isBootstrappable | ( | ) | const |
◆ isCKKS()
| bool helib::PubKey::isCKKS | ( | ) | const |
◆ isReachable()
| bool helib::PubKey::isReachable | ( | long | k, |
| long | keyID = 0 |
||
| ) | const |
Is it possible to re-linearize the automorphism X -> X^k See Section 3.2.2 in the design document (KeySwitchMap)
◆ keyExists()
| bool helib::PubKey::keyExists | ( | long | keyID | ) | const |
◆ keySWlist()
| const std::vector< KeySwitch > & helib::PubKey::keySWlist | ( | ) | const |
◆ operator!=()
| bool helib::PubKey::operator!= | ( | const PubKey & | other | ) | const |
◆ operator==()
| bool helib::PubKey::operator== | ( | const PubKey & | other | ) | const |
◆ reCrypt()
| void helib::PubKey::reCrypt | ( | Ctxt & | ctxt | ) | const |
◆ setKeySwitchMap()
| void helib::PubKey::setKeySwitchMap | ( | long | keyId = 0 | ) |
Compute the reachability graph of key-switching matrices See Section 3.2.2 in the design document (KeySwitchMap)
◆ setKSStrategy()
| void helib::PubKey::setKSStrategy | ( | long | dim, |
| int | val | ||
| ) |
set KS strategy for dimension dim dim == -1 is Frobenius
◆ thinReCrypt()
| void helib::PubKey::thinReCrypt | ( | Ctxt & | ctxt | ) | const |
◆ void ::helib::readPubKeyBinary()
| helib::PubKey::void ::helib::readPubKeyBinary | ( | std::istream & | str, |
| PubKey & | pk | ||
| ) |
◆ void ::helib::writePubKeyBinary()
| helib::PubKey::void ::helib::writePubKeyBinary | ( | std::ostream & | str, |
| const PubKey & | pk | ||
| ) |
Friends And Related Function Documentation
◆ operator<<
|
friend |
◆ operator>>
|
friend |
◆ SecKey
|
friend |
The documentation for this class was generated from the following files:
- /HElib/include/helib/keys.h
- /HElib/src/keys.cpp
- /HElib/src/recryption.cpp


This is plugin for Acorn - a tiny, fast JavaScript parser, written completely in JavaScript.
It was created as an experimental alternative, faster React.js JSX parser.
According to benchmarks, Acorn-JSX is 2x faster than official Esprima-based parser when location tracking is turned on in both (call it “source maps enabled mode”). At the same time, it consumes all the ES6+JSX syntax that can be consumed by Esprima-FB (this is proved by official tests).
UPDATE [14-Apr-2015]: Facebook implementation started deprecation process in favor of Acorn + Acorn-JSX + Babel for parsing and transpiling JSX syntax.
Please note that this tool only parses source code to JSX AST, which is useful for various language tools and services. If you want to transpile your code to regular ES5-compliant JavaScript with source map, check out the babel transpiler which uses acorn-jsx
under the hood.
You can use module directly in order to get Acorn instance with plugin installed:
javascript
var acorn = require('acorn-jsx');
Or you can use inject.js
for injecting plugin into your own version of Acorn like following:
javascript
var acorn = require('acorn-jsx/inject')(require('./custom-acorn'));
Then, use plugins
option whenever you need to support JSX while parsing:
javascript
var ast = acorn.parse(code, {
plugins: { jsx: true }
});
Note that official spec doesn’t support mix of XML namespaces and object-style access in tag names (#27) like in
, so it was deprecated in<EMAIL_ADDRESS>. If you still want to opt-in to support of such constructions, you can pass the following option:
javascript
var ast = acorn.parse(code, {
plugins: {
jsx: { allowNamespacedObjects: true }
}
});
Also, since most apps use pure React transformer, a new option was introduced that allows to prohibit namespaces completely:
javascript
var ast = acorn.parse(code, {
plugins: {
jsx: { allowNamespaces: false }
}
});
Note that by default allowNamespaces
is enabled for spec compliancy.
This plugin is issued under the MIT license.


Coffee at JavaJam
| Just Java |
Regular house blend, decaffeinated coffee, or flavor of the
day. Endless Cup $2.00 |
| Cafe au Lait |
House blended coffee infuse in to a smooth, steamed milk Single $2.00 Double $3.00 |
| Iced Cappucino |
Sweetened espresso blended with icy-cold milk and served in a
chilled glass. Single $4.75 Double $5.75 |


pt - Parser Tools Application
Are you lost ? Do you have trouble understanding this document ? In that case please read the overview provided by the Introduction to Parser Tools. This document is the entrypoint to the whole system the current package is a part of.
This document describes pt, the main application of the module, a parser generator. Its intended audience are people who wish to create a parser for some language of theirs. Should you wish to modify the application instead, please see the section about the application's Internals for the basic references.
It resides in the User Application Layer of Parser Tools.
This sub-command of the application reads the parsing expression grammar stored in the inputfile in the format inputformat, converts it to the resultformat under the direction of the (format-specific) set of options specified by the user and stores the result in the resultfile.
The inputfile has to exist, while the resultfile may be created, overwriting any pre-existing content of the file. Any missing directory in the path to the resultfile will be created as well.
The exact form of the result for, and the set of options supported by the known result-formats, are explained in the upcoming sections of this document, with the list below providing an index mapping between format name and its associated section. In alphabetical order:
A resultformat. See section C Parser.
A resultformat. See section Grammar Container.
A resultformat. See section C Parser Embedded In Tcl.
A input- and resultformat. See section JSON Grammar Exchange.
A resultformat. See section TclOO Parser.
A input- and resultformat. See section PEG Specification Language.
A resultformat. See section Snit Parser.
Of the seven possible results four are parsers outright (c, critcl, oo, and snit), one (container) provides code which can be used in conjunction with a generic parser (also known as a grammar interpreter), and the last two (json and peg) are doing double-duty as input formats, allowing the transformation of grammars for exchange, reformatting, and the like.
The created parsers fall into three categories:
The fastest parsers are created when using the result formats c and critcl. The first returns the raw C code for the parser, while the latter wraps it into a Tcl package using CriTcl.
This makes the latter much easier to use than the former. On the other hand, the former can be adapted to the users' requirements through a multitude of options, allowing for things like usage of the parser outside of a Tcl environment, something the critcl format doesn't support. As such the c format is meant for more advanced users, or users with special needs.
A disadvantage of all the parsers in this section is the need to run them through a C compiler to make them actually executable. This is not something everyone has the necessary tools for. The parsers in the next section are for people under such restrictions.
As the parsers in this section are implemented in Tcl they are quite a bit slower than anything from the previous section. On the other hand this allows them to be used in pure-Tcl environments, or in environments which allow only a limited set of binary packages. In the latter case it will be advantageous to lobby for the inclusion of the C-based runtime support (notes below) into the environment to reduce the impact of Tcl's on the speed of these parsers.
The relevant formats are snit and oo. Both place their result into a Tcl package containing a snit::type, or TclOO class respectively.
Of the supporting runtime, which is the package pt::rde, the user has to know nothing but that it does exist and that the parsers are dependent on it. Knowledge of the API exported by the runtime for the parsers' consumption is not required by the parsers' users.
The last category, grammar interpretation. This means that an interpreter for parsing expression grammars takes the description of the grammar to parse input for, and uses it guide the parsing process. This is the slowest of the available options, as the interpreter has to continually run through the configured grammar, whereas the specialized parsers of the previous sections have the relevant knowledge about the grammar baked into them.
The only places where using interpretation make sense is where the grammar for some input may be changed interactively by the user, as the interpretation allows for quick turnaround after each change, whereas the previous methods require the generation of a whole new parser, which is not as fast. On the other hand, wherever the grammar to use is fixed, the previous methods are much more advantageous as the time to generate the parser is minuscule compared to the time the parser code is in use.
The relevant result format is container. It (quickly) generates grammar descriptions (instead of a full parser) which match the API expected by ParserTools' grammar interpreter. The latter is provided by the package pt::peg::interp.
All the parsers generated by critcl, snit, and oo, and the grammar interpreter share a common API for access to the actual parsing functionality, making them all plug-compatible. It is described in the Parser API specification document.
peg, a language for the specification of parsing expression grammars is meant to be human readable, and writable as well, yet strict enough to allow its processing by machine. Like any computer language. It was defined to make writing the specification of a grammar easy, something the other formats found in the Parser Tools do not lend themselves too.
For either an introduction to or the formal specification of the language, please go and read the PEG Language Tutorial.
When used as a result-format this format supports the following options:
The json format for parsing expression grammars was written as a data exchange format not bound to Tcl. It was defined to allow the exchange of grammars with PackRat/PEG based parser generators for other languages.
For the formal specification of the JSON grammar exchange format, please go and read The JSON Grammar Exchange Format.
When used as a result-format this format supports the following options:
The critcl format is executable code, a parser for the grammar. It is a Tcl package with the actual parser implementation written in C and embedded in Tcl via the critcl package.
This result-format supports the following options:
The c format is executable code, a parser for the grammar. The parser implementation is written in C and can be tweaked to the users' needs through a multitude of options.
The critcl format, for example, is implemented as a canned configuration of these options on top of the generator for c.
This result-format supports the following options:
The snit format is executable code, a parser for the grammar. It is a Tcl package holding a snit::type, i.e. a class, whose instances are parsers for the input grammar.
This result-format supports the following options:
The oo format is executable code, a parser for the grammar. It is a Tcl package holding a TclOO class, whose instances are parsers for the input grammar.
This result-format supports the following options:
The container format is another form of describing parsing expression grammars. While data in this format is executable it does not constitute a parser for the grammar. It always has to be used in conjunction with the package pt::peg::interp, a grammar interpreter.
The format represents grammars by a snit::type, i.e. class, whose instances are API-compatible to the instances of the pt::peg::container package, and which are preloaded with the grammar in question.
This result-format supports the following options:
In this section we are working a complete example, starting with a PEG grammar and ending with running the parser generated from it over some input, following the outline shown in the figure below:
Our grammar, assumed to the stored in the file "calculator.peg" is
PEG calculator (Expression) Digit <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9' ; Sign <- '-' / '+' ; Number <- Sign? Digit+ ; Expression <- Term (AddOp Term)* ; MulOp <- '*' / '/' ; Term <- Factor (MulOp Factor)* ; AddOp <- '+'/'-' ; Factor <- '(' Expression ')' / Number ; END;
From this we create a snit-based parser via
pt generate snit calculator.tcl -class calculator -name calculator peg calculator.peg
which leaves us with the parser package and class written to the file "calculator.tcl". Assuming that this package is then properly installed in a place where Tcl can find it we can now use this class via a script like
package require calculator lassign $argv input set channel [open $input r] set parser [calculator] set ast [$parser parse $channel] $parser destroy close $channel ... now process the returned abstract syntax tree ...
where the abstract syntax tree stored in the variable will look like
set ast {Expression 0 4 {Factor 0 4 {Term 0 2 {Number 0 2 {Digit 0 0} {Digit 1 1} {Digit 2 2} } } {AddOp 3 3} {Term 4 4 {Number 4 4 {Digit 4 4} } } } }
assuming that the input file and channel contained the text
120+5
A more graphical representation of the tree would be
Regardless, at this point it is the user's responsibility to work with the tree to reach whatever goal she desires. I.e. analyze it, transform it, etc. The package pt::ast should be of help here, providing commands to walk such ASTs structures in various ways.
One important thing to note is that the parsers used here return a data structure representing the structure of the input per the grammar underlying the parser. There are no callbacks during the parsing process, i.e. no parsing actions, as most other parsers will have.
Going back to the last snippet of code, the execution of the parser for some input, note how the parser instance follows the specified Parser API.
This section is intended for users of the application which wish to modify or extend it. Users only interested in the generation of parsers can ignore it.
The main functionality of the application is encapsulated in the package pt::pgen. Please read it for more information.
This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category pt of the Tcllib Trackers. Please also report any ideas for enhancements you may have for either package and/or documentation.
When proposing code changes, please provide unified diffs, i.e the output of diff -u.
Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar.
EBNF, LL(k), PEG, TDPL, context-free languages, expression, grammar, matching, parser, parsing expression, parsing expression grammar, push down automaton, recursive descent, state, top-down parsing languages, transducer
Parsing and Grammars
Copyright © 2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>


I am, Mwai yusuf
I am a web-developer and an Entrepreneur,with 1 year experience in conceptualizing and designing website .I work from concept to completion on a wide range of projects,fusing creativity with marketing strategy and design with business.I play Basketball and like watching movies and series....


Why would GMO Internet switch all mining capacity to $BTC from $BCH? Only ~$37,867 for one hour 51% $BCH attack? Does DARI ratio account for block maturation times? Nov fork? What could possibly happen with this $9B testnet? Sure is fun to watch! https://t.co/2P5...
@vin_thetown @monerotrader @WattCrypto @TraceMayer @rogerkver $kmd Komodo can notarize all of these BTC forks to $BTC for the measly fee of 300KMD/yr.
That will solve your 51% dilemma
@Deleted User
Hollowman900029-Aug-18 09:04 PM
KMD on Binance is starting to look like the BTC manipulation(edited)
For a limited time, #Cred will match a $10 investment in @KomodoPlatform with $10 in #KMD.
Get Cred here: https://t.co/rcGf8JLC5X
Limit one transaction per user. Other restrictions may apply.
#Komodo #deal
ALTCOIN TOURNAMENT - FINAL
Congratulations to these 4 projects that made it so far, it has been amazing to see crypto communities so active
Regardless of final result, every coin that made it here deserves recognition!
#PARETO
#TELCOIN
#KOMODO
#ZILLIQA...
Its not to kick a dead horse... but blocknet has broke new ground again!
They did an SPV transaction!
2
sure, they would get lots of benefit from collaboration.
but its funny how they do these catchy lines
"its now possible to do a transaction without the blockchain!"
LOL
2
who does these titles for them!?
Cryptoon30-Aug-18 12:44 PM
@siu - Chainmakers I meant if you were to calculate the value of the S&P500 without it taking into account the FAANG stocks, then you could already see the graph flattening, meaning the bullrun is actually ending
siu - Chainmakers30-Aug-18 12:44 PM
ahhh okok
Cryptoon30-Aug-18 12:44 PM
FAANG is Faceboom amazon apple netflix google
siu - Chainmakers30-Aug-18 12:44 PM
understood
Cryptoon30-Aug-18 12:44 PM
but assume you knew that
facebook rather
siu - Chainmakers30-Aug-18 12:44 PM
yeah yeah... sorry.
faceboom sounds better lol
jorian30-Aug-18 12:45 PM
boom, in your face
Cryptoon30-Aug-18 12:45 PM
going boom when it crashes indeed
I tried to plot SPX-AAPL-GOOGL-... in tradingview but then realized it just substracted the absolute values of those stocks, and the SPX itself is a weighted index
So not really sure how we can see and track in realtime for ourselves
but that would be similar to removing BTC from the overall crypto index
Cryptoon30-Aug-18 12:48 PM
yeah something like that
except not really, because when btc goes up alts go up in usd as well. While this is not necessarily the case for FAANG and the rest of the S&P
Anyway, the article said it was a good indicator of predicting the end of the bull as FAANG skews the results of SPX too much
siu - Chainmakers30-Aug-18 12:56 PM
weird part of this is that the DOW is still lagging and SPX and NASDAQ are already in ATH
normally its the contrary
stealth30-Aug-18 01:27 PM
When is the Kmd rebrand and what will that actually mean?
Bittersweet30-Aug-18 02:42 PM
Hahahhahaha
Cryptoon30-Aug-18 02:42 PM
@siu - Chainmakers I think it has to do with cheap money being available and companies in the s&p that are generally more prone to overinvesting by PE firms?


These unit tests should be run through a web server, as some of the test runner requires AJAX to load external data files. If you have trouble in running these tests on your local machine, online ones can be viewed in our website.
Note: some tests may require a period of time to execute.


class: center, middle
.title[Gibbs Seawater - Rust] .subtitle[GSW Toolbox implemented in Rust for efficiency and robustness]
.author[Guilherme Castelão] .institution[Scripps Institution of Oceanography - UCSD]
.author[Luiz Irber] .institution[University of California Davis]
.date[April 4, 2022 - [SEA's ISS](https://sea.ucar.edu)] slides: https://github.com/castelao/GSW-rs
.note[Created with [{Liminal}](https://github.com/jonathanlilly/liminal) using [{Remark.js}](http://remarkjs.com/) + [{Markdown}](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) + [{KaTeX}](https://katex.org)] --- name: whatisgsw class: left #Gibbs Seawater Toolbox "TEOS-10 is based on a Gibbs function formulation from which all **thermodynamic properties of seawater** (density, enthalpy, entropy sound speed, etc.) can be derived in a thermodynamically **consistent** manner. TEOS-10 was adopted by the Intergovernmental Oceanographic Commission (**IOC**) at its 25th Assembly in June 2009 to replace EOS-80 as the official description of seawater and ice properties in marine science." [TEOS-10](http://www.teos-10.org) A notable use is on estimating density of the seawater from sensors measuring pressure, temperature, and conductivity. -- Current state: - Toolbox available on MatLab, FORTRAN, C/C++, JS - Wrapper around C library: Haskell, Julia, Python, R, ... - Scientific development focused on MatLab. - The C library almost reproduce MatLab. --- name: wishlist class: left ##Our wishlist for Scientific Computing Motivation: Enable more onboard decision making, such as using Machine Learning, in Argo floats and Spray underwater gliders. -- - **Embedded:** Use within firmware for microcontrollers; -- - **Package manager:** Reuse = speed coding; Take advantage of others expertise; -- - **Interoperable:** Work with existing systems; Partial integration avoids complete rewrites; -- - **Robustness:** Bugs on remote autonomous systems can be a catastrophic failure. A plus for robust concurrent processing; -- - **Testing/Validation:** Integrated testing system; -- - **Readable:** Code for human and leave for compiler to optimize it; --
--- name: rustintro class: left # Rust? System programming language (same realm as C) - High-level ergonomics and low-level control - Memory safety enforced by the compiler - Explicit error handling with the `Result` type Initially develop at Mozilla, increased adoption across industry - Integration within Firefox (large C++ codebase) - Iterative, not total rewrite - Minimize data races and other concurrency bugs Official book: https://doc.rust-lang.org/book/ --- name: tree class: left #Package structure .left-column[ ```shell $ tree -L 2 . ├── Cargo.toml ├── README.md ├── assets │ └── gswteos-10.h ├── benches │ └── volume.rs ├── build.rs ├── cbindgen.toml ├── convert_refdata │ ├── Cargo.toml │ ├── data/ │ ├── src/ │ └── tests/ ├── examples │ └── usage-from-c/ ``` ] .right-column[ ```shell . ├── src │ ├── conversions.rs │ ├── earth.rs │ ├── error.rs │ ├── ffi.rs │ ├── gsw_internal_const.rs │ ├── gsw_internal_funcs.rs │ ├── gsw_sp_coefficients.rs │ ├── gsw_specvol_coefficients.rs │ ├── lib.rs │ ├── practical_salinity.rs │ └── volume.rs ├── tests │ ├── data/ │ ├── earth.rs │ └── volume.rs └── utils ├── gen_stubs.py └── gsw-py-patch ``` ] --- name: crates class: left #Distributing - [crates.io](https://crates.io/crates/gsw) ```shell $ cargo search gsw gsw = "0.0.10" # TEOS-10 Gibbs Seawater Oceanographic Toolbox in Rust ``` -- How to use other crates? ```shell= $ cat Cargo.toml [package] name = "gsw" ... [dependencies] libm = "0.2.1" libc = { version = "0.2", optional = true } thiserror = { version = "1.0.24", optional = true } ... ``` -- ```shell $ grep libm src/conversions.rs | head -n 1 src/conversions.rs: let x = libm::sin(lat * DEG2RAD); ``` --- name: cargo_doc class: left #cargo doc - [docs.rs/gsw](https://docs.rs/gsw/0.0.10/gsw/volume/fn.specvol.html) As written in src/volume.rs, near the function implementation. ````shell= /// Specific volume of sea water (75-term polynomial approximation) /// /// Calculates specific volume from Absolute Salinity, Conservative /// Temperature and pressure, using the computationally-efficient /// polynomial expression for specific volume (Roquet et al., 2014). /// /// # Arguments /// /// * `sa`: Absolute Salinity \[ g kg-1 \] /// * `ct`: Conservative Temperature (ITS-90) \[ deg C \] /// * `p`: sea pressure \[ dbar \] (i.e. absolute pressure - 10.1325 dbar) /// /// # Returns /// /// * `specvol`: specific volume \[m3 kg-1\] /// /// ... /// pub fn specvol(sa: f64, ct: f64, p: f64) -> Result
{ ... } ```` --- name: doctest class: left #cargo test - Doctest ````shell= /// Specific volume of sea water (75-term polynomial approximation) /// /// Calculates specific volume from Absolute Salinity, Conservative /// Temperature and pressure, using the computationally-efficient /// polynomial expression for specific volume (Roquet et al., 2014). /// ... /// /// # Example: /// ``` /// use gsw::volume::specvol; /// let v = specvol(32.0, 10.0, 100.0).unwrap(); /// assert!((v - 0.0009756515980668401).abs() <= f64::EPSILON); /// ``` /// pub fn specvol(sa: f64, ct: f64, p: f64) -> Result
{ ... } ```` --- name: unittest class: left #cargo test - Unit [{src/volume.rs}](https://github.com/castelao/GSW-rs/blob/7b5c6b5ab2b61ed86585fffd69f6c780e8894706/src/volume.rs#L96) ```shell= pub fn specvol(sa: f64, ct: f64, p: f64) -> Result
{...} #[cfg(test)] mod test_specvol { use super::specvol; #[test] // NaN input results in NaN output. // Other libraries using GSW-rs might rely on this // behavior to propagate and handle invalid elements. fn nan() { let v = specvol(f64::NAN, 1.0, 1.0); assert!(v.unwrap().is_nan()); } #[test] // Test value from Roquet 2015 Appendix C.3, rounded to 9.732819628e-04 fn roquet2015() { assert!((specvol(30., 10., 1000.0).unwrap() - 9.732819628e-04).abs() <= 5e-14); } ... } ``` --- name: validationtest class: left #cargo test - Validation .left-column[ Matlab has a testing dataset that we use as our reference. But that dataset is a matlab binary. We created an auxiliary crate ([convert_refdata](https://github.com/castelao/GSW-rs/tree/main/convert_refdata)) to convert the matlab dataset into a serialized binary. With a readeable dataset (heapless) we can write tests ([tests/volume.rs](https://github.com/castelao/GSW-rs/blob/main/tests/volume.rs)) to validate against the reference values. ] .right-column[ ```shell $ tree -L 2 . ├── Cargo.toml ├── README.md ├── build.rs ├── convert_refdata │ ├── Cargo.toml │ ├── data/ │ ├── src/ │ └── tests/ ├── tests │ ├── data/ │ ├── earth.rs │ └── volume.rs ... ``` ] --- name: cargotest class:left # Running tests ```shell $ cargo test cargo test Finished test [unoptimized + debuginfo] target(s) in 0.14s Running unittests (target/debug/deps/gsw-fe1efe8952eba1b5) running 53 tests ... test result: ok. 53 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Running tests/earth.rs (target/debug/deps/earth-445971b965eed566) running 2 tests ... test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Running tests/volume.rs (target/debug/deps/volume-26d3c06ea78d8e71) running 14 tests ... test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s Doc-tests gsw running 27 tests ... test result: ok. 27 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.47s ``` Integrated with [Github Actions](https://github.com/castelao/GSW-rs/actions/runs/2075234547) to monitor for several platforms. --- name: FFI-intro class: left #C FFI Generate C-compatible libraries - static or dynamic linking - `pkg-config` configuration Using [{cargo-c}](https://github.com/lu-zero/cargo-c) for convenience --- name: FFI-example class: left #C FFI [{src/ffi.rs}](https://github.com/castelao/GSW-rs/blob/7b5c6b5ab2b61ed86585fffd69f6c780e8894706/src/ffi.rs) ```rust pub const GSW_INVALID_VALUE: f64 = 9e15; pub const GSW_ERROR_LIMIT: f64 = 1e10; #[no_mangle] pub unsafe extern "C" fn gsw_specvol(sa: f64, ct: f64, p: f64) -> f64 { crate::volume::specvol(sa, ct, p).unwrap_or(GSW_INVALID_VALUE) } ``` [{assets/gswteos-10.rs}](https://github.com/castelao/GSW-rs/blob/7b5c6b5ab2b61ed86585fffd69f6c780e8894706/assets/gswteos-10.h) ```c /* GSW TEOS-10 V3.05 definitions and prototypes. */ #ifndef GSWTEOS_10_H #define GSWTEOS_10_H #define GSW_INVALID_VALUE 9e15 #define GSW_ERROR_LIMIT 1e10 #ifdef __cplusplus extern "C" { #endif // __cplusplus double gsw_specvol(double sa, double ct, double p); #ifdef __cplusplus } // extern "C" #endif // __cplusplus #endif /* GSWTEOS_10_H */ ``` --- name: other_languages class: left #Using in GSW-Python **Goal**: Run the `GSW-Python` test suite in CI Only change: [Patch `setup.py`](https://github.com/castelao/GSW-rs/blob/7b5c6b5ab2b61ed86585fffd69f6c780e8894706/utils/gsw-py-patch) to build with Rust instead - Same header file - Linking with `ufunc` optimizations in GSW-Python (for `numpy`) - Current status: 84 failed, 399 passed - (mostly failures from functions not implemented yet) --- name: bench_intro class: left #Benchmarking - Using [criterion](https://bheisler.github.io/criterion.rs/book/index.html) - Also tracking in CI for regressions [`{benches/volume.rs}`](https://github.com/castelao/GSW-rs/blob/7b5c6b5ab2b61ed86585fffd69f6c780e8894706/benches/volume.rs) ```rust use criterion::{black_box, criterion_group, criterion_main, Criterion}; use gsw::{conversions, practical_salinity, volume}; fn volume(c: &mut Criterion) { c.bench_function("specvol", |b| { b.iter(|| volume::specvol(black_box(10.0), black_box(10.0), black_box(10.0)).unwrap()) }); } criterion_group!(benches, volume); criterion_main!(benches); ``` ```shell= $ cargo bench -- specvol specvol time: [19.385 ns 19.402 ns 19.419 ns] Found 1 outliers among 100 measurements (1.00%) 1 (1.00%) high severe ``` --- name: bench_c class: left #Benchmarking In parallel: implementing benchmarks for `GSW-C` using https://github.com/google/benchmark - to check if they are in the same ballpark - focus on correctness at the moment, not performance ```c #include
#include "gswteos-10.h" static void BM_specvol(benchmark::State& state) { for (auto _ : state) { gsw_specvol(10.0, 10.0, 10.0); } } BENCHMARK(BM_specvol); ``` ```shell= $ ./gsw_bench Running ./gsw_bench ------------------------------------------------------------------------------------- Benchmark Time CPU Iterations ------------------------------------------------------------------------------------- BM_specvol 18.3 ns 18.3 ns 38028678 ``` --- name: bench_compare class: left #Benchmarking Top 8 - Rust faster than C: change | time_c | time_rs | units | function ------ | ------ | ------- | ----- | -------- 0.29 | 46.49 | 13.68 | ns/ns | c_from_sp 0.48 | 47.01 | 22.54 | ns/ns | enthalpy_second_derivatives 0.65 | 17.11 | 11.09 | ns/ns | z_from_p 0.67 | 47.65 | 31.82 | ns/ns | specvol_first_derivatives 0.84 | 12.13 | 10.22 | ns/ns | sigma0 0.84 | 46.64 | 39.28 | ns/ns | rho_first_derivatives 0.89 | 104.21 | 92.65 | ns/ns | rho_second_derivatives 0.92 | 41.16 | 37.72 | ns/ns | specvol_second_derivatives_wrt_enthalpy --- name: bench_compare class: left #Benchmarking Top 8 - C faster than Rust: change | time_c | time_rs | units | function ------ | ------ | ------- | ----- | -------- 4.31 | 42.04 | 181.29 | ns/ns | sa_from_rho 2.95 | 41.12 | 121.48 | ns/ns | specvol_second_derivatives 2.39 | 39.77 | 94.91 | ns/ns | specvol_alpha_beta 2.31 | 41.81 | 96.62 | ns/ns | rho_alpha_beta 1.65 | 26.92 | 44.30 | ns/ns | enthalpy_diff 1.53 | 1.77 | 2.70 | ns/ns | specvol_sso_0 1.38 | 60.48 | 83.74 | ns/ns | thermobaric 1.22 | 55.09 | 67.28 | ns/ns | specvol_first_derivatives_wrt_enthalpy --- name: embedded class: left #Embedded - `no_std` - Run on "Bare Metal" embedded systems, such as microcontrollers. - Microcontrollers used for real-time operational systems and low energy consumption. - With `#![no_std]` the crate links to the core-crate instead of the std-crate, thus it is platform-agnostic, lacking APIs for anything that involves platform integration. - Use of libm for math operations and heap not available by default. --- name: features class: left #Features Choose your flavor on compilation time. E.x.: to include C-API: ```shell $ cargo build --features capi ``` -- Also allow strategy decisions: - GSW-Matlab ```matlab % This line ensures that SA is non-negative. SA(SA < 0) = 0; ``` -- - GSW-C ```shell #define GSW_INVALID_VALUE 9e15 ``` ```shell /* This line ensures that SP is non-negative. */ if (sp < 0.0) { sp = GSW_INVALID_VALUE; } ``` --- name: compat class: left #Features - compat To reproduce Matlab: ```shell $ cargo build --features compat ``` ```shell pub fn specvol(sa: f64, ct: f64, p: f64) -> Result
{ let sa: f64 = if sa < 0.0 { if cfg!(feature = "compat") { 0.0 } else if cfg!(feature = "invalidasnan") { return Ok(f64::NAN); } else { return Err(Error::NegativeSalinity); } } else { sa }; ... } ``` --- name: humanreadeable class: left #Write code for humans Explicit definition without compromising performance and matching reference notation. For instance, `const`. ```shell /// SSO: Standard Ocean Reference Salinity [ g/kg ]. pub const GSW_SSO: f64 = 35.16504; /// uPS: unit conversion factor for salinities (Millero et al., 2008) [g/kg] /// Reference Salinity SR is uPS times Practical Salinity SP. pub const GSW_UPS: f64 = GSW_SSO / 35.0; /// sfac = 1/(40*gsw_ups) ~ 0.024882667558461472 pub const GSW_SFAC: f64 = if cfg!(feature = "compat") { 0.0248826675584615 } else { 1.0 / (40.0 * GSW_UPS) }; ``` Write code for humans and leave the optimization for the compiler. - Easier to compare with papers; - Easier to maintain and update scientific advances; --- name: whatisliminal class: left #Other applications ##[BUFR](https://github.com/castelao/bufr) An Open Source pure Rust library with a BUFR-dump (WIP). ##Satellite Communications Iridium communications at Scripps Institution of Oceanography for Solo-II (Argo) and Spray (underwater gliders) have been running with a custom system written in Rust since 2017. - Fast response - Light process - Multi-Thread ##[sourmash](https://github.com/sourmash-bio/sourmash) Quickly search, compare, and analyze genomic and metagenomic data sets. --- name: community class: left #Community and references GSW-rs: where to learn more and how to contribute? - https://github.com/castelao/GSW-rs How to learn more about Rust - [The official book](https://doc.rust-lang.org/book/) (intro) - [Rust for Rustaceans](https://nostarch.com/rust-rustaceans) (intermediate) Link for community resource - https://gitter.im/rustopensci/community --- name: closing class: middle, center #That's All! Have fun! [{GSW-rs}](https://github.com/castelao/GSW-rs)


Receber ao Aprender
There is a mismatch between the kind of learning prescribed by these enlightened experts and what many employers perceive to be their shortterm needs. As a result of this mismatch, the school-to-work transition has become an increasingly difficult phase, and many employers now take their own direct training measures. These tend to be heavy on applied skills— and light on metacognitive ones.8 We might reject the narrow focus of much corporate education, but it’s partly our own fault as a society. We have filled the world with such unstable technology and clunky systems; these need to be looked after by people with limited horizons who do what they are told and don’t ask too many questions. Call centers—to name just one among a thousand support functions in our technological culture—don’t recruit people with metacognitive skills who look at the bigger picture. They need drones. The widening gap between what formal education provides and what business thinks it needs has stimulated the emergence of learning as a market. This market also benefits from the fact that governments are looking for ways to educate more people to ever higher levels—but without spending more money. They therefore encourage private-sector investment in what is known in new-economy-speak as the ‘‘education space.’’ On paper, education, like health and care, is a vast market. Spending on learning by all organizations in the United States amounts to some seven hundred fifty billion dollars, or 7 percent of GDP. That’s half what the country spends on health, but still a tidy sum. In France, Europe’s highest spender on education, the number is closer to 25 percent.9 Spending by all organizations worldwide is estimated to be two thousand billion dollars.
 The so-called consumer market for learning is also huge. Two hundred million North Americans take some kind of continuing education course each year, and nine out of ten adults aged fifty and over are actively seeking learning opportunities at any given time. These are remarkable numbers when compared to annual sales of tickets to sporting events in the United States, which total just ten million.10 The approach business has taken to the learning market has been to segment it. An influential paper by Jerry Wind and David Reibstein at Wharton Business School11 divided education into discrete markets: child care and early education, K–12 or secondary education, postsecondary education, corporate training, and the consumer market. Another popular matrix divides learning into content (information technology, business skills, lifestyle, academic, customized), services (content distribution, consulting, implementation, e-commerce, community portals), and technology (learning management tools, digital portfolios, content creation tools, delivery platforms, collaboration tools). There was a time when market analyses of this kind, combined with the huge financial numbers bandied around, greatly excited investors. There was talk of an ‘‘emerging electronic university,’’ a ninety-billion-dollar ‘‘unified global marketplace for ideas,’’ ‘‘Web-based knowledge exchanges,’’ and so on.12 One start-up, UNext, proclaimed that ‘‘the vast imbalance between the supply and demand for quality education provides an enormous, untapped global market. Countries, companies, and individuals that don’t invest in knowledge are destined to fall behind.’’13 This bewitching vision enticed investors to pour billions of dollars of venture capital onto the e-learning bandwagon during the last years of the dot-com boom. A lot of this money went to so-called pure-play learning start-ups following a ‘‘land grab’’ or first-mover-advantage strategy. These start-ups thought it vital to own or control access to as much content as possible. ‘‘We are continually combing the Net to feed our growing database of 37,000 online courses,’’ boasted the website of HungryMinds (now defunct).14 Other start-ups proclaimed themselves to be ‘‘learning portals’’ through which all conceivable types of knowledge and learning would be accessed and exchanged. Blue-chip players were not immune from the frenzy. Columbia University invested tens of millions of dollars in Fathom, a learning portal, and recruited a consortium of fellow blue-chip academic institutions to join them; these included the London School of Economics, the New York Public Library, and the Universities of Chicago and Michigan. Industry gossip at the time had it that Fathom spent seventy-five million dollars building its portal website before the service was even launched.15 Most e-learning start-ups were inspired by a simple idea: They would make money by ‘‘dis-intermediating’’ disposable steps in the production process of learning—namely, people. They compared the people costs of education (which are up to 80 percent) with those in manufacturing (20– 40 percent) and services (around 60 percent)—and concluded that it must surely be possible to produce learning in a more profitable way by automating the process.16 The e-learning investment bubble burst when, in 2001, MIT announced that it would put all its content online—and access would be free. The university further committed one hundred million dollars to a project called OpenCourseWare in which public-domain websites would be built for all of its two thousand courses. Lecture notes, problem sets, syllabuses, simulations, even videos of lectures would be put online. As Charles Vest, MIT’s president, said at the time, ‘‘our central value is people, and the human experience of faculty working with students.’’17 The private sector was not uniquely to blame for a skewed vision of learning that prioritized prerecorded content over people. Visions of a vast, semiautomated learning machine still bewitch many politicians— not just entrepreneurs—and the world is replete with government-backed plans to ‘‘penetrate the schools’’ with new technology. A senior Dutch minister once told me confidently that with the Internet, ‘‘we can beam lectures from the best 10 percent of teachers to classrooms and do without the other 90 percent.’’ The minister’s dream reminded me of a joke I once heard in Hungary about the factory of the future. It will have only two employees, a man and a dog: The man will be there to feed the dog; the dog will be there to stop the man from touching the equipment. Evangelists for computers in schools are perplexed that the computer revolution has moved so slowly. They observe that some areas of human activity—medicine, transportation, entertainment—have changed beyond recognition in the wake of modern science and technology. One institution that most definitely has not is school. MIT’s Seymour Papert has a vision of a truly modern school in which the computer is as much part of all learning as the pencil and the book have been in the past. In Papert’s vision, computer-based media would enable children to master areas of knowledge that would otherwise remain inaccessibly difficult. Self-directed work would allow an unprecedented diversity of learning styles and opportunity for students to learn to take charge of their own learning. According to Papert, American schools have acquired more than three million computers, yet resistance to progress persists.18


There are two ways to add a new Holding Register to the configuration:
1. Right-click on the Holding Registers group in the System Configuration Tree and select Add Holding Register.
2. While the Holding Registers group is selected, click the Add One button in the upper-right and corner.
Bulk Adding New Holding Registers
There are two ways to add a new Holding Register to the configuration:
1. Right-click on the Holding Registers group in the System Configuration Tree and select Bulk Add.
2. While the Holding Registers group is selected, click the Add One button in the upper-right and corner.
Confirm the options in the dialog box that appears.
Configuring Holding Registers
Name: The VeriStand channel name associated with the Holding Register.
Address The address of the Holding Register, zero-indexed. If your slave device lists the Holding Register addresses as between 40001-49999, you will need to subtract 40001 from the value given. Changing the selector next to the Address indicator will toggle input between Decimal and Hexidecimal representations.
Read Select this option to get the value of the Holding Register from the Modbus slave to the target.
Write Select this option to set the value of the Holding Register on the Modbus slave with this channel's value.
DataTypeThe type of data represented in the given register or registers. If the data is more than 16 bits, the channel will read multiple registers and interpret them as the given datatype.
Registers This displays the number of registers a given datatype uses.
Description This is for documentation purposes only, and does not affect the functionality.


--- layout: default lang: en title: Development of Open Procurement toolkit menu_title: Home permalink: /en/ ---
OpenProcurement is an open source e-procurement toolkit.
OpenProcurement's goal is to provide the tools to design and build a procurement process that is transparent and competative. The toolkit builds accessible processes that leverage auctions to drive savings and are backed by strong data collection and reporting. It is designed to be automated and scalable. Accessibility, transparency of tendering process, electronic documents, detailed reporting - these are only a few benefits of using this e-Procurement software.
OpenProcurement’s initial application was with ProZorro, a procurement system implemented to support multiple national government agencies in Ukraine. OpenProcurement is flexible enough to handle all shapes and sizes of government and private sector procurements.
The basic toolkit, which covers storing data and reverse auctions, is free. The toolkit's Data Standard was developed on the basis of Open Contracting 1.0RC. These data standards were extended to ensure practical implementation of the procurement process in the Prozorro system.
The technical specifications of OpenProcurement are intended to provide a functional solution that will be flexible enough to work with different standards and varied applications. The toolkit was developed with Python, Pyramid, Angular and other powerful open source web technologies to ensure reliable functionality and secure workflow.
OpenProcurement consists of a Central database (CDB) and an API via which specialized eMalls can interact with CDB. eMalls are web platforms that implement e-Procurement system features and provide access for procuring entities, suppliers and regular visitors. eMalls interact with the CDB via OpenProcurement API and provide suppliers with temporary credentials to access the Auction module for participation in the auction.
Once a procurement is announced and bid proposals are registered, users get access to the 3-round auction. Reverse auctions enable competitive bidding environment, while the 3-round design ensures auctions are not overly long to discourage participation.
Prozorro is an application of the OpenProcurement toolkit to design and implement a scalable, dynamic software system for electronic public procurement. Prozorro provides a platform for transparent and efficient spending of public funds and aims to prevent corruption through public oversight and enhanced competition.
Prozorro coordinates the work of Open Procurement toolkit and local eMalls. Six e-Malls are already providing access to the system: Newtend, PublicBid, NetCast, Prom.ua, e-tender.biz, and smarttender.biz. What is more important, the project is open, so any eMall can join if it offers the necessary functionality.
Prozorro also provides cross-access to the system. Users can see all procurements via their eMalls and suppliers can register their bid proposals to any procurement regardless of where the proposal was first announced. This approach creates real competition among suppliers that will lead to savings, as well as keeping the market of eMalls competitive.
The procuring entities that use Prozorro include the Ministry of Infrastructure, Ministry of Defence, Ministry of Justice, Ministry of Economy, State Management of Affairs, Ministry of Ecology, and many others. We have received positive feedback from our users, namely:
Memorandum of initiative people and companies interested in building a transparent and effective system of public procurement in Ukraine
Projects with components related to Open Procurement system (presentation):


{% extends "content_template.html" %} {% from "components/page-header.html" import page_header %} {# Used by the content_template.html layout, prefixes the "navigation" accessible name #} {% set navigation_label_prefix = 'Pricing information' %} {% block per_page_title %} Billing details {% endblock %} {% block content_column_content %} {{ page_header('Billing details') }}
Sign in to see our:
You can use this information to add the Cabinet Office as a supplier. Your organisation may need to do this before you can raise a purchase order.
{% endblock %}


A new "[DocumentType]" has been uploaded
into CATS for action.
Correspondent’s Name:
[CorrespondentName]
Subject:
[Subject]
CATS ID:
[CATSID]
Lead Office:
[Lead Offices]
Copied Offices:
[Copied Office]
Due for Signature By:
[Due for Signature By]
Please navigate to the following URL in your browser to
locate the document:
[siteUrl]


| Endpoint | Method | Content type | Description | Request body | Response body |
|---|---|---|---|---|---|
| /currency | GET | application/json | List available currencies with conversion rates |
Available currencies in json format.
Example: { "fty":{ "fty":1, "xdt":2.5, "cdt":0.2 }, "xdt":{ "fty":0.4, "xdt":1, "cdt":1 }, "cdt":{ "fty":5, "xdt":1, "cdt":1 } } |
|
| /wallets | GET | application/json | Get all wallets |
Wallets in json format.
Example: [ { "id":"test2", "address":"ad0234829205b9033196ba818f7a872b", "balance":2500.0, "currency":"xdt", "tags":[] }, { "id":"main", "address":"fad58de7366495db4650cfefac2fcd61", "balance":97500.0, "currency":"fty", "tags":[] } ] |
|
| /wallets | POST | application/json | Create a wallet |
Wallet details as id, currency and tags (as a list of strings):
{ "id":"test2", "currency":"cdt", "tags":[] } |
Created wallet information:
{ "id":"test22", "address":"4d42bf9c18cb04139f918ff0ae68f8a0", "balance":0.0, "currency":"xdt", "tags":[] } |
| /wallets/:id | GET | application/json | Get wallet details |
Wallet details of given id:
GET /wallets/test2 { "id":"test2", "address":"4d42bf9c18cb04139f918ff0ae68f8a0", "balance":100.0, "currency":"xdt", "tags":[] } |
|
| /wallets/:id | DELETE | Delete a wallet | |||
| /transfer | POST | application/json | Transfer funds between wallets |
Sender and receiver addresses and the amount of funds to be transferred (in sender currency).
Conversions are done automatically according to the conversion rates. { "sender":"fad58de7366495db4650cfefac2fcd61", "receiver":"ad0234829205b9033196ba818f7a872b", "amount":200 } |
Handling failure
For all endpoints, in case of failed requests (e.g. 404, 400), a json payload is returned with the status code and the error message:For example, creating a wallet with the same id of an existing wallet:
{ "status": 400, "message": "a wallet with the same of \'test22\' already exists" }


Home
about
Portfolio
Contact
Portfolio
view project
view project
view project
view project
view project
view project
view project
view project
view project
Contact Info
Contact Form
send


A Concepts Map Created Using Dimensions Data
Total concepts: {{nodes|length}}
Original query: {{query}}
Created on: {{timestamp}}


Knockout Crud Examples
1) Directly edit the Observable Array
| index |
_id |
Task |
Completed |
isSelected |
|
|
|
|
|
2) Editing an object as a protected observable
Editing
| index |
_id |
Task |
Completed |
isSelected |
|
|
|
|
|
3) Adding a new object to an Observable Array with cancellation option
Editing
Add
| index |
_id |
Task |
Completed |
isSelected |
|
|
|
|
|
4) Adding a new object to an Observable Array with cancellation option using Knockout Components


{% extends 'webapp/base.html' %} {% block mainbody %}
Welcome to the swapi, the Star Wars API! This documentation should help you familiarise yourself with the resources available and how to consume them with HTTP requests. If you're after a native helper library then I suggest you scroll down and check out what's available. Read through the getting started section before you dive in. Most of your problems should be solved just by reading through it.
Let's make our first API request to the Star Wars API!
Open up a terminal and use curl or httpie to make an API request for a resource. In the example below, we're trying to get the first planet, Tatooine:
http swapi.py4e.com/api/planets/1/
We'll use httpie for our examples as it displays responses nicely and gives us a whole lot more useful information. If you don't want to download httpie, just use the curl command instead.
Here is the response we get:
HTTP/1.0 200 OK
Content-Type: application/json
{
"climate": "Arid",
"diameter": "10465",
"gravity": "1 standard",
"name": "Tatooine",
"orbital_period": "304",
"population": "200000",
"residents": [
"https://swapi.py4e.com/api/persons/1/",
"https://swapi.py4e.com/api/persons/2/",
...
],
"rotation_period": "23",
"surface_water": "1",
"terrain": "Dessert",
"url": "https://swapi.py4e.com/api/planets/1/"
}
If your response looks slightly different don't panic. This is probably because more data has been added to swapi since we made this documentation.
The Base URL is the root URL for all of the API, if you ever make a request to swapi and you get back a 404 NOT FOUND response then check the Base URL first.
The Base URL for swapi is:
https://swapi.py4e.com/api/
The documentation below assumes you are prepending the Base URL to the endpoints in order to make requests.
Swapi has rate limiting to prevent malicious abuse (as if anyone would abuse Star Wars data!) and to make sure our service can handle a potentially large amount of traffic. Rate limiting is done via IP address and is currently limited to 10,000 API request per day. This is enough to request all the data on the website at least ten times over. There should be no reason for hitting the rate limit.
Swapi is a completely open API. No authentication is required to query and get data. This also means that we've limited what you can do to just GET-ing the data. If you find a mistake in the data, then tweet the author or email him.
All resources support JSON Schema. Making a
request to /api/<resource>/schema
will give you the details of
that resource. This will allow you to programmatically inspect the attributes of
that resource and their types.
All resources support a search
parameter that filters the set of
resources returned. This allows you to make queries like:
https://swapi.py4e.com/api/persons/?search=r2
All searches will use case-insensitive partial matches on the set of search fields. To see the set of search fields for each resource, check out the individual resource documentation. For more information on advanced search terms see here.
SWAPI provides two encodings for you to render the data with:
JSON is the standard data format provided by SWAPI by default.


{{< layout}} {{$pageTitle}}Photo with a code{{/pageTitle}} {{$propositionHeader}}{{/propositionHeader}} {{$header}}
At a photo booth or shop, choose to get a code with your photo.
It's simple and easy to use. In the online passport application:
The photo code is a new service and may not be available yet from photo booths or shops in your area.


Off-Topic
I have a question for my gui i am making
(5)
Can't find where to buy :/
(13)
Hexus 24hrs
(3)
Purchased hexus a week ago
(11)
Can yall exploit this game and kill ppl
(4)
FE MM2 Scripts?
(10)
Another Math problem
(8)
My new gui i made tell me if its good
(9)
Hexus patched
(10)
Something funny continued from my fanfiction req post
(3)
Cant join hexus discord
(4)
Did the discord get terminated?
(4)
Hexus makes my roblox laggy
(11)
Dear Hexus Buyers
(4)
I cant delete posts
(2)
Download
(6)
Is acttuaaaal hexus autoupdating?
(3)
When youve gotta use internet explorer to download hexus
(5)
[REQ] Customality x Charlie theme?
(7)
What is your favorite game on Roblox to exploit?
(
2
)
(26)
Can't run loadstring
(2)
Why are all the discords getting deleted?
(3)
Yes Hexus Got deleted
(3)
Can Yall Fix This Pls
(2)
Love for custom
(2)
Snip to be forgotten
(11)
Server deleted, join the waiting lobby
(4)
Gonna be protosmasher so I can keep switching between hexus and proto
(7)
Buy HEXUS
(4)
What happened to the discord? (Please read)
(4)
← previous page
next page →


The Florida Gators
The Gators are one of the most sauced up teams you can find. They are a member of the SEC, arguably the most competitive conference of all college football. Their bright colors of orange and blue help them to stand out in "The Swamp" as they beat their competitors. Looking nice always helps with that. They are located in Ganesvill florida in the hot humid weather. They get to play in the swamp where there are upwards of 30,000 fans who come to watch. There is an esencial need for them to be stiring the pot with the ice for that reason. Even the big dogs in the trenches have some swagger.


Documentation
Evaluate BODY for each instance of CLASS where SLOT has the
specified value. INSTANCE-VAR will be bound successively to each
instance. See the documentation of RUCKSACK-MAP-SLOT for more
details.
Source
(defmacro rucksack-do-slot ((instance-var class slot
&rest args
&key (rucksack '*rucksack*)
equal min max include-min include-max
order include-subclasses)
&body body)
"Evaluate BODY for each instance of CLASS where SLOT has the
specified value. INSTANCE-VAR will be bound successively to each
instance. See the documentation of RUCKSACK-MAP-SLOT for more
details."
(declare (ignorable equal min max include-min include-max order
include-subclasses))
(check-type instance-var symbol)
`(rucksack-map-slot ,rucksack ,class ,slot
(lambda (,instance-var) ,@body)
,@(sans args ':rucksack)))
Source Context


We have received a new request to our housing service.
Name:{{ hosing.name}} {{ housing.last_name}}
Country:{{ housing.country }}
University:{{ housing.university }}
Email:{{ housing.email }}
You can check this record and all records in ISE Page, only click the next link.
GO TO HOUSING RECORDS


Welcome! Here are my favorite places!
My favorite places are listed below by type (food, drink, vacation spots)
Places to eat!
- The Slanted Door
- State Bird Provisions
- Bluestem
Places to drink!
- Smuggler's Cover
- Clover Club
- The Kill Devil
Places to visit!
- San Francisco
- Denver
- Portland
Thank you for reading my list! Now let's explore!
To read my list of favorite things, click here!


filter rectangles
connected rectangles
fan in
fan out
filter rectangles
Select All
Clear All
Get Filtered Rectangles


WHO WE ARE
Established in 1953, the Pasadena Community Foundation is a tax-exempt public charity created by and for the people of Pasadena. We work with individuals, families, and organizations to establish philanthropic funds, create and build endowment funds, and distribute charitable gifts to nonprofit organizations in Pasadena and across the country. In addition to donor-directed grants and scholarships, PCF makes annual grants in six areas: arts and culture, education, environment, health, human services, and youth. These grants are restricted to Pasadena-area nonprofits to enrich the community and provide vital services to vulnerable residents. PCF is Pasadena’s permanent endowment for public good, building hometown legacies that benefit our community now and for decades to come.
COLLABORATE WITH DONORS
We help people with philanthropic interests support the issues they care about now and in the future. Using a variety of fund options and charitable tools, donors — whether individuals, families or organizations — contribute their assets to PCF in order to manage their giving and accomplish their philanthropic goals.
ESTABLISH ENDOWMENTS AND INVEST AND MANAGE CHARITABLE ASSETS
We assist individuals, families, professional advisors, and organizations to establish endowed funds that benefit diverse philanthropic interests, causes, and organizations in perpetuity and build those endowed assets through prudent investment for long-term growth. Our expert financial advisors also provide nonprofits with endowment management services through our Agency Partner Funds program.
PROVIDE GRANTS TO CHARITABLE ORGANIZATIONS
PCF manages a variety of grant programs that support local nonprofit organizations in Pasadena. PCF works with professional advisors to help their clients organize their charitable giving and maximize the impact of their philanthropy through planned giving options, philanthropic counsel, and personalized support.


Keeping repositories contributable.
This is a great place to talk about your webpage. This template is purposefully unstyled so you can use it as a boilerplate or starting point for you own landing page designs! This template features:
You may raise the issue in our github repository


This block allows one to use the SDS011 particle sensor.
It uses this library : https://github.com/lewapek/sds-dust-sensors-arduino-library