DataNucleus "LDAP" provides persistence of Java objects to LDAP datastores. It builds on top of the DataNucleus "core" jar supporting specific features of LDAP datastores. It provides querying capabilities using JDOQL. The code can be utilised with either JDO or JPA persistence APIs.
Support for this persistence layer is provided by way of a Forum at http://www.datanucleus.org.


PSALMS 115
A psalm written by David
1 Yahweh, people should praise you alone;
they must praise you, not us,
because you faithfully love us and always do what you have promised to do.
2 It is not right that other people groups should say about us,
"They claim that their God is very powerful,
but if that is true, why does he not help them?"
3 Our God is in heaven,
and he does whatever he wants!
4 But their idols are only statues made of silver and gold,
things that humans have made.
5 Their idols have mouths, but they cannot say anything;
they have eyes, but they cannot see anything.
6 They have ears, but they cannot hear anything;
they have noses, but they cannot smell anything.
7 They have hands, but they cannot feel anything;
they have feet, but they cannot walk,
and they cannot even make any sounds in their throats!
8 The people who make those idols are as powerless as those idols,
and those who trust in those idols can accomplish nothing, just like their idols!
9 You, my fellow Israelite people, trust in Yahweh!
He is the one who helps you and protects you like a shield.
10 You priests, descendants of Aaron, trust in Yahweh!
He is the one who helps you and protects you like a shield.
11 All you who have a reverential respect for Yahweh, trust in him!

He will bless the priests,
13 and he will bless all those who have a reverential respect for him;
he will bless important people and people who are considered to be unimportant, everyone!
14 I wish that Yahweh may give many children
to you, my fellow Israelite people, and to your descendants.
15 I wish that Yahweh, the one who made heaven and the earth, may bless all of you!
16 The highest heavens belong to Yahweh,
but he gave everything that is on the earth to us people.
17 Dead people are not able to praise Yahweh;
when they descend into the place where dead people are,
they are unable to speak and cannot praise him.
18 But we who are alive will thank him,
now and forever.
Praise Yahweh!


I am having problems getting my NanodeRF to properly communicate with my personal Emoncms server. I have my EmonTX transmitting valid data to my NanodeRF, which is seen on the serial port of the Nanode. The Nanode is properly receiving an IP address when I try in both the DHCP and in the static IP cases. Using packet sniffing I have determined that the NanodeRF is sending out a valid URL that is reaching the server, but the server is responding with a 403 Forbidden error indicating that it does not have permission to access that part of the server.
I have verified that the server is setup properly by copying the URL stream from the serial monitor and pasting it in a browser and getting the 'OK' response from the server. Using a packet sniffer, the only difference I can see between packets from my browser and packets from my Nanode is in the Host: section of the http GET. In my browser, the HOST section of the packet lists the proper sending IP address, while the packet from the Nanode shows garbage after the Host: text. This is occuring whether I use DHCP to set the Nanode IP address or I set it manually. Any ideas on what to check?
Dan
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
In my browser, the HOST section of the packet lists the proper sending IP address
Sending IP address, or the IP address of the server? I think the HOST field is how apache determines which virtual host to send the request to.
I'm not particularly familiar with the Nanode, but from a quick browse, it looks like this field:
// 1) Set this to the domain name of your hosted emoncms - leave blank if posting to IP address
char website[] PROGMEM = "emoncms.org";
could be what's supposed to end up in the HOST field.
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Also, could you check in your server logs what page is giving the 403 errors ?
Your server logs should also log the complete request (since it is a GET request) with no need of the packet sniffer.
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Thanks for your assistance. I am using the NanodeRF_multinode_static_IP sketch (although I have tried and failed with all of the other sketches as well). Here are what I believe to be the relevant parts of the code. The API key has been hidden to protect the data. My local Emoncms server is <IP_ADDRESS> and my NanodeRF is the <IP_ADDRESS> address.
My apache logs are not showing errors, possibly since the log level is not set properly. The access logs show the get request being received, but not an error. Here are the results of the packet sniffing, using Wireshark to follow the TCP data stream.
A GET request packet stream from the NanodeRF and the server response looks like this:
If I copy and paste the URL from the serial monitor, or from the packet stream and instead of sending it from the URL, send it from a browser I see this successful packet stream.
The two packets are different in a variety of ways, but my main concern is that the Host section following the GET request is blank on the failing packet. When trying this with the NanodeRF_multinode sketch (using DHCP to assign the NanodeRF an IP address), I was getting the same errors, but in that case the Host section had garbage in it instead of being blank. So, that leads me to believe that this part of the ethercard code is not working properly, but I cannot verify. I am not sure if this is something that everyone has, but my server configuration is different and therefore not tolerant of, or if it is a sketch error. To test that I will later today setup an account on the main Emoncms server across the pond and see if I can post to that server with this sketch or if I get the same error.
Apologies for the weird web site formatting. I can't seem to figure out to make it wrap the long lines. Thanks in advance for any assistance.
Dan
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
For what it's worth, I've only had success with a NanodeRF with a static dotted IP address (with WampServer under Windows). All your settings in the Nanode look sensible to me.
Is your server a separate machine, or is it running on the same machine as the browser?
When you sent the data from the browser, did emonCMS respond with "ok" (LOWER CASE, no quotes!) or do you mean Apache responded OK?
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Robert,
My Emoncms is running on a dedicated server, on my home network, under FreeBSD. I posted a tutorial on getting it running under FreeBSD awhile ago. I am using a laptop to do packet sniffing on the network, and looking at the stream between the NanodeRF and the dedicated server. When I copy and post the TCP stream from the packet sniffing and use the browser on the laptop, I am able to see the OK response from Emoncms, and the data shows up in the feeds. I can also do that manually from other computers on the network. While I waited for my EmonTX kit to arrive, I used a professional 3-phase power analyzer (real nice setup I borrowed from work) to log some data from my home/solar panels. I took the spreadsheet of logged data in Excel and wrote a macro to post it to the server every 5 seconds to simulate realtime data being posted. During that work I played with the dashboard and visualization features in Emoncms, so I feel confident that the Emoncms is working properly.
My Dad is in town and we are hooking up the EmonTX to the circuits today and doing the calibration using the power analyzer. So, I will try and use the hosted Emoncms in an hour or two once our calibrations are done. Thanks for everyone's assistance.
Dan
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Well, your server in Wales is receiving my data without error, so the problem is somewhere in my server configuration. I will start investigating that and determine what fixes it and post that here. If anyone has any ideas I would appreciate some hints since browser posted data is OK, but NanodeRF posted data is rejected. I will look at increasing the Apache logging and see if that points to anything.
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
On second look, packet sniffing the outgoing packets to Wales shows that the Host field of the packet is properly filled with "emoncms.org" so it may still be a NanodeRF issue. Anyone get the NanodeRF to work using a static IP address for the server?
Dan
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Does it help any if you load this guy:
char website[] PROGMEM = "<IP_ADDRESS>";
with the static IP address of your server as shown?
That might get your Nanode request looking more like your browser request in the HOST field.
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
As I said (maybe not too clearly), I have a NanodeRF working to Wampserver under Windows XP using static addressing. Here is the pertinent bit:
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x42,0x31,0x42,0x21,0x30,0x31 };
// 1) Set this to the domain name of your hosted emoncms - leave blank if posting to IP address
char website[] PROGMEM = "";
// or if your posting to a static IP server, change to true if you would like the sketch to post to static IP (not sure if this is working..)
boolean use_hisip = true;
//static byte hisip[] = { 213,138,101,177}; //emoncms.org IP
static byte hisip[] = { 192,168,1,65}; // IP of Machine with Wampserver running
// Set to true and enter IP to give the NanodeRF a static IP address - default is DHCP (NB: must be used with static server IP (hisip)
boolean use_staticIP = true;
static byte myip[] = { 192,168,1,66 }; //NanodeRF static IP address - not needed if using DHCP
static byte gwip[] = { 192,168,1,254 }; // gateway ip address - not needed if using DHCP
// 2) If your emoncms install is in a subdirectory add details here i.e "/emoncms3"
char basedir[] = "/emoncms5";
// 3) Set to your account write apikey
// char apikey[] = "----your API key ---";
char apikey[] = "b821f5936a56e44392c6f3bccf2bdcae"; // don't worry - this is a random string
//IP address of remote sever, only needed when posting to a server that has not got a dns domain name (staticIP e.g local server)
byte Ethernet::buffer[700];
That looks similar enough to me to think the problem isn't there - unless there's something funny going on with line endings or something like that.
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
My theory is (but it's nothing more than a hunch) that Robert's Wampserver is more forgiving about having a blank HOST field than Dan's apache is. From what I can tell (without have a setup here to experiment with), whatever you put in:
char website[] PROGMEM = "";
ends up in the HOST field. Since we know Dan's apache is happy when it sees <IP_ADDRESS> in the HOST field (as shown by his browser experiments), then perhaps forcing the Nanode to do the same may sort it.
Robert, do you have any way to inspect your packets to see if your HOST field is indeed blank with the above config?
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
It will be late tomorrow (15 hrs at best) before I can look at that - assuming my brain doesn't overheat. What I can add now is I've looked at the library used by the Nanode - and it's totally uncommented and impenetrable. I think - I'm not sure - that if it sees anything in PROGMEM, it uses that in preference to the IP address, even if you say don't.
I'm still running Apache of course, it's just that the configuration is likely to be not quite the same! I've got Wireshark so I'll get that out.
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Yeh, I think it very much depends on your virtual hosts config. There's a description of how apache uses the provided HOST: field here:
https://httpd.apache.org/docs/2.0/vhosts/details.html
... including which rule it follows when it's blank. So Dan, I suspect you've got two options:
1. find a way to force the Nanode to put the server IP address in the HOST field (like your browser does)
2. reconfigure your apache vhosts stuff so that blank or unknown HOSTs end up at the right virtual host
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Thank you all for the comments and information. I have tried in the past to put the IP address in the website field as dBC indicated above, but that did not work at the time. When I tried that I did not have packet sniffing going on, just seeing no response from the server and no data posted.
Thanks for your extra words Robert. I have tried all of those items as well with no success. Static IP for NanodeRF with static IP for server, DHCP for NanodeRF (successful) with static IP for server, and all variations of the same. I have also tried using my dynamic DNS address that points to my WAN IP address, and turning on port forwarding to my server, so the packet leaves my house, bounces back, and then hits the server using name addressing. The DNS lookup correctly gets my external IP address, but the server still refuses it.
One challenge is that without packet sniffing, or digging into the Apache logs, you cannot tell the difference between the NanodeRF not reaching your server, and it getting refused for some other reason. The serial monitor says the same thing. It may be useful if the NanodeRF gets some form of response back to post that response code instead of only posting the Data Received message on a successful post.
Looking through the documentation on the Apache httpd.conf file, there is a spot where you list the server name, or the server IP address. I have edited that many ways as well without success. I am also attempting to get my router, which can act as a local DNS server, to give the Emoncms server a network name that I can try to address, but so far have not been successful at that. Anyhow, I will dig into the Vhosts link you have given later this weekend. I will be busy most of tomorrow so I won't get back to this until tomorrow night or Sunday. Thanks again for your collective thinking and hopefully when we figure it out we can get a root cause to share and help ease the collective burden. Good night.
Dan
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Hi, had a look at the ethercard code that the firmware is using .... If you have set up apache with a virtual host identified by a name, then you should put that name in the website array, and you should halso put the ip in the hisip array and set the boolean use_hisip to true
If on the other hand, your virtualhost is identified by an ip, you should put the ip, and still use the hisip in order not to trigger a dns resolution
If it is neither of these two, then you should post the relevant part of the apache config file (the virtualhost section) to see whether you are doing something weird with the folder access rules....
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Here is the NanodeRF successfully talking to Apache under Wampserver. I've given you the bytes for the whole frame so that you can see exactly what's being sent and returned.
I think this just confirms, Dan, that your Nanode is doing the same as mine. It looks to me as if Matt is on the right track...
(Falsified APIkey again!)
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
Yes, I believe it is a server name issue. I recall when working to get the system originally running I had two different configuration files where the server name was put in, but I can only find one right now. I will dig further in and report back when I figure it out. In the mean time, I am logging my data to the Wales hosted Emoncms server to do some power logging so I can see how accurate my calibrations on the EmonTX have been. I have limited use of a very nice Fluke 435 3 phase power analyzer from work so I am trying to compared summed values over time to see how accurate it runs compared to the Fluke. The generated readings are fluctuating quite a lot so I am interested in seeing if that noise integrates out. Once I see that accuracy over a few days I will try out the Emonlibpro that was recently posted to compare.
Thanks for your notes and information. I will update when I figure more out.
Dan
Re: Solved - Problem with Nanode RF reaching personal Emoncms server - 403 Forbidden error
I have determined the problem and corrected it. The issue relates to addressing Emoncms servers only by IP address instead of by DNS name. The httpd.conf file used by the Apache server to set many server options has a section in which you tell it the server name. More information on it can be found here: http://httpd.apache.org/docs/2.2/configuring.html. The comments in the config file tell you if your server does not have a name, to put the IP address in it. But, even with that setting, it will look for the HOST: field of the GET packet to list that IP address before serving any files. Without that field being filled in, and nothing extra in the httpd.conf file to tell it what to do, it will return a HTTP 403 Forbidden code which the NanodeRF does not know what to do with.
By adding a virtual hosts section to the httpd.conf file, a server can serve multiple sites from one IP address, matching the hosts field with the server name for each host (http://httpd.apache.org/docs/current/vhosts/examples.html). In this case, we can use the virtual hosts section with a wildcard "*" to tell it what to do with packets that have the HOST field blank. So, adding:
to the httpd.conf file right after the default document root section of the config file fixed it. The DocumentRoot is simply the default root for the apache server as a whole. The *:80 in the VirtualHost header tells it what to do if a packet arrives that does not match any other listed virtual hosts. Since I don't have any other hosts listed, it defaults to the root for all packets.
So, to summarize, if you want a static IP for your personal Emoncms server, and you are getting 403 forbidden errors (which the NanodeRF will not report but you may see in the Apache logs if you set it to list the details (http://www.cyberciti.biz/faq/apache-logs/), set the ServerName to your static IP and add the above lines below the DocumentRoot section, and it should work.
Let me know if you have any questions. Thanks to all who assisted and for my Dad who tracked down the page on virtual host settings.
Dan


Previous drug experience: Whole lot of weed, some dramamine, some DXM, and a little bit of alcohol.
2 days ago my friend gave me a 12 pills of Concerta. He did not know the exact milligrams of these pills as the outer shell of the pills were somehow removed before he recieved them. I had never done any type of pills before. He told me that they would make me feel good and would allow me to concentrate like I wouldn't believe. He wasn't lying.
It was Thursday, and I had a big test. I am horrible at tests. I always go blank. I thought of the Concerta. I decided to take 2 of them. Before I left school I swallowed the 2 pills. It was on an empty stomach. By the time I arrived at school, which is a 20 minute ride, I was feeling a lot better than I usually do in the mornings. I was ready. I wanted to talk to someone. I was excited about school and all of the people that I would be able to see throughout the day. This is very unlike me.
The bell rang and school was in session. I had a huge test. English.  The only thing I hate more in school than English class is interpreting poems in English class. You can guess where this is going. I had predetermined that I would be getting somewhere around a 50 on it the day before. The teacher handed out the test. Long, complicated poems. The first direction on the test was to give a summary of a random poem. I looked at the poem and read it. For once I understood it. I could concentrate on it for more than 5 seconds to actually read it and understand it. I am the first one to turn in the test, and I am confident that I did very well.
The next 30 minutes were very boring. I felt like talking to everyone in the room all at the same time, but I had to keep quiet as I was the only one finished. The teacher got angry at me because I was fidgeting so much. He called me over to his desk. Since I finished so early he had enough time to grade my test. 92.  That is the highest test grade I have made the entire year, and on poetry of all things.
Luckily for me in my next class, we had a subsitute, a very lenient subsitute. Everyone was allowed to talk. Myself and four other friends made a circle with our desks to play blackjack. I had so much to say. Everything I wanted to say had so much meaning. I had so many words to say, the words that I did get out were jumbled, and didn't make too much sense. I didn't care. I was in one of the best moods of my life. I seemed to be the center of attention for the rest of the class period, which is unusual becuase I usually just listen to what my friends have to say and don't say anything.
My next class is very boring. I have calmed down a lot. I am a lot less jittery. The class is Driver's Ed. We sit in the library all day while the teacher take one student out at a time to drive. While in the library we are not allowed to talk, eat, sleep, drink, leave our designated area, and we can only sit two to a table. Hail Fuhrer! I just do homework for my English class and my class coming up that was supposed to be done last night. I get it done suprisingly quick. I read a book for the rest of the period. Me... read a book... I must be high.
Lunch. I'm not hungry at all, so I go outside to the courtyard to talk to my friends and play hackysack.
My next class is pretty fun. World History. We started a new chatper, and the entire class period we have discussions. Something I would usually hate. I make great points the entire class.  Although there is no euphoria like there was in my first class and most of my second class, I still feel wonderful.
School is over. My friends and I walk home. They seem to notice something about me, and they mention it, but I say that they seeing things. Well, I did tell the friend who gave me the pills. On the way home he told me about snorting them. He told me to open them up and crush the white and pink parts, and just throw away the green part. He says that it gives a huge rush. He compared it to a dilluted version of coke, which he has done in the past.
When I get home, I still feel some of the effects of the pills. I guess I have no tolerance what-so-ever for methylphenidate. I do all of the my homework for my history class, which was to write an essay that summarized the entire chapter we went over in class. It took me 10 minutes. This was a task that would regulary take me 30 or 40 minutes.
Around 5:30, it hits me. I have a huge headache.  When I woke up, I was pretty bored. I see the pills. I couldn't wait to open those suckers up. I had never insufflated anything before. I was very curious. It turned out to be much harder than it seemed.   I didn't even think of getting it into a powder.
Well, I finally got it somewhat crushed up. I did it at exactly 10:00 so I could keep track of my experience. It kept getting stuck in my nosehairs. But I did manage to crush up and snort 2 pills. I could feel it in about 2 minutes. It made me dizzy.  The dizzyness goes away, and I feel really good. It was 10:00 by the time I snorted the pills, and by 10:02 I felt it, and by 10:11 I felt really Euphoric. I was on the internet and typing a million words a minute to anyone who was online. At around eleven, I started to notice little things out of the corners of my eyes, nothing major, just dots or the like. And every once and a while I would see lines that looked like when you stare at something bright and then look away to see the outline, except I didn't have to do this.

In summary, 2 pills ingested took around 30 minutes to take effect, and I felt very good, a little euphoric and good about myself, and could easily concentrate for the next 3 hours, and I could, think very well, and felt good self-esteem for the next 6 hours. With the 2 pills I snorted, the effects took place in about 2 minutes, and I felt very euphoric for the next 3 hours.
I may do this in the future, but only if I really need to be able to concentrate, and I would only do it orally. This is because the next day I was left with a headache, a sore nose, and a yearning to do more. Even after one time I wanted to do more, so I can easily see how people can get hooked on this drug.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


| DOSE: |
2 hits |
oral |
LSD |
(blotter / tab) |
I first moved into my college dorm room not knowing what to expect. I had transferred to a new school, with my girlfriend and another friend. The campus seemed, well dull and dry as could be. So all we had to keep ourselves entertained was the local liquor store that did not id. From the looks of most of the other students I wouldnít be finding anything to smoke until I returned home. I had no idea that a drug dealer lived only a few rooms down the hall!
Eventually this came to my attention, as the familiar smell of cannabis filled the hallway. Being that this was a freshman/transfer student dorm building I figured hey they are probably looking to make a few friends who also smoke. So I gave his door a knock, and nothing. Somewhat depressed I headed back to my room mentioning what I had smelled to my girlfriend. Fortunately the next day I saw him in the hallway, so I decided to start a conversation with him. Eventually finding out he sold weed, acid, shrooms and other various drugs. At first I just stuck to good old weed. After about a month of knowing him, and becoming fairly good friends with him, he offered me acid for $10 a hit. So we (my girlfriend, friend and I) decided to try it.
The first 45 minutes went by and absolutely no effects were noticed. After about an hour and a half after taking the acid I began to intensely feel the effects. I began to question the nature of things for some odd reason. This led me to my 30 gallon fish tank, which I had recently purchased. I began rambling on about how these fish should be free, and what a shitty life they must be living now. This conversation brought my friend and girlfriend to the tank. They began gazing, and my girlfriend agreed with my comment. I began to hate the people that must have captured them and sent them to the pet store ultimately doomed to swim in my rectangular tank for the remainder of their lives.
I suddenly realized someone was knocking on my door. I was relieved to find out it was just the kid from down the hall. He instantly knew we were on acid and began to smile. We invited him to spend the night with us and he took 2 hits. Seeing this I decided to get each of us another hit. So after taking that we decided to go outside. Little did we know there was a rather large amount of snow falling in our area, which made the experience wonderful. Everything was blanketed with snow, and glistening. At first I wanted to run back upstairs to grab my jacket because it happened to be a fairly cold night. However, we began walking towards this large parking lot on the campus and the longer I walked the warmer I became. Eventually I felt perfectly fine wearing a t-shirt and jeans.
Once at the parking lot, we were in for a hilarious experience. While walking around we all managed to end up on a sheet of ice that built up on the blacktop of the parking lot. For some reason I felt like ice-skating in my sneakers, and my girlfriend began to follow my lead. She fell backwards and we all started laughing so hard. I slipped and fell to the ground from laughing and that only made everyone laugh harder. After a few minutes everyone was on the ground laughing. Eventually we all regained our balance and headed back into the dorm.
Before I met them in my room I went to one of the many shared bathrooms in my building. My school had these already trippy looking floor tiles that we all used to joke around about on the bathroom floors and walls. They now began to swirl but only when I concentrated on the toilet bowl. It was one of those out of the corner of my eye kinda things. Every time I looked at the tiles they stopped, and began swirling every time I looked back at the toilet. This kept me entertained for what seemed like 10 minutes but what was probably only 1 or 2 minutes.
I decided to head back to my room and meet back up with my friends. After only half an hour I decided to go for a drive.
[Erowid Note: Driving while intoxicated or tripping is dangerous and irresponsible because it endangers other people. Don't do it!] It had to be 11 pm and because of the snow storm nobody was traveling on the roads. Also I figured I swerved slightly because of the effects of the acid I could blame it on the snow. It wasnít really that bad at first. I really tried to concentrate only on driving and that wasnít all too difficult. I began to feel connected through the car somehow while driving along. Especially so when I pressed the breaks, I could feel the pulsation of the anti-lock breaks. It seemed to shoot up through my entire body and it almost felt like a pain. Similar to that sort of pain associated with nails on a chalk board.
In any event we arrived at the 7eleven and purchased random snacks, although the acid didnít give me the munchies at all. We decided to smoke when we arrived back at the dorm so we grabbed some cigars and snacks for the expected munchies.  I love the movie straight or even while smoking weed, but definitely not on acid. Everyone unanimously wanted to stop watching it, so we turned on some techno and Winamp visualizations. I normally donít listen to much techno, unless high, but its excellent while on acid.
Eventually the night came to an end, everyone left except my girlfriend and I, so we tried to sleep. Unfortunately this didnít seem possible, as we laid there for half an hour with no progress. So we talked the night away, about every subject that came to mind. Overall an amazing experience and I have taken acid several times after this first time.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Azure Stream Analytics is a cloud-based service for ingesting high-velocity data streaming from devices, sensors, applications, Web sites, and other data sources and analyzing that data in real time. It supports a SQL-like query language that works over dynamic data streams and makes analyzing constantly changing data no more difficult than performing queries on static data stored in traditional databases. With Azure Stream Analytics, you can set up jobs that analyze incoming data for anomalies or information of interest and record the results, present notifications on dashboards, or even fire off alerts to mobile devices. And all of it can be done at low cost and with a minimum of effort.
Scenarios for the application of real-time data analytics are legion and include fraud detection, identity-theft protection, optimizing the allocation of resources (think of an Uber-like transportation service that sends drivers to areas of increasing demand before that demand peaks), click-stream analysis on Web sites, shopping suggestions on retail-sales sites, and countless others. Having the ability to process data as it comes in rather than waiting until after it has been aggregated offers a competitive advantage to businesses that are agile enough to make adjustments on the fly.
In this lab, you'll create an Azure Stream Analytics job and use it to analyze data from simulated Internet of Things (IoT) devices. You will see how simple it is to monitor real-time data streams for information of significance. And at the end, you will build a Web app that shows output from the Stream Analytics job in real time.
In this hands-on lab, you will learn how to:
The following are required to complete this hands-on lab:
This hands-on lab includes the following exercises:
Estimated time to complete this lab: 75 minutes.
Azure Stream Analytics supports several types of input, including input from Azure blobs and input from Azure event hubs. Of the two, the latter is typically more interesting because in the IoT world, data is easily transmitted to Azure event hubs through field gateways (for devices that are not IP-capable) or cloud gateways (for devices that are IP-capable), and a single Azure event hub can handle millions of events per second transmitted from devices spread throughout the world.
In this exercise, you'll create an Azure event hub to provide input to Azure Stream Analytics and configure it to so that it can be accessed safely and securely by IoT devices and gateways.
Because the Azure Portal lacks full support for event hubs and Stream Analytics at the moment, you will work this lab using the Classic Portal. Go to https://manage.windowsazure.com to open the Classic Portal, and click Service Bus in the ribbon on the left. Then click CREATE A NEW NAMESPACE to create a new service-bus namespace. (If you have already created one or more namespaces, click + NEW in the lower-left corner of the page to create another one.)
Azure Service Bus
Type a namespace name into the NAMESPACE NAME box. The name must be unique within Azure, so you'll have to use something other than the name in the screen shot below. (A green check mark will appear in the box when the name you've entered is one that Azure will accept.) Set TYPE to EVENTHUB, and choose the region closest to you from the REGION drop-down. Then click the check mark in the lower-right corner of the dialog.
Creating a service-bus namespace
Click the + NEW button in the lower-left corner of the page. Click EVENT HUB, followed by QUICK CREATE. Type "inputhub" (without quotation marks) into the EVENT HUB NAME box (the name doesn't have to be unique within Azure). Select the same region you selected for the service-bus namespace in the previous step, and make sure the namespace you created in that step is selected in the NAMESPACE box. Then click CREATE A NEW EVENT HUB in the lower-right corner.
Creating an event hub
Wait for the event hub to be created. Then click the event hub name to display the event hub's dashboard.
Opening the event hub
Click CONFIGURE.
Configuring the event hub
In order to transmit events to the event hub from an application or device, you need to create a shared-access policy that includes Send permission. In the shared access policies section of the page, create a new policy by typing "SendPolicy" (without quotation marks) into the first text box and checking the Send box in the drop-down list under PERMISSIONS. Then click the Save button at the bottom of the page to save the new policy.
Creating a policy with Send permission
Click DASHBOARD near the top of the page to return to the event hub's dashboard.
Returning to the dashboard
Under quick glance on the right side of the page, click View Connection String.
Viewing the connection string
Copy the connection string to the clipboard. (If you hover over the connection string, a copy-to-clipboard button will appear.) Then click the check mark to dismiss the dialog. Finish up by pasting the connection string into your favorite text editor so you can retrieve it in the next exercise.
Copying the connection string
You have created an event hub that can ingest events and be used as the source of input to a Stream Analytics job. You have also created a policy that allows holders of that policy to send events to the event hub, and a connection string that encapsulates that policy. The next step is to use that connection string to transmit events to the event hub.
Applications, devices, and gateways can send events to Azure event hubs using the Azure Event Hubs REST API or the Advanced Message Queuing Protocol, or AMQP for short. In this exercise, you will write a Windows console app that uses AMQP to send events to the event hub you created in Exercise 1. Each event will represent a withdrawal from an ATM machine, and will contain relevant information such as the card number used for the withdrawal, the time and amount of the withdrawal, and a unique identifier for the ATM machine used.
Start Visual Studio 2015 and use the File -> New -> Project command to create a new Windows Console Application named "ATMEventGenerator."
Creating a new console app
In the Solution Explorer window, right-click the ATMEventGenerator project and select Manage NuGet Packages...
Managing NuGet Packages for the project
NuGet is a free and open-source package manager for Microsoft development platforms. It provides access to thousands of libraries, or packages, containing code to perform a variety of tasks. It is integrated into Visual Studio 2015, which makes it easy to add NuGet packages to your project and make a lot of things happen without writing a lot of code.
Click Browse. Then type "azure" (without quotation marks) into the search box. Click WindowsAzure.ServiceBus to select the Azure service-bus package from NuGet. Finally, click Install to install the latest stable version of the package. This package contains the APIs that your app will use to send events to the event hub.
Installing WindowsAzure.ServiceBus
If prompted to review changes, click OK. Optionally check Do not show this again so you won't be prompted again.
Reviewing changes
If prompted to accept a license for the package, click I Accept..
Accepting the package license
Return to the search box and type "newtonsoft," again without quotation marks. Select Newtonsoft.Json and click Install to install the latest stable version of Json.NET. This package contains convenient APIs for generating and consuming JSON. If prompted to review changes, click OK.
Installing Json.NET
Open Program.cs and add the following using statements to the using statements at the top of the file:
using Microsoft.ServiceBus.Messaging;
using Newtonsoft.Json;
Replace the empty Program class with the following implementation:
class Program
{
static double _probability = 0.01;
static int _transactions = 0;
static int _cardNumber = -1;
static string _connectionString = "connection_string";
static void Main(string[] args)
{
var rand = new Random();
var client = EventHubClient.CreateFromConnectionString(_connectionString, "inputhub");
while (true)
{
int card = 123456789 + rand.Next(0, 888888888);
// Occasionally generate a fraudulent transaction by reusing a card number
if (rand.NextDouble() < _probability && _cardNumber != -1)
{
card = _cardNumber;
_cardNumber = -1;
}
// Formulate a transaction
var transaction = new {
transactionId = _transactions++,
transactionTime = DateTime.UtcNow.ToString(),
deviceId = 12345 + rand.Next(0, 88888),
cardNumber = card,
amount = rand.Next(1, 20) * 20
};
// Occasionally record a card number for later use in generating fraud
if (rand.NextDouble() < _probability)
{
_cardNumber = transaction.cardNumber;
}
// Send an event to the event hub
var message = JsonConvert.SerializeObject(transaction);
client.Send(new EventData(Encoding.UTF8.GetBytes(message)));
Console.WriteLine("[{0}] Event transmitted", transaction.transactionId);
}
}
}
Replace connection_string in line 6 with the connection string you copied to the clipboard (and hopefully into your favorite text editor) in Exercise 1, Step 9.
Remove ";EntityPath=inputhub" from the end of the connection string. The _connectionString field should now look something like this:
static string _connectionString = "Endpoint=sb://dxlabs.servicebus.windows.net/;SharedAccessKeyName=SendPolicy;SharedAccessKey=Zx/fjB8kH3nuW789pUpXJ1S45FkMacJq9gYku6cRD3Y=";
Press Ctrl+F5 to run the program and confirm that you see output similar to the following. Each line represents one event sent to the event hub, and events will probably roll by at a rate of about 2 to 3 per second. (Rates will vary depending on your connection speed.) Confirm that no exceptions are thrown.
Messages sent to the event hub
Press Ctrl+C to stop the flow of events. Then press Enter to close the Command Prompt window.
In real life, there would be real ATM machines sending events to the event hub. ATMEventGenerator simulates these events in software and sets the stage for you to build and test a Stream Analytics job that analyzes these events.
You now have software that sends events to an Azure event hub, and an event hub that ingests the data. In this exercise, you'll use the Microsoft Azure Classic Portal to create a Stream Analytics job and connect it to the event hub. You'll also capture the raw data being presented to Stream Analytics by the event hub and examine its structure.
Open the Classic Portal in your browser if it isn't already open. Click STREAM ANALYTICS in the ribbon on the left, and then click CREATE A NEW STREAM ANALYTICS JOB.
Azure Stream Analytics
Type "IoT-Analytics" (without quotation marks) into the JOB NAME box. Select the region nearest you in the REGION box. (It is important to select the same region here that you selected for the event hub in Exercise 1, because you're not charged for data that moves within a data center, but you are charged for data that moves between data centers. In addition, locating services that talk to each other in the same data center reduces latency.) Under REGIONAL MONITORING STORAGE ACCOUNT, either specify the name of a new storage account, or select an existing storage account if the portal presents you with that option.
If you choose to create a new storage account, recall that storage-account names can be 3 to 24 characters in length, can only contain numbers and lowercase letters, and must be unique within Azure. A green check mark next to the name indicates that it meets all these criteria. It is also advisable to locate the storage account in the same region as the Stream Analytics job to prevent the data from moving between data centers.
When you're done, click CREATE STREAM ANALYTICS JOB in the lower-right corner.
Creating a Stream Analytics job
After a few moments, the Stream Analytics job will appear in the portal. Wait until the job has been created, and then click it.
The new Stream Analytics job
Click INPUTS near the top of the page.
IoT-Analytics page
Click ADD AN INPUT.
Adding an input
Make sure Data stream is selected, and then click the right-arrow in the lower-right corner of the dialog.
Specifying an input type
Make sure Event Hub is selected, and then click the right-arrow.
Specifying a data-stream type
IoT hubs are a relatively recent addition to Azure. Their primary purpose is to enable two-way communications between hubs and IoT devices, and to allow devices that communicate with them to be registered. You chose Event Hub because you don't need the added functionality that IoT hubs provide. In addition, IoT hubs are still in preview and therefore are subject to change.
Enter "Withdrawals" (without quotation marks) as a friendly alias for the input in the INPUT ALIAS box. In the CHOOSE A NAMESPACE and CHOOSE AN EVENTHUB boxes, select the namespace and event hub that you created in Exercise 1. Leave EVENT HUB POLICY NAME set to RootManageSharedAccessKey (that's a default policy that's created automatically when you create an event hub; it grants permission to manage the event hub, send events, and receive events) and CHOOSE A CONSUMER GROUP set to $Default. Then click the right-arrow in the lower-right corner.
Specifying event-hub settings
Make sure JSON is selected under EVENT SERIALIZATION FORMAT (the console app that sends events to the event hub sends JSON data), and UTF8 is selected under ENCODING. Then click the check mark in the lower-right corner to finish adding the input.
Specifying a serialization format
After a few moments, the new input — "Withdrawals" — appears in the list of inputs for the Stream Analytics job. Go back to Visual Studio and run ATMEventGenerator again.
Allow ATMEventGenerator to run for a minute or two. Then press Ctrl+C to stop it and Enter to close it, and return to the portal open in your browser.
Click the SAMPLE DATA button at the bottom of the page to sample data from the event hub.
Sampling input data
Click the check mark in the lower-right corner of the ensuing dialog to sample any data transmitted to the event hub in the last 10 minutes. (This is why you ran ATMEventGenerator again: to make sure there is data to sample, even if more than 10 minutes have elapsed since you completed Exercise 2.)
Specifying start time and duration
Wait until sampling has completed. Then click the button in the lower-right corner of the page that indicates the operation has completed.
Data sampling completed
When a ribbon appears that says "Successfully sampled data from Withdrawals," click the Details button on the right.
Data sampling succeeded
Click Click here to download the data sampled from the event hub. Save the JSON file that is downloaded to a location where you can easily find it. Then click OK to dismiss the ribbon.
Downloading sample data
Open the JSON file you downloaded in your favorite text editor and take a moment to examine its contents. How many rows (events) are represented in the sample data? What is the structure of each row — that is, what fields does each row contain?
If you find the output hard to digest since there are no line breaks, try pasting it into an online JSON viewer such as the one at http://jsonviewer.stack.hu/ or https://jsonformatter.curiousconcept.com/.
You have connected a Stream Analytics job to an event hub and demonstrated that data is passed from one to the other. You have also examined the structure of that data. The next step is to do something with it — specifically, to bring the power of Azure Stream Analytics to bear on the data.
Now that your job is set up, there's much more you can do with Stream Analytics than simply view the raw data presented to it. The whole point of Stream Analytics is being able to perform queries on the data, even though the data is dynamic rather than static. In this exercise, you'll use the Stream Analytics Query Language to query a sample data set for potentially fraudulent ATM transactions. It is always a good idea to test your queries against sample data before deploying them against live data streams, because with sample data, you can verify that a known set of inputs produces the expected set of outputs.
To flag potentially fraudulent withdrawals from ATMs, you will query for transactions performed with the same ATM card at different ATM machines within a specified time window (60 seconds). In real life, you would probably use a larger time window and perhaps even factor in the distance between ATM machines. However, a narrower time window is useful in a lab environment because it allows you to perform meaningful experiments in minutes rather than hours.
Begin by returning to the Stream Analytics job in the portal and clicking QUERY at the top of the page.
Navigating to the Query page
Enter the following query into the query field, and then click the Test button.
SELECT * FROM Withdrawals
Where did the name "Withdrawals" come from? That's the alias you assigned to the event-hub input in the previous exercise. If you named it differently, you'll need to replace "Withdrawals" with the alias you used.
Testing a query
In the ensuing dialog, click BROWSE FOR FILE. Select the file named Withdrawals.json provided in the "resources" directory of this lab. Then OK the selection by clicking the check mark in the dialog's lower-right corner.
The reason you're using a file provided for you (rather than the one you captured in the previous exercise) is to make sure everyone who is doing this exercise gets the same results.
Loading test data
Scroll down the page and confirm that you see the output pictured below. The test data contains 607 rows. Each row has fields named TRANSACTIONID, TRANSACTIONTIME, DEVICEID, CARDNUMBER, and AMOUNT. DEVICEID is the ID of the ATM machine at which the transaction took place. AMOUNT is the amount of cash withdrawn from the ATM.
Output from SELECT *
Suppose you only wanted to view transactions for amounts between 200 and 300, inclusive. Furthermore, suppose you wanted to clean up the output by assigning your own column names and excluding the TRANSACTIONID column. Enter the following query and click the Rerun button to test it. (Rerun executes the query against the test data already loaded. If you wanted to load a different test file, you would click the Test button again.)
SELECT TransactionTime as [Time of Transaction], DeviceID as [ATM], CardNumber as [Card Number], Amount as [Amount] FROM Withdrawals WHERE Amount >= 200 and Amount <= 300
Scroll down and confirm that the query generated the following output:
Customizing the output
One of the key features of the Stream Analytics Query Language is its ability to group results using windows of time whose length you specify. To demonstrate, enter the following query to count the number of transactions taking place each minute and click Rerun to execute it:
SELECT System.Timestamp as [Time Ending], COUNT(*) AS [Number of Transactions] FROM Withdrawals TIMESTAMP BY TransactionTime GROUP BY TumblingWindow(n, 1)
TIMESTAMP BY is an important element of the Stream Analytics Query Language. If it was omitted from the query above, you would be querying for the number of transactions that arrived at the event hub each minute rather than the number of transactions that occurred in each 1-minute interval. TIMESTAMP BY allows you to specify a field in the input stream as the event time.
Scroll down and confirm that you see the output below:
Number of transactions per minute
Now it's time to query the test data for potentially fraudulent transactions — transactions involving the same ATM card but different ATM machines that take place within 60 seconds of each other. This is the query you will later use against a live data stream.
Enter the following query and click Rerun to execute it:
SELECT W1.CardNumber as [CardNumber], W1.DeviceID as [ATM1], W2.DeviceID as [ATM2], W1.TransactionTime as [Time1], W2.TransactionTime as [Time2] FROM Withdrawals W1 TIMESTAMP BY TransactionTime JOIN Withdrawals W2 TIMESTAMP BY TransactionTime ON W1.CardNumber = W2.CardNumber AND DATEDIFF(ss, W1, W2) BETWEEN 0 and 60 WHERE W1.DeviceID != W2.DeviceID
This time the output should contain just three rows, each representing two transactions performed with one ATM card at two different locations within 60 seconds of each other:
Potentially fraudulent transactions
Click the SAVE button at the bottom of the page to save the query. Then click YES when asked to confirm.
Saving the query
With the query now formulated, tested against a set of sample data, and saved, it's time to deploy it against a live data stream to produce a running record of potentially fraudulent transactions.
Being able to run queries and see the results in the portal is great for testing, but the whole point of Stream Analytics is being able to query live data streams. Azure Stream Analytics supports a variety of output types, including blobs, Azure SQL databases, and event hubs. You can designate blob storage as the destination for output from a Stream Analytics job to generate a persistent record of query results. Another useful scenario involves using event hubs as output. Because software can subscribe to events from event hubs, developers can build custom applications that show Stream Analytics output in real time.
In this exercise, you'll configure the Stream Analytics job to write output to an event hub.
Return to the Classic Portal and click the + NEW button in the lower-left corner.
Click APP SERVICES -> SERVICE BUS -> EVENT HUB -> QUICK CREATE to create a new event hub. Name the event hub "outputhub," select the same region you selected for the other event hub and the Stream Analytics job, and select the namespace you created in Exercise 1. Then click CREATE A NEW EVENT HUB.
Creating an event hub for output
Click the new event hub to go to the event-hub dashboard.
Opening the event hub
Click CONFIGURE.
Configuring the event hub
In order for an application to subscribe to events firing from an event hub, you need to create a shared-access policy that includes Listen permission. In the shared access policies section of the outputhub configuration page, create a new policy by typing "ReceivePolicy" (without quotation marks) into the first text box and checking the Listen box in the drop-down list under PERMISSIONS. Then click the Save button at the bottom of the page to save the new policy.
Creating a policy with Listen permission
Click DASHBOARD near the top of the page to return to the event hub's dashboard.
Returning to the dashboard
Under quick glance on the right side of the page, click View Connection String.
Viewing the connection string
Copy the connection string to the clipboard. (If you hover over the connection string, a copy-to-clipboard button will appear.) Then click the check mark to dismiss the dialog. Finish up by pasting the connection string into your favorite text editor so you can retrieve it in the next exercise.
Copying the connection string
Click the STREAM ANALYTICS button in the ribbon on the left to list all your Stream Analytics jobs, and then click IoT-Analytics to return to your Stream Analytics job.
Returning to the Stream Analytics job
Click OUTPUTS.
Navigating to the Outputs page
Click ADD AN OUTPUT to add an output to the job.
Adding an output
Select Event Hub as the output type. Then click the right-arrow in the lower-right corner of the dialog.
Specifying the output type
Type "Flagged-Withdrawals" into the OUTPUT ALIAS box. Select Use Event Hub from Current Subscription, the namespace you created in Exercise 1, and the event hub you created in this exercise (outputhub). Then click the right-arrow in the lower-right corner.
Specifying event-hub settings
Make sure EVENT SERIALIZATION FORMAT, ENCODING, and FORMAT are set as shown below, and then finish up by clicking the check mark in the lower-right corner.
Specifying serialization settings
Now that you have directed the output from the Stream Analytics job to an event hub, the next task is to write an app that consumes events from that event hub.
In this exercise, you will write a Web app that connects to the event hub and displays real-time notifications of potentially fraudulent transactions.
Start a new instance of Visual Studio 2015 and use the File -> New -> Project command to create a new ASP.NET Web Application named "ATMDashboard."
Creating a new Web app
In the New ASP.NET Project dialog, select MVC and check the Web API box. If Host in the cloud is checked, uncheck it. (For testing purposes, you'll run this Web app locally.) Then click OK.
Specifying paremeters for the Web app
In the Solution Explorer window, right-click the ATMDashboard project and select Manage NuGet Packages...
Managing NuGet Packages for the project
Click Browse. Then type "eventprocessor" (without quotation marks) into the search box. Click Microsoft.Azure.ServiceBus.EventProcessorHost to select the Azure EventProcessorHost package from NuGet. Finally, click Install to install the latest stable version of the package. This package contains the APIs that your app will use to receive events from the output event hub. Click OK if you're prompted review changes, and I Accept when prompted to accept licenses for the downloaded packages.
Installing EventProcessorHost
Right-click the project in the Solution Explorer window and use the Add -> Class command to add a class named ATMEvent to the project.
Adding ATMEvent
Implement the ATMEvent class as follows:
public class ATMEvent
{
public string CardNumber { get; set; }
public string ATM1 { get; set; }
public string ATM2 { get; set; }
public string TransactionTime1 { get; set; }
public string TransactionTime2 { get; set; }
}
Right-click the project in the Solution Explorer window and use the Add -> Class command to add a class named ATMEventAggregator to the project.
Adding ATMEventAggregator
Implement the ATMEventAggregator class as follows:
public static class ATMEventAggregator
{
private static List<ATMEvent> _events = new List<ATMEvent>();
public static void LogEvent(ATMEvent e)
{
if (_events.Count < 1024) // Avoid unconstrained memory growth
{
_events.Add(e);
}
}
public static ATMEvent[] GetLoggedEvents()
{
var events = _events.ToArray();
_events.Clear();
return events;
}
}
Right-click the project in the Solution Explorer window and use the Add -> Class command to add a class named SimpleEventProcessor to the project.
Adding SimpleEventProcessor
Add the following using statements to the ones at the top of the file:
using Microsoft.ServiceBus.Messaging;
using System.Diagnostics;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Text;
Implement the SimpleEventProcessor class as follows:
class SimpleEventProcessor : IEventProcessor
{
Stopwatch checkpointStopWatch;
async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
{
Debug.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason);
if (reason == CloseReason.Shutdown)
{
await context.CheckpointAsync();
}
}
Task IEventProcessor.OpenAsync(PartitionContext context)
{
Debug.WriteLine("SimpleEventProcessor initialized. Partition: '{0}', Offset: '{1}'", context.Lease.PartitionId, context.Lease.Offset);
this.checkpointStopWatch = new Stopwatch();
this.checkpointStopWatch.Start();
return Task.FromResult<object>(null);
}
async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
foreach (EventData eventData in messages)
{
string data = Encoding.UTF8.GetString(eventData.GetBytes());
Debug.WriteLine(string.Format("Message received. Partition: '{0}', Data: '{1}'",
context.Lease.PartitionId, data));
// Log the event
ATMEvent e = JsonConvert.DeserializeObject<ATMEvent>(data);
ATMEventAggregator.LogEvent(e);
}
if (this.checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
{
await context.CheckpointAsync();
this.checkpointStopWatch.Restart();
}
}
}
Open Global.asax.cs and add the following using statements:
using Microsoft.ServiceBus.Messaging;
using System.Diagnostics;
In Global.asax.cs, add the following statements to the end of the Application_Start method:
string eventHubConnectionString = "connection_string";
string eventHubName = "outputhub";
string storageAccountName = "storage_account_name";
string storageAccountKey = "storage_account_key";
string storageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", storageAccountName, storageAccountKey);
string eventProcessorHostName = Guid.NewGuid().ToString();
EventProcessorHost eventProcessorHost = new EventProcessorHost(eventProcessorHostName, eventHubName, EventHubConsumerGroup.DefaultGroupName, eventHubConnectionString, storageConnectionString);
Debug.WriteLine("Registering EventProcessor...");
var options = new EventProcessorOptions();
options.ExceptionReceived += (sender, e) => { Debug.WriteLine(e.Exception); };
eventProcessorHost.RegisterEventProcessorAsync<SimpleEventProcessor>(options).Wait();
Debug.WriteLine("Receiving...");
Replace connection_string in line 1 with the connection string you copied to the clipboard (and hopefully into your favorite text editor) in Exercise 5, Step 8.
Remove ";EntityPath=outputhub" from the end of the connection string. The eventHubConnectionString variable declaration should now look something like this:
string eventHubConnectionString = "Endpoint=sb://dxlabs.servicebus.windows.net/;SharedAccessKeyName=ReceivePolicy;SharedAccessKey=3XHaU3pm5t82WxA43hUM/bWa7kumqAsqzJ1rVJq3Qv0=";
Replace storage_account_name in line 3 with the the name of the storage account you created in Exercise 3, Step 2, and storage_account_key in line 4 with the storage account's primary access key. You can copy the access key to the clipboard by opening the storage account in the portal, clicking MANAGE ACCESS KEYS at the bottom of the page, and clicking the Copy button next to PRIMARY ACCESS KEY.
This storage account has nothing to do with the Stream Analytics job; it's used by the EventProcessorHost class. However, you are letting one storage account do double duty for Stream Analytics and EventProcessorHost.
In the Solution Explorer window, right-click the Controllers folder and use the Add -> Controller command to add an empty Web API 2 controller.
Adding a Web API Controller
Name the controller "EventsController" (without quotation marks). Then click Add.
Naming the Web API Controller
Add the following method to the EventsController class:
public ATMEvent[] GetEvents()
{
return ATMEventAggregator.GetLoggedEvents();
}
The controller you just added is a Web API controller. It exposes a REST method that can be called over HTTP to retrieve the latest events that ATMEventAggregator received from the event hub.
Open Index.cshtml in the project's Views/Home folder and replace its contents with the following statements:
@{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<h1>ATM Dashboard</h1>
<p class="lead">The table below lists potentially fraudulent ATM transactions and is updated every 5 seconds.</p>
</div>
<div class="row">
<div class="col-xs-12">
<table id="output" style="width: 100%">
<tr>
<td><b>Card Number</b></td>
<td><b>ATM 1</b></td>
<td><b>ATM 2</b></td>
</tr>
</table>
</div>
</div>
@section scripts {
<script type="text/javascript">
$(function () {
// Check for new events every 5 seconds
window.setInterval(function () {
$.ajax({
url: "/api/events",
success: function (result) {
for (i = 0; i < result.length; i++) {
$("#output tr:last").after("<tr><td>" + result[i].CardNumber + "</td><td>" + result[i].ATM1 + "</td><td>" + result[i].ATM2 + "</td></tr>");
}
},
error: function (xhr, status, error) {
if (status == "error") {
console.log("Error: " + xhr.status);
}
},
dataType: "json"
});
}, 5000);
});
</script>
}
See what's happening here? In addition to modifying the view's UI to include an HTML table in which ATM events can be displayed, you added a script block that uses jQuery's $.ajax method to call back to the server every 5 seconds. The endpoint for the call is the method you implemented in the Web API controller in the previous step. When that method returns one or more events, rows are added to the table to display them.
Go to the Build menu at the top of the Visual Studio window and use the Build Solution command to build the solution. Correct any build errors that are reported, and then press Ctrl+F5 to launch the application in your browser. Confirm that the application looks like this:
The ATM dashboard
Leave the browser open with the application running. And don't be alarmed if a few events show up the first few seconds the dashboard is open. Those are simply events that the event hub cached. You'll be generating new events in the next exercise.
Almost there! Now it's time to run the Stream Analytics job and see the output in your dashboard.
Return to the Stream Analytics job in the Azure Portal and click the START button at the bottom of the page to start it.
Starting the Stream Analytics job
Make sure JOB START TIME is selected, and then click the check mark. JOB START TIME means that the job will begin sampling output from the input source the moment the job is started. Event hubs retain events for a specified period of time (the default is 1 day), so if you wanted, you could select CUSTOM TIME and start sampling output before the job's start time.
Starting the output
Wait until the Stream Analytics job starts. Then return to the instance of Visual Studio in which the ATMEventGenerator project is open and start ATMEventGenerator again to pump events into the input event hub.
If you'd like, you can run several instances of ATMEventGenerator simultaneously to increase the volume of events.
Return to the ATMDashboard application running in your browser and watch for a few minutes. Every so often, a line should appear representing a potentially fraudulent transaction and identifying the ATM card number and the ATMs at which the card was used.
Potentially fraudulent transactions
Return to the Stream Analytics job in the portal and click the STOP button at the bottom of the page to stop it. Then click YES when asked if you're sure you want to stop the job.
Stopping the Stream Analytics job
Return to the console window in which ATMEventGenerator is running and press Ctrl+C to terminate it.
You now have a Web app that displays output from a Stream Analytics job in near real-time. There are other ways to build such dashboards, including Microsoft Power BI. With Power BI, you can create dashboards that render output from Stream Analytics jobs without writing any code. For more information, refer to Stream Analytics & Power BI: A real-time analytics dashboard for streaming data.
Azure Stream Analytics is a powerful tool for analyzing live data streams from IoT devices or anything else that's capable of transmitting data. In this lab, you got a first-hand look at Stream Analytics as well as Azure event hubs. Among other things, you learned how to:
One drawback to hard-coding rules into Stream Analytics is that rules don't "learn" from the data streams, which can lead to false positives in anomaly detection. If this concerns you, read the article entitled Anomaly Detection – Using Machine Learning to Detect Abnormalities in Time Series Data in the Azure team's Machine Learning blog. In it, they present an anomaly detection service accessible through a REST API that uses Azure Machine Learning to learn from the data presented to it. Imagine combining the power of Stream Analytics to extract information from real-time data streams with the power of Azure Machine Learning to learn from that information and refine the analytics on the fly. This is precisely the type of solution that Microsoft Azure empowers you to build!
Copyright 2016 Microsoft Corporation. All rights reserved. Except where otherwise noted, these materials are licensed under the terms of the MIT License. You may use them according to the license as is most appropriate for your project. The terms of this license can be found at https://opensource.org/licenses/MIT.


ScottHugh
Home
Contact
Welcome to my Static GitHub Website.
This is to show-off some of the possibilities on GitHub.
Reach out to me


Settings
Background Notifications
About
My name is Joshua Harms, and I built this application because I needed a way to get alerts when new subscribers joined my ConvertKit list. I'd be a poor ConvertKit user if I didn't mention that I'm writing The Shopify Development Handbook, a premium course for building Shopify apps and integrations with C# and ASP.NET.
This application is an unofficial port of ConvertKit for the universal Windows platform. It's built with WinJS, an implementation of HTML, JavaScript and TypeScript that runs both natively in Windows and can be loaded as a library in the browser. In Windows, a WinJS app is both first-class and native, which means the app runs on bare metal rather than being loaded through a performance-killing webview like you'd find on iOS or Android.
ConvertKit for Windows is open source. You can view the code, make edits, pull requests or just build it for yourself at https://github.com/nozzlegear/ConvertKitForWindows


The BHSP Summer Institute at Notre Dame is designed to jump-start our Scholars’ transition to college life and their acculturation to the demanding academic environment of a top-20 university.
Students will attend five classes during the week and various team building activities on the weekend, all aimed at both academic, social, and emotional growth
The Summer Program will help prepare students for the college life, as well as provide a caring community from day one
Balfour will coordinate travel and cover all costs (including summer tuition, housing and meals) to attend the Summer Institute.
Students will spend four weeks in dorms here at Notre Dame.
(June 27th - July 24th)
Give us a call or send us an email and we will get back to you as soon as possible!
(574) 631-7363


Your new Ufront App is almost ready to go. You will need to add some routes and let ufront know about them:
app = new UfrontApplication({
indexController: MySiteController,
});
app.executeRequest();
See the Getting Started tutorial for more information.


This toggles the character area between displaying ASCII and EBCDIC characters. This command is an old command that has been replaced by use of the character sets commands (Char Set ASCII, Char Set ANSI, Char Set IBM/OEM, and Char Set EBCDIC).
This command is not available if the character area is not displayed (see Character Display Toggle). EBCDIC control characters and invalid EBCDIC characters are displayed as red dots.
When EBCDIC mode is on the Control Characters Toggle and the Graphic Characters Toggle are not available.
This command also affects how string searches are performed (see Find Tool) and how text is copied to the clipboard (see Copy command). HexEdit will also tell you if you try to type an invalid EBCDIC character into the character area.
Shortcuts
Toolbar:


Currency Exchange!
Enter the amount of USD you'd like to convert:
Select a foreign currency:
Canadian Dollar
Great Britain Pound Sterling
Indian Rupee
Jamaican Dollar
Mexican Peso
Get Currency Conversion!


{{.ErrorPlaceHolder}}
<< Show Bare
My website
Sample Website
Show Blog >>
home
contact
Some other page (leaving the master page)
Terms
of Use
Privacy
Policy
About


function GetTransformedBounds: TRect; override;
Returns the bounding rectangle that surrounds the destination area affected by the transformation. The coordinates of the rectangle are specified relative to the destination bitmap origin.
[See also]:


A User’s Guide to OpenBCI
This tutorial covers all the steps from the initial set-up to the completion of a BCI (brain-computer interface) project. Working with OpenBCI’s software is easy and setup can be completed in under half an hour, making it accessible to anyone interested in exploring the brain. At the same time, because OpenBCI is open-source, it provides programmers and experts with all the flexibility needed to create a great project.
Contents
- What does it do?
- Why it works
- The setup: software
- Getting it to work
- What am I looking at?
- The setup: hardware
- Testing things out
- Better recording
- Putting it all together
What does it do?
Electrical activity is the stuff of thought. Whenever a person thinks, there’s a corresponding pattern of electricity in their brain. Different patterns of thought lead to different patterns of electrical activity. The faint echo of this activity is even measurable on the surface of a person’s head. This is where OpenBCI comes in.
A brain’s electrical activity can be measured by OpenBCI’s electrodes. OpenBCI’s software then makes sense of the information being collected by the electrodes. It’s that simple. OpenBCI is a mind-reader, taking thoughts and translating them into a form that computers can understand.
Why it works
OpenBCI isn’t the only tool to translate thoughts. Other systems like NeuroSky, Emotiv, and Muse are fun to play around with, but aren’t able to capture the same level of detail as clinical and scientific BCI systems. These clinical and scientific systems have the best possible level of detail, but are unaffordable for the average user.
OpenBCI captures almost as much detail as the professional systems while being as cheap as the normal setups. Also, because all of its software is open-source, there exists a large community of hobbyists on the internet sharing ideas and working together. This lowers the barrier of entry significantly, allowing almost anyone to get started with OpenBCI.
The set-up: software
Go to the Downloads Page to find the latest version of the software that’s compatible with your operating system.
More specific installation information can be found on the OpenBCI Docs Page.
Getting it to work
- Make sure that the system running OpenBCI has a Java Runtime Environment installed. This is a program that runs Java applications. You can do this by visiting the Oracle website or in Linux with the terminal command sudo apt-get install default-jre.
- Run the OpenBCI application with administrator privileges, as this program needs to have access to your computer’s serial port. This can be done with the Linux command cd ~/application.linux64 && sudo bash OpenBCI_GUI.
- Navigate to the top of the GUI (graphical user interface). Under “Data Sources" select “SYNTHETIC (algorithmic)". This runs the display with dummy-data.
What am I looking at?
In the EEG window are eight channels (labeled in colored boxes to their left), one for each electrode. Later a jagged line will appear in each channel.The shape of the line represents activity: on the x-axis is time and on the y-axis is level of activation. Spikes mean that more action has been recorded from that electrode at a given time, and troughs mean that less activity has been recorded.
The setup: hardware
The activity in each channel is just dummy information. After all, the hardware isn’t even set up yet. However, after following the next few steps the electrodes will be able to record electrical activity:
- 1. Plug the bluetooth dongle into a USB port in your computer.
- 2. Plug the battery pack and each electrode into its corresponding port on the OpenBCI board. Make sure that the board’s switch is set to “PC".
- 3. Close the OpenBCI application. Open it again, with administrator privileges.
- 4. Select “LIVE (from OpenBCI)" from the “Data Sources" tab.
- 5. Navigate to “WRITE TO SD (Y/N)" and select “Do not write to SD".
To see activity being recorded from the electrodes, click “Start System" and then “Start Data Stream".
Testing things out
Place one of the electrodes firmly against the skin of your wrist as pictured below. Secure with tape if necessary.
You should notice the activity in the electrode’s channel changing as it touches the surface of your skin (picture below). This is because the electrode is recording electrocardiographic (EKG) information--the electrical activity of your heartbeat. The activity will not, however, look like an EKG in a doctor’s office. This is because a grounding electrode and conductive paste are necessary for both successful EKG and BCI.
Better recording
Each of the eight electrodes is color coded [see here ]. To measure EKG, you’ll need two of these: electrode 1 and SRB.
Make sure that both electrodes are firmly connected to their respective locations on the OpenBCI board.
Locate the “10-20 paste" and apply this to the bottom surface of both electrodes. This allows a greater area of contact to be made between the electrode and your skin, further increasing the fidelity of the recordings.
Place your gray-colored recording electrode (electrode 1) on your wrist as before. Place the second white-colored SRB electrode on another part of your arm--the precise location does not matter. If needed, secure these electrodes with tape or a strip of cloth.
Now you should notice on your OpenBCI GUI that channel 1 is producing regular spikes, corresponding to your heartbeat. The pattern of electrical activity that your heart produces is much more consistent than the activity produced by your brain.
Putting it all together
To produce BCI recordings, which involve placing electrodes directly onto the scalp, it’s necessary to have a second person act as an assistant.
BCI uses the same logic as EKG, except with a different number of electrodes placed in different locations. There are many different ways to organize these electrodes on the scalp, and the particular orientation of electrodes will depend on the project you’re pursuing. However, there is a standard layout for an 8-electrode system, shown in the image below.
To begin your BCI recording, close the OpenBCI application. Insert all electrodes into their respective locations on the OpenBCI board. Then restart the application with the same settings as listed in the setup: hardware.
After applying paste to an electrode, part your assistant’s hair and place the electrode directly against their scalp. Repeat until all electrodes are in the locations listed on the electrode map above.
If you are worried about electrodes becoming loose, place the EEG cap over your assistant’s hair. Electrodes can be clamped into place by the pins in this cap. However, this cap is optional. BCI enthusiasts have used hats, shower caps, and beanies to secure their electrodes.
On the OpenBCI application’s GUI, you will now see the electrical activity being recorded by each electrode. This activity will appear to be much more random than the EKG activity.
Possibilities
Now that your system is set up, the possibilities are endless. OpenBCI can be used to control drones, play games, and in meditation. New uses for OpenBCI are being created every day. And because OpenBCI is open-source, it’s also possible to create new uses for yourself. Some of these applications can be found here.
When you install a new OpenBCI package, this will replace the standard OpenBCI GUI. After installing your new package, you will usually set up your electrodes in the same way as described above; however, some projects use slightly different arrangements.
OpenBCI is the world’s only fully open-source BCI system, allowing both amateurs and professionals to hack their brains. Thanks for your interest in OpenBCI.


Dear colleagues,
We are very happy to announce the fourth major public release (v1.0) of the astropy package, a core Python package for Astronomy:
Astropy is a community-driven Python package intended to contain much of the core functionality and common tools needed for astronomy and astrophysics.
New and improved major functionality in this release includes:
In addition, hundreds of smaller improvements and fixes have been made. An overview of the changes is provided at:
http://docs.astropy.org/en/stable/whatsnew/1.0.html
Astropy v1.0 is a special release that we are denoting a Long Term Support (LTS) release, which means that we will be supporting it with bug fixes for the next two years, rather than the usual six months. More information about this can be found at the link above.
Instructions for installing Astropy are provided on our website, and extensive documentation can be found at:
In particular, if you use the Anaconda Python Distribution, you can update to v1.0 with:
conda update astropy
Whereas if you usually use pip, you can do:
pip install astropy --upgrade
Please report any issues, or request new features via our GitHub repository:
https://github.com/astropy/astropy/issues
Over 122 developers have contributed code to Astropy so far, and you can find out more about the team behind Astropy here:
http://www.astropy.org/team.html
If you use Astropy directly for your work, or as a dependency to another package, please remember to include the following acknowledgment at the end of papers:
This research made use of Astropy, a community-developed core Python package for Astronomy (Astropy Collaboration, 2013).
where (Astropy Collaboration, 2013) is a citation to the Astropy Paper (ADS - BibTeX).
Please feel free to forward this announcement to anyone you think might be interested in this release.
We hope that you enjoy using Astropy as much as we enjoyed developing it!
Thomas Robitaille, Erik Tollerud, and Perry Greenfield
on behalf of The Astropy Collaboration


{% extends 'layout.html' %} {% block body %}
It looks like no account with that profile ID currently exists! Would you like to go back to the home page?


First Paragraph
Second Paragraph (SPECIAL)
Third Paragraph
Fourth Paragraph
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia, hic!


SIGNALFD
Section: Linux Programmer's Manual (2)
Updated: 2014-07-08
Index
Return to Main Contents
NAME
signalfd - create a file descriptor for accepting signals
SYNOPSIS
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t *mask, int flags);
DESCRIPTION
signalfd()
creates a file descriptor that can be used to accept signals
targeted at the caller.
This provides an alternative to the use of a signal handler or
sigwaitinfo(2),
and has the advantage that the file descriptor may be monitored by
select(2),
poll(2),
and
epoll(7).
The
mask
argument specifies the set of signals that the caller
wishes to accept via the file descriptor.
This argument is a signal set whose contents can be initialized
using the macros described in
sigsetops(3).
Normally, the set of signals to be received via the
file descriptor should be blocked using
sigprocmask(2),
to prevent the signals being handled according to their default
dispositions.
It is not possible to receive
SIGKILL
or
SIGSTOP
signals via a signalfd file descriptor;
these signals are silently ignored if specified in
mask.
If the
fd
argument is -1,
then the call creates a new file descriptor and associates the
signal set specified in
mask
with that descriptor.
If
fd
is not -1,
then it must specify a valid existing signalfd file descriptor, and
mask
is used to replace the signal set associated with that descriptor.
Starting with Linux 2.6.27, the following values may be bitwise ORed in
flags
to change the behavior of
signalfd():
- SFD_NONBLOCK
-
Set the
O_NONBLOCK
file status flag on the new open file description.
Using this flag saves extra calls to
fcntl(2)
to achieve the same result.
- SFD_CLOEXEC
-
Set the close-on-exec
(FD_CLOEXEC)
flag on the new file descriptor.
See the description of the
O_CLOEXEC
flag in
open(2)
for reasons why this may be useful.
In Linux up to version 2.6.26, the
flags
argument is unused, and must be specified as zero.
signalfd()
returns a file descriptor that supports the following operations:
- read(2)
-
If one or more of the signals specified in
mask
is pending for the process, then the buffer supplied to
read(2)
is used to return one or more
signalfd_siginfo
structures (see below) that describe the signals.
The
read(2)
returns information for as many signals as are pending and will
fit in the supplied buffer.
The buffer must be at least
sizeof(struct signalfd_siginfo)
bytes.
The return value of the
read(2)
is the total number of bytes read.
-
As a consequence of the
read(2),
the signals are consumed,
so that they are no longer pending for the process
(i.e., will not be caught by signal handlers,
and cannot be accepted using
sigwaitinfo(2)).
-
If none of the signals in
mask
is pending for the process, then the
read(2)
either blocks until one of the signals in
mask
is generated for the process,
or fails with the error
EAGAIN
if the file descriptor has been made nonblocking.
- poll(2), select(2) (and similar)
-
The file descriptor is readable
(the
select(2)
readfds
argument; the
poll(2)
POLLIN
flag)
if one or more of the signals in
mask
is pending for the process.
-
The signalfd file descriptor also supports the other file-descriptor
multiplexing APIs:
pselect(2),
ppoll(2),
and
epoll(7).
- close(2)
-
When the file descriptor is no longer required it should be closed.
When all file descriptors associated with the same signalfd object
have been closed, the resources for object are freed by the kernel.
The signalfd_siginfo structure
The format of the
signalfd_siginfo
structure(s) returned by
read(2)s
from a signalfd file descriptor is as follows:
struct signalfd_siginfo {
uint32_t ssi_signo; /* Signal number */
int32_t ssi_errno; /* Error number (unused) */
int32_t ssi_code; /* Signal code */
uint32_t ssi_pid; /* PID of sender */
uint32_t ssi_uid; /* Real UID of sender */
int32_t ssi_fd; /* File descriptor (SIGIO) */
uint32_t ssi_tid; /* Kernel timer ID (POSIX timers)
uint32_t ssi_band; /* Band event (SIGIO) */
uint32_t ssi_overrun; /* POSIX timer overrun count */
uint32_t ssi_trapno; /* Trap number that caused signal */
int32_t ssi_status; /* Exit status or signal (SIGCHLD) */
int32_t ssi_int; /* Integer sent by sigqueue(3) */
uint64_t ssi_ptr; /* Pointer sent by sigqueue(3) */
uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */
uint64_t ssi_stime; /* System CPU time consumed (SIGCHLD) */
uint64_t ssi_addr; /* Address that generated signal
(for hardware-generated signals) */
uint8_t pad[X]; /* Pad size to 128 bytes (allow for
additional fields in the future) */
};
Each of the fields in this structure
is analogous to the similarly named field in the
siginfo_t
structure.
The
siginfo_t
structure is described in
sigaction(2).
Not all fields in the returned
signalfd_siginfo
structure will be valid for a specific signal;
the set of valid fields can be determined from the value returned in the
ssi_code
field.
This field is the analog of the
siginfo_t
si_code
field; see
sigaction(2)
for details.
fork(2) semantics
After a
fork(2),
the child inherits a copy of the signalfd file descriptor.
A
read(2)
from the file descriptor in the child will return information
about signals queued to the child.
execve(2) semantics
Just like any other file descriptor,
a signalfd file descriptor remains open across an
execve(2),
unless it has been marked for close-on-exec (see
fcntl(2)).
Any signals that were available for reading before the
execve(2)
remain available to the newly loaded program.
(This is analogous to traditional signal semantics,
where a blocked signal that is pending remains pending across an
execve(2).)
Thread semantics
The semantics of signalfd file descriptors in a multithreaded program
mirror the standard semantics for signals.
In other words,
when a thread reads from a signalfd file descriptor,
it will read the signals that are directed to the thread
itself and the signals that are directed to the process
(i.e., the entire thread group).
(A thread will not be able to read signals that are directed
to other threads in the process.)
RETURN VALUE
On success,
signalfd()
returns a signalfd file descriptor;
this is either a new file descriptor (if
fd
was -1), or
fd
if
fd
was a valid signalfd file descriptor.
On error, -1 is returned and
errno
is set to indicate the error.
ERRORS
- EBADF
-
The
fd
file descriptor is not a valid file descriptor.
- EINVAL
-
fd
is not a valid signalfd file descriptor.
- EINVAL
-
flags
is invalid;
or, in Linux 2.6.26 or earlier,
flags
is nonzero.
- EMFILE
-
The per-process limit of open file descriptors has been reached.
- ENFILE
-
The system-wide limit on the total number of open files has been
reached.
- ENODEV
-
Could not mount (internal) anonymous inode device.
- ENOMEM
-
There was insufficient memory to create a new signalfd file descriptor.
VERSIONS
signalfd()
is available on Linux since kernel 2.6.22.
Working support is provided in glibc since version 2.8.
The
signalfd4()
system call (see NOTES) is available on Linux since kernel 2.6.27.
CONFORMING TO
signalfd()
and
signalfd4()
are Linux-specific.
NOTES
A process can create multiple signalfd file descriptors.
This makes it possible to accept different signals
on different file descriptors.
(This may be useful if monitoring the file descriptors using
select(2),
poll(2),
or
epoll(7):
the arrival of different signals will make different descriptors ready.)
If a signal appears in the
mask
of more than one of the file descriptors, then occurrences
of that signal can be read (once) from any one of the descriptors.
C library/kernel ABI differences
The underlying Linux system call requires an additional argument,
size_t sizemask,
which specifies the size of the
mask
argument.
The glibc
signalfd()
wrapper function does not include this argument,
since it provides the required value for the underlying system call.
There are two underlying Linux system calls:
signalfd()
and the more recent
signalfd4().
The former system call does not implement a
flags
argument.
The latter system call implements the
flags
values described above.
Starting with glibc 2.9, the
signalfd()
wrapper function will use
signalfd4()
where it is available.
BUGS
In kernels before 2.6.25, the
ssi_ptr
and
ssi_int
fields are not filled in with the data accompanying a signal sent by
sigqueue(3).
EXAMPLE
The program below accepts the signals
SIGINT
and
SIGQUIT
via a signalfd file descriptor.
The program terminates after accepting a
SIGQUIT
signal.
The following shell session demonstrates the use of the program:
$ ./signalfd_demo
^C # Control-C generates SIGINT
Got SIGINT
^C
Got SIGINT
^\ # Control-\ generates SIGQUIT
Got SIGQUIT
$
Program source
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
/* Block signals so that they aren't handled
according to their default dispositions */
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
handle_error("sigprocmask");
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
handle_error("signalfd");
for (;;) {
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
handle_error("read");
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINT\n");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUIT\n");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signal\n");
}
}
}
SEE ALSO
eventfd(2),
poll(2),
read(2),
select(2),
sigaction(2),
sigprocmask(2),
sigwaitinfo(2),
timerfd_create(2),
sigsetops(3),
sigwait(3),
epoll(7),
signal(7)
Index
- NAME
-
- SYNOPSIS
-
- DESCRIPTION
-
- The signalfd_siginfo structure
-
- fork(2) semantics
-
- execve(2) semantics
-
- Thread semantics
-
- RETURN VALUE
-
- ERRORS
-
- VERSIONS
-
- CONFORMING TO
-
- NOTES
-
- C library/kernel ABI differences
-
- BUGS
-
- EXAMPLE
-
- Program source
-
- SEE ALSO
-
This document was created by
man2html,
using the manual pages.
Time: 02:54:45 GMT, September 18, 2014


Data Analyst (6256U) 1737 - 1737 - Berkeley, CA 94720
Data Analyst (6256U) 1737 - 1737 About Berkeley
The University of California, Berkeley, is one of the world's most iconic teaching and research institutions. Since 1868, Berkeley has fueled a perpetual renaissance, generating unparalleled intellectual, economic and social value in California, the United States and the world. Berkeley's culture of openness, freedom and acceptance—academic and artistic, political and cultural—make it a very special place for students, faculty and staff.
Berkeley is committed to hiring and developing staff who want to work in a high performing culture that supports the outstanding work of our faculty and students. In deciding whether to apply for a staff position at Berkeley, candidates are strongly encouraged to consider the alignment of the Berkeley Workplace Culture with their potential for success at http://jobs.berkeley.edu/why-berkeley.html .
Application Review Date
The First Review Date for this job is: October 7, 2019
Departmental Overview
The Center for Healthcare Organizational and Innovation Research (CHOIR) is a research center within the Division of Health Policy and Management in the School of Public Health. CHOIR conducts studies of the organization and delivery of health services in order to improve the effectiveness of care and, ultimately, accountability for population health. Its studies emphasize innovations in health care delivery and assessment of organizational performance to improve the technical quality of care delivered, patient experience and outcomes of care, population health, and cost.
This position involves gathering, analyzing, and interpreting a wide variety of health services research data to support CHOIR's research studies, including managing database processes, selecting data samples, preparing questionnaires, and analyzing collected information according to established statistical methods using SAS or STATA statistical software packages . Prepares reports, charts, tables, and other visual aids.
Responsibilities
Under the direction of PI/PD, manages, manipulates, and analyzes research data for the purpose of identifying and reporting trends for internal review, and prepares reports of results for publications of large, complex studies.
Participates in the design of survey instruments and determining the data management and reporting procedures.
Collaborates on the design, documentation, testing and implementation of research studies. Prepares reports and/or analysis for internal department constituents.
Assists with implementation of business processes for CHOIR research projects. Maintains and develops research gathering, retrieval and reporting systems. Includes: coordinating with CHOIR and collaborating investigators and staff to implement and maintain business and administrative processes necessary for achieving specific study aims. Examples include, accounts payable and receivable reporting, and subcontract development.
Required Qualifications
Experience working with large datasets, including ability to manipulate and merge large and complex datasets, perform statistical analyses (using SAS and/or STATA statistical software), system programming, database design and data security measures.
Knowledge of research design and methods.
Proficiency with Microsoft Office suite, including Excel, Word, Access, and Powerpoint.
Familiarity with EndNote for bibliographic referencing.
Well organized and detail-oriented.
Ability to work independently with moderate direction or supervisory involvement.
Ability to relate well with other staff, take initiative and become an integral member of the research team.
High professional standards to ensure compliance with University and funding organization policies, and with ethical research standards.
Skills to communicate complex information in a clear and concise manner both verbally and written.
Education/Training:
Masters degree in Statistics, Economics, Public Health with Statistics or Epidemiology concentration, or related quantitative field and/or equivalent experience/training.
Salary & Benefits
For information on the comprehensive benefits package offered by the University visit:
http://ucnet.universityofcalifornia.edu/compensation-and-benefits/index.html


--- layout: post title: Nexenta Core Platform 2 released! date: 2009-05-25 18:22:13.000000000 +05:30 categories: - Nexenta - Opensolaris - tech - ubuntu tags: - Nexenta - Opensolaris - release status: publish type: post published: true meta: _edit_last: '1' author: login: admin email<EMAIL_ADDRESS>display_name: admin first_name: '' last_name: '' ---
I've been neglecting my blogging duties, but I'm back on track. Lots of things have happened in the recent times, but the big news today is the release of the Nexenta Core Platform 2. This release has been a year in the making, and took a lot of hard work.
We've also produced a short comic, with our very own hero, Nexentaman, to walk you through NCP. Click below to read the comic.
[caption id="" align="aligncenter" width="744" caption="The Adventures of Nexentaman"][/caption]
Links
Nexenta homepage: http://www.nexenta.org
Artwork and Wallpapers: http://www.nexenta.org/os/SpreadTheWord
IRC : #nexenta on freenode
Go ahead, test drive Nexenta, and spread the word


{% extends 'base.html' %} {% block title %}Settings{% endblock %} {% block content %}
You can change your preferred username and name here. Your preferred username will be used when you are composing and replying to threads.


Renting has become a long-term reality for many New Zealanders. In fact, approximately one third of all New Zealand households currently rent their home. However, our laws around renting have simply not kept up.
We're committed to making life better for renters. We need to make sure everyone's rights are protected, and everyone has the chance to feel at home.
The Residential Tenancies Act 1986 (RTA) is the main piece of legislation that regulates interactions between landlords and tenants.
Reforming the Residential Tenancies Act will ensure the rights of renters to a secure, healthy and decent place to call home.
Our reform focuses on three areas of the RTA: tenancy agreements, boarding house tenancies, and compliance arrangements.
We want to make sure renters are safe and secure in their homes, while protecting the rights and interests of landlords.
We're keeping up with the times, modernising the law so it can appropriately respond to changing trends and patterns in the housing and rental markets.
And we're promoting improved standards and accountability for boarding houses.
MBIE is currently consulting on a range of proposals, including limiting rent increases, and increasing the amount of notice a landlord must give before terminating a tenancy. Aswell as tenants no longer have to give 21 days notice when vacating and tenants paying smaller bonds.
Many renters wish to own pets, but landlords can say no to pets in all instances without needing to consider the nature of the pet or the condition of the property. We're considering whether this can be made fairer while also insuring that the law allows landlords to protect themselves against the additional wear and tear that some pets can cause.
We're also reviewing modifications tenants wish to make to their home. The law already allows tenants to make reasonable modifications to their home, e.g. install a shelf or hang pictures. It does this by specifying that landlords should not withhold their agreement for these things unreasonably. We want to check if this law is understood and working properly.
We know the vast majority of landlords operate with integrity and seek to provide decent accommodation at a reasonable rent. The reforms being considered are designed to stop exploitative behaviour by a minority of landlords.
We want to ensure that the RTA strikes a balance between protecting a landlord’s interest in their property and ensuring tenants receive fair rights for the rent they are paying. That's why we’re calling on everyone to have their say and to be part of the process. We want hear your views on how best we strike the balance between tenants and landlords.
Have your say - more info and a link to an online submission survey are available here.
Consultation runs for eight weeks and closes at 5pm, on Sunday 21 October 2018.
Sign up for the latest updates. Become part of the campaign:
Like this post? Share: