|
|
static const unsigned short | SUCCESS = 0x0000 |
| |
|
static const unsigned short | RAW_READ_IDS = 0x0012 |
| |
|
static const unsigned short | INVENTORY_TAG = 0x0013 |
| |
|
static const unsigned short | ADD_READ_TRIGGER = 0x003F |
| |
|
static const unsigned short | ADD_NOTIFY_TRIGGER = 0x0040 |
| |
|
static const unsigned short | REMOVE_READ_TRIGGER = 0x0041 |
| |
|
static const unsigned short | REMOVE_NOTIFY_TRIGGER = 0x0042 |
| |
|
static const unsigned short | ALLOCATE_TRIGGER = 0x0049 |
| |
|
static const unsigned short | DEALLOCATE_TRIGGER = 0x004A |
| |
|
static const unsigned short | ALLOCATE_CHANNEL = 0x0053 |
| |
|
static const unsigned short | DEALLOCATE_CHANNEL = 0x0054 |
| |
|
static const unsigned short | ADD_SOURCE_TO_CHANNEL = 0x005D |
| |
|
static const unsigned short | REMOVE_SOURCE_FROM_CHANNEL = 0x005E |
| |
|
static const unsigned short | ADD_READ_POINT_TO_SOURCE = 0x005F |
| |
|
static const unsigned short | REMOVE_READ_POINT_FROM_SOURCE = 0x0060 |
| |
|
static const unsigned short | SET_POWER = 0x0064 |
| |
|
static const unsigned short | ERROR = 0x0066 |
| |
|
static const unsigned short | READ_TAG_DATA = 0x006E |
| |
|
static const unsigned short | WRITE_TAG_DATA = 0x006F |
| |
|
static const unsigned short | LOCK_TAG = 0x0070 |
| |
|
static const unsigned short | SET_BIT_RATE = 0x0072 |
| |
|
static const unsigned short | GET_POWER = 0x0073 |
| |
|
static const unsigned short | SET_PROTOCOL = 0x0074 |
| |
|
static const unsigned short | CHECK_READ_POINT_STATUS = 0x0076 |
| |
|
static const unsigned short | CHECK_SOURCE_IN_CHANNEL = 0x0077 |
| |
|
static const unsigned short | CHECK_READ_POINT_IN_SOURCE = 0x0078 |
| |
|
static const unsigned short | GET_PROTOCOL = 0x0079 |
| |
|
static const unsigned short | SET_NETWORK = 0x007A |
| |
|
static const unsigned short | SET_DESB = 0x007B |
| |
|
static const unsigned short | GET_FIRMWARE_RELEASE = 0x007C |
| |
|
static const unsigned short | GET_DESB = 0x007D |
| |
|
static const unsigned short | PROGRAM_ID = 0x007E |
| |
|
static const unsigned short | KILL_TAG = 0x007F |
| |
|
static const unsigned short | RF_ON_OFF = 0x0080 |
| |
|
static const unsigned short | GET_BIT_RATE = 0x0081 |
| |
|
static const unsigned short | BLOCK_WRITE_TAG = 0x0082 |
| |
|
static const unsigned short | SET_RS232 = 0x0083 |
| |
|
static const unsigned short | SET_DATE_TIME = 0x0084 |
| |
|
static const unsigned short | GROUP_SELECT_UNSELECT = 0x0085 |
| |
|
static const unsigned short | GET_IO = 0x0086 |
| |
|
static const unsigned short | SET_IO = 0x0087 |
| |
|
static const unsigned short | SET_IO_DIRECTION = 0x0088 |
| |
|
static const unsigned short | GET_IO_DIRECTION = 0x0089 |
| |
|
static const unsigned short | SET_SOURCE_CONFIG = 0x008A |
| |
|
static const unsigned short | GET_SOURCE_CONFIG = 0x008B |
| |
|
static const unsigned short | GET_TRIGGERS = 0x008C |
| |
|
static const unsigned short | GET_CHANNELS = 0x008D |
| |
|
static const unsigned short | CHECK_SOURCE_IN_TRIGGER = 0x008E |
| |
|
static const unsigned short | CHECK_TRIGGER_IN_CHANNEL = 0x008F |
| |
|
static const unsigned short | CHECK_CHANNEL_IN_TRIGGER = 0x0090 |
| |
|
static const unsigned short | SET_EVENT_MODE = 0x0091 |
| |
|
static const unsigned short | GET_EVENT_MODE = 0x0092 |
| |
|
static const unsigned short | FIRMWARE_UPGRADE = 0x0093 |
| |
|
static const unsigned short | E119_PROGRAM_ID = 0x0094 |
| |
|
static const unsigned short | PROGRAM_ID_EPC_C1G2 = 0x0095 |
| |
|
static const unsigned short | READ_TAG_DATA_EPC_C1G2 = 0x0096 |
| |
|
static const unsigned short | WRITE_TAG_DATA_EPC_C1G2 = 0x0097 |
| |
|
static const unsigned short | LOCK_TAG_EPC_C1G2 = 0x0098 |
| |
|
static const unsigned short | KILL_TAG_EPC_C1G2 = 0x0099 |
| |
|
static const unsigned short | QUERY_EPC_C1G2 = 0x009A |
| |
|
static const unsigned short | SET_Q_EPC_C1G2 = 0x009B |
| |
|
static const unsigned short | GET_Q_EPC_C1G2 = 0x009C |
| |
|
static const unsigned short | QUERY_ACK_EPC_C1G2 = 0x009D |
| |
|
static const unsigned short | GET_READER_INFO = 0x009E |
| |
|
static const unsigned short | SET_LBT_MODE = 0x009F |
| |
|
static const unsigned short | GET_LBT_MODE = 0x00A0 |
| |
|
static const unsigned short | GET_RF_REGULATION = 0x00A2 |
| |
|
static const unsigned short | SET_RF_CHANNEL = 0x00A3 |
| |
|
static const unsigned short | GET_RF_CHANNEL = 0x00A4 |
| |
|
static const unsigned short | GET_BUFFERED_DATA = 0x00B0 |
| |
|
static const unsigned short | LOCK_BLOCK_PERMA_LOCK_EPC_C1G2 = 0x00B1 |
| |
|
static const unsigned short | READ_BLOCK_PERMA_LOCK_EPC_C1G2 = 0x00B2 |
| |
The RFIDCommandsCodes class is an auxiliary class created to simplify the work of the programmer.
The RFIDCommandsCodes class is an auxiliary class with all the AVP commands name that can be sent to the RFID reader.


HR Systems
Add Employee
Name
Email
Department
Call-Center
Information-Technology
Human-Resources
Name
Email
Department
Salary


Setting up OverDrive/Libby on your device
Looking to borrow eTitles in your browser? Visit the OverDrive website.
OverDrive/Libby allows you to download the latest children’s and adult eBooks and eAudiobooks for free. This service is available on a tablet, smartphone or web browser such as Chrome, Firefox, Opera, Safari or Internet Explorer.
You can also read eBooks and listen to eAudiobooks on a device that plays MP3 files, such as an iPod, tablet or smartphone using OverDrive’s app, Libby. OverDrive is additionally available on some eReaders.
Devices compatible with OverDrive and Libby
- Tablets: any that run in iOS 9.0 or later, Android 4.4 or later or Windows 10
- Smartphones: any that run in iOS 9.0 or later, Android 4.4 or later or Windows 10
- eReaders: Sony, Kobo, Nook, PocketBook Touch, Tolino Vision (but not Kindle eReaders)
Setting up OverDrive/Libby
On a smartphone or tablet with the Libby app
- Download and install the ‘Libby, by OverDrive’ app from the App Store, Google Play or Windows Store
- When the download is complete, press ‘Open’
- When the Libby app opens, press the green/blue button that says ‘Hi!’
- A new page will appear. Scroll to the end of the page and select ‘Find My Library’
- The app will then try and find your local library service – this takes a few moments. When the app has located a local library service it will ask you at the top of the screen ‘Is this your local library?’. At the bottom of the screen you will have an option to select ‘Yes’ or ‘No’
- If it has located Suffolk Libraries, press ‘Yes’. If it has located a different library service, press ‘No’
- If you have pressed ‘No’, a new screen will ask you if you want to search for your library service. Select this option
- Type in the box ‘Suffolk’
- The app will automatically bring up matching libraries. Select the first option shown, ‘Suffolk Libraries’. You now have access to the new Libby OverDrive app.
On an eReader
You will need a Kobo or Nook or other account, depending on which eReader you have.
- Plug your eReader into your computer
- Install the Adobe Digital Editions program on your computer
- Go to the OverDrive website and download an eBook to your PC. The file name will end ‘.acsm’
- Find the eBook you’ve downloaded on your computer
- Open the eBook in Adobe Digital Editions
- The first time you do this Adobe Digital Editions will prompt you to enter your Adobe account details. If you don’t have an Adobe account, follow the link to set one up
- Enter your Adobe account details
- Your eReader will appear under the ‘Device’ heading. Drag and drop your eBook to copy it on to your eReader
On a laptop or desktop PC
- Go to the OverDrive website and click the ‘Sign in’ link
- Enter your library card number and click ‘Sign in’
- Suffolk Libraries OverDrive service will now be available to use
Borrowing eBooks or eAudio books with OverDrive/Libby
On a smartphone or tablet with the Libby app
- Open the Libby app
- There will be a blue strip across the middle of the screen and on the right-hand side are the words ‘Add Your Card’. Press this. This will load a sign in screen
- Enter your library card number and then press the purple ‘SIGN IN’ button
- Select the eBook or eAudio book you want and press ‘Borrow’. If it is on loan to another borrower, you can reserve it by pressing ‘Place a hold’
- Another screen will load with a button that says ‘Borrow!’. Press this
- The item will then download and you will be given the option to ‘Keep Browsing’ or ‘Go to Shelf’. The first will take you back to the catalogue, the second will take you to the item you have selected and downloaded. Both eBooks and eAudio books will automatically expire in 3 weeks
- To renew or return the item, select the eBook/eAudio cover in the ‘Loans’ tab/screen. If you are on the main page you can access your loan page by pressing the word ‘Shelf’ at the bottom of the page.
- Select ‘Renew Loan’ or ‘Return Title to Library’ as appropriate
- From this page, you can return to the catalogue by pressing the ‘Library’ button at the bottom of the page.
Please note if you have additional cards linked to the app you will need to activate the card you want to use for borrowing before choosing an item and downloading:
- Press the words ‘2 Library Cards’, or however many you have linked to the app
- A tab will open on the right-hand side of the screen. Press the word ‘Activate’ next to the named card that card you want to use
- Follow the same borrowing instructions as above.
On an eReader
- Open OverDrive in a web browser and click the ‘Sign in’ link
- Sign in with your library card number
- Select the eBook you want and click ‘Borrow’. If it is on loan to another borrower, you can reserve it by clicking ‘Place a hold’
- The eBook will appear on your ‘Bookshelf’. Click the option to ‘Download (EPUB eBook)’
- Open Adobe Digital Editions
- Click on ‘File > Add to library’
- Open the eBook from your computer – this will end in ‘.acsm’
- Plug your eReader into your computer
- Drag your eBook from ‘Bookshelves > Borrowed’ in the sidebar to your eReader in the ‘Device’ menu
- The eBook will automatically expire in 3 weeks. You can renew it if no one else has reserved it, by clicking the ‘Renew’ button on the ‘Bookshelf’ page. Alternatively, return an eBook early by double clicking on the eBook you want to return, and select ‘Return Borrowed Item’
On a laptop or desktop PC
- Go to the OverDrive website and click the ‘Sign in’ link
- Find an eBook or eAudio book through the search bar or by browsing the categories
- Select the eBook or eAudio book you want and click ‘Borrow’, and then choose ‘Download (EPUB book)/(MP3 Audiobook)’ or ‘Read (in your browser)’. If it is on loan to another borrower, you can reserve it by clicking ‘Place a hold’. If you download a ‘WMA Audiobook’, you will not be able to listen to it on your tablet or smartphone.
- If you download an eAudio book, you will need to install OverDrive Media Console. The files will be ODM format
- Find the eAudio book files on your computer and open them in OverDrive Media Console
- Both eBooks and eAudio books will automatically expire in 3 weeks. You can renew it within 3 days of the expiration date if no one else has reserved it, by clicking the ‘Renew’ button on the ‘Bookshelf’ page
- You can view books you have previously borrowed by going to the ‘Bookshelf’ page and clicking History. Any titles you borrow after October 2017 will automatically be added to this list. Please see the OverDrive History instructions page for further information and instructions on using this feature.
Further instructions for Libby
Adding additional library cards
Libby allows you to link multiple library cards. This may be particularly helpful if you share the use of your device with another person.
- Open the Libby app
- If you have previously signed into Libby with your library card, this will automatically remain signed into the app. This can be seen on the right-hand side of the screen which will show the following: ‘1 Library Card’
- Press the words ‘1 Library Card’
- A tab will open on the right-hand side of the screen. Before linking additional library cards, name your original card so you can distinguish between them by pressing on the card shape and pressing the words ‘Change Name’. This will open a box that allows you to name the card
- Press the button at the top that says ‘Add Another Card’. This will load a sign in screen
- Enter the library card number and press the purple ‘SIGN IN’ button
- On the main page this will now show ‘2 Library Cards’. You can repeat this process to name and link additional library cards.
Unlinking library cards which have been added to your Libby app
- Press the words ‘2 Library Cards’
- A tab will on the right-hand side of the screen. Press the word ‘Activate’ next to the named card that card you want to remove
- Press the card shape which will flip the card over, and you will see the option in red to ‘Unlink Card’
- Press ‘Unlink Card’
- A box will appear asking you to confirm this, which will explain that any existing loans for this card will be removed along with the linked card. Press the red button ‘YES, UNLINK CARD’
- The card will be removed from your account
- Repeat as necessary.
If you decide to relink the library card later, the app will remember the name you previously gave the card.
Accessing your account information
If you have one library card registered in the app
- Open the Libby app
- Press the words ‘1 Library Card’
- A tab will open on the right-hand side of the screen. Press the card shape, which will flip the card over. You will see when the card was added, the allowance you have for loans/holds, how many loans you currently have and how many holds you have placed on items.
If you have multiple cards registered in the app
- Open the Libby app
- Press the words ‘2 Library Cards’, or however many you have linked to the app
- A tab will open on the right-hand side of the screen. Press the word ‘Activate’ next to the named card you want to review
- Press the card shape, which will flip the card over. You will see when the card was added, the allowance you have for loans/holds, how many loans you currently have and how many holds you have placed on items.


The report I am writing is explaining about my first time ever drinking a real amount of alcohol (all other times were simple sips). I was in the middle of high school when this experience happened, so I am probably quite a 'lightweight' to most of you guys. I have never touched tobacco or cannabis.
The last time I tried to drink alcohol, all of my friends got really drunk, and I was busy dealing with them. By the end of the night, I never got a chance to drink. I sure learned a lot that night though, mainly that you need to be careful about how much alcohol someone around you consumes (two of my friends probably got alcohol poisoning that night).
So for my first time, I was careful to make sure the enviroment around me was safe and easy to interact with. I knew that I was going to use the computer and my Xbox, so I made sure both were up and running before I would consume any alcohol. My mom was going to bed early due to work she had the next day, and so I designed my preparations around not waking her up mainly. At the time of writing this, I can be pretty proud about the preparations I took, and it led to no complications. Planning ahead definitely has its benefits.
I had my 'plan' all thought out days before, and it was only a couple of hours before I would start drinking. All I needed to do was wait for my mom to go to bed, and I would be off drinking. However, I had one problem with a cold that I had for quite a long time. I started coughing a lot, so decided I needed to take some sort of cough medicine. I had Dayquil and Nyquil, and at the time it was 9:30 pm. I knew I'd be up till around 3 am, but for some reason I thought that Dayquil would keep me up all night. I knew that Nyquil is a powerful drug, and it will combine with the alcohol to do some negative effects, but I chose to take it anyway. It was in my stomach for around one and a half hours before I started to drink, and I was starting to get really tired. This effect eventually went away. I think Nyquil might have had a big effect on my body that night, but I am no expert, so I don't know for sure.
Right before my mom went to bed, I actually had a lengthy conversation with my mom about alcohol, and I eventually realized I didn't need to be so secretive about it. I still decided to stick with the plan of her not knowing, but now I know if I get caught it won't be as big of a deal. My mom went to bed, I waited about 20 minutes, and then the 'show' began.
The first thing I decided to drink was all of the whiskey I had on me, and I mixed it into orange juice. I honestly think I didn't have enough to even get a 'buzz,' so I chugged the whole orange juice/whiskey combo while holding my nose. It was 11:00 pm when I did this. I played one game of Halo 2 online that lasted around 10 minutes, and then I went down stairs to chat on my computer. It was after about 2 minutes of chatting that the effects really hit me, I mean, I never expected the effects to hit me so fast like that. I drank this strong old red wine that my mom had, and then I went back upstairs.
I was totally new to alcohol, so the effects surprised me. The world around me wasn't a blur at all like I thought it would be, but I felt really dizzy. The only way I could compare it to is when you are one of those spinning rides in a theme park, and you can feel the G-forces weighing down on your body. The only difference was that I could move my body much more, and the feeling didn't make me feel bad at all. I had fun just moving my head side to side, because it just felt cool moving my head. I also noticed that walking felt really weird, I kept stumbling and had to keep holding onto walls in order to walk. Tastes in my mouth also felt really numb, and I fear that most people that are drunk can start drinking a lot of hard alcohol without feeling the taste.
I knew I needed to try out the 'social' aspects of drinking, so I started talking to my friends on Xbox Live while playing Halo 2. I am usually pretty timid, but I noticed that I kept talking almost nonstop. I knew it was also the typical slurred speech you get from drunks, and I kept trying to make my speech intelligent, but I always failed.  I could see that my inhibitions were lowered, and it didn't really bother me at all.
At around 2 am, I knew I was coming down. One of the odd things about alcohol is that the effects come in waves, in which I feel the effects greatly, and then it goes down to an almost sober feeling, and then back up again. I was in a continued state of feeling the lower 'sober' feeling, so I knew that I was coming down. It was at this point that I recognized the true danger of alcohol. I felt very tempted to go and drink more in order to get the higher 'feeling' that I had, but I knew I shouldn't. The next day, I felt like getting drunk again, and that really scared me. I had no hangover though. I can see why this is a drug that requires A LOT of respect, because it is so easy to abuse.
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.


Learn to model, design, build, and test RESTful web services with the latest ASP.NET Web API platform


Dear sir, I am pleased to introduce a business opportunity to you,to transfer to your overseas account,sum of,(US$10.500.000m)Ten million five hundred thousands United States Dollars) from one of the Prime Banks here in Dakar-Senegal,I urgently want to know soonest you,If you are not capable to handle and acomodate this magnitude of funds untill i resign and come over to join for an investment in your country,tell me so that i can quietly look for another reliable and honest individual/organisation that would be capable and fit enough to provide either an existing bank account or to set up a new Bank a/c immediately to receive this funds,even an empty a/c can serve to receive this funds,as long as you will remain honest to me till we actualise this interest,believing that you will never let me down either now or in future. I am Mr Mona Noah the Auditor General of one of the prime banks here in Dakar Senegal west Africa during the course of our auditing,I discovered a floating fund in an account opened in the our bank since 1982 and till date no body has operated on this account again,after going through some old files in the records I discovered that the owner of the account died long ago in a plane crash along with his family without leaving a[Heir/WILL] hence the funds is floating and if I do not remit this money out urgently it will be forfeited for nothing.The owner of this account is Khalifa T.Ibrahim a foreigner before his death,he was a management consultant and he died since 1992.No other person knows about this account or any thing concerning it, the account has no other beneficiary and my investigation proved to me as well that until his sudden death he was a management consultant. Since I hardly know any foreigner,I am only contacting you as a foreigner partner to stand and apply as his next of kin because this money can not be approved to a local person here as his next of kin,without valid international foreign passport,but can only be approved to any foreigner with valid international passport or drivers license and foreign a/c because the money is in US dollars and the former owner of the a/c is a foreigner too,and the money can only be approved into a foreign a/c. I need your full co-operation to make this work fine because the management is ready to approve this payment to any foreigner who has correct information of this account,which I will give to you upon your positive response and once I am convinced that you are capable and will meet up with instruction of a key bank official who is deeply involved with me in this business.I need your strong assurance that you will never,never let me down. With my influence and my position in the bank the bank official can transfer this money to any foreigner's reliable account that you can provide with assurance that this money will be intact pending on my physical arrival in your country for sharing. The bank official Will destroy all documents of transaction immediately we receive this money leaving no trace to any place and to build confidence you can call me for heart to heart discussion through my private satellite phone which I secured for the security and safety of this business as you know that this business is confidential. At the conclusion of this business,you will be given 35% of the total amount,60% will be for me, while 5% will be for expenses both parties might have incurred during the process of transferring. I look forward to your earliest reply through my email address. you can contact me with<EMAIL_ADDRESS>Yours truly, Mr Mona Noah. _________________________________________________________________ Add photos to your messages with MSN 8. Get 2 months FREE*. http://join.msn.com/?page=features/featuredemail


Altair + Vega + Justcharts = Interactive Visualisations in Static Websites
Despite being a huge proponent of using interactive plots when publishing data visualisations on the web, the plots on this blog are all static.
The problem with static site generators and interactive charts
Pandas, numpy, scikit-learn and seaborn are commonly used when playing around with data and have been used in all data-related posts on this blog before. However, while seaborn produces very nice images, with relatively little effort, there isn’t a straightforward way to add some interactivity to them. You could, once you have results you want to show, write additional code to export the data in a format compatible with a javascript charting library (like Chart.js). Apart from being extra work, this results into a second issue … How to include these in a blog generated using e.g. Jekyll? Markdown supports images, but adding charts usually requires specific html tags and a few custom lines of javascript, which should not be included in markdown files.
How to solve this in a nutshell
Altair, a Python package to create charts, solves the first problem. While working in a notebook, Altair behaves the same as seaborn, the plots show up when they need to. However, under the hood these plots are drawn using Vega, a javascript library. Altair also allows the plot-data to be exported as a JSON file that can be rendered on any website, as long as you include the required javascript.
Including the necessary javascript in a Markdown file to include these plots in a e.g. a Jekyll blog, is still an anti-pattern. This is where justcharts comes in. Once this library is loaded, a JSON file with a Vega plot can be included using a single line of HTML.
Using Altair to prepare the plot
This post isn’t supposed to be a comprehensive tutorial for Altair or Vega, so it is kept very simple. An example
dataset is loaded and shown as a scatter-plot, however by including the tooltip=
keyword additional information
is shown when hovering over nodes. The .interactive()
method allows basic panning and zooming, simple but
sufficient as a proof-of-concept.
import altair as alt
from vega_datasets import data
source = data.cars()
source.rename(columns={"Miles_per_Gallon":"Miles per Gallon"}, inplace=True)
chart = alt.Chart(source).mark_circle(size=60).encode(
x='Horsepower',
y='Miles per Gallon',
color='Origin',
tooltip=['Name', 'Origin', 'Horsepower', 'Miles per Gallon']
).interactive()
Altair’s API feels a little like a hybrid between seaborn and ggplot2, and it will require some getting used to when coming from another library. However, in a few lines of code we have a plot with tooltips and zooming/panning.
Finally, the chart can be written to disk as a JSON file compatible with Vega-Lite. Here,
.properties(width='container')
(which doesn’t work inside a Jupyter Notebook) is applied first to make sure
it will occupy the full width of the parent element once included in the website. This makes the plot responsive as
well in one go. Using .save()
everything is stored in the specified file.
chart.properties(width='container').save("cars.json")
Including everything in a Jekyll template
Fortunately, the Jekyll template used for this blog already supports adding additional js libraries to specific posts. So after copying all .js files to the correct directory they can be enabled for a specific post by including the few lines below in the header.
custom_js:
- vega.min
- vega-lite.min
- vega-embed.min
- justcharts
With these libraries loaded a <vegachart>
html tag, with the attribute schema-url
pointing to the JSON file
made using Altair, can be included in a post. It will magically be converted into a graph, no additonal code required.
Note that the custom style style="width: 100%"
is required when the width is set to container in the Vega JSON file.
<vegachart schema-url="{{ site.baseurl }}/assets/posts/2021-05-03-Interactive-Visualizations/cars.json" style="width: 100%"></vegachart>
The result is shown below. A pan-able, zoom-able chart with tooltips showing additional data for each point. A small, but significant improvement over a static image! Vega can do much, much more, so this can be pushed a further still .
Better integration with Markdown
While a few HTML tags in a markdown document in some cases cannot be avoided, there is a way to do this even better.
Using a Jekyll hook, we can create a custom plugin that scans for a pattern as shown below. This is a valid Markdown
syntax of an image, linking to another file. With the hook this is turned into the <vegachart>
tag. This way in case we ever need to use the markdown file in another project, where Vega is not available the page
will render the static image without issue and turn it into a link to the JSON data.
[![Number of cylinders vs different stats](/assets/posts/2021-05-03-Interactive-Visualizations/cars2.png)](/assets/posts/2021-05-03-Interactive-Visualizations/cars2.json)
This custom plugin will detect this and convert it into the required <vegachart>
tag. In case there is no plugin
it is perfectly valid Markdown and will show the PNG version of the image, which can be clicked to download the JSON
file.
Jekyll::Hooks.register :posts, :pre_render do |post, payload|
post.content.gsub!(/^\[!\[(.*)\]\(([^\)]+)\)\]\(([^\)]+)\)/, "<vegachart schema-url=\"{{ site.baseurl }}\\3\" style=\"width: 100%\"></vegachart>")
end
And to show this works, here is the car dataset but shown as box-plots comparing different features based on the number of cylinders. (Okay, I’m lying the previous plot also was included using this syntax)
Conclusion
Your mileage may vary as the creator of justcharts describes his own library as “very hacky” and me adding another layer onto it probably isn’t making it any better. Regardless of the hacky-ness, this provides an extremely elegant way to include interactive plots in a Jekyll template. The workflow as a whole is also smooth as data can be explored as before, with the exception Altair needs to be used instead of seaborn, exported and added with the same amount of code as before. It will take some work to get as proficient with Altair as I’m currently with seaborn, but the advantage of having interactive graphs in my blog is absolutely worth putting in a little effort.
Liked this post ? You can buy me a coffee


This is sample content
Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet.
This is sample content
Post-ironic keffiyeh bitters Banksy street art yr, ennui flexitarian organic bespoke lomo readymade. Schlitz single-origin coffee Wes Anderson XOXO, literally whatever cliche lo-fi deep v pug beard. Blog whatever banh mi wayfarers, tousled roof party try-hard gentrify aesthetic ennui 90's Bushwick. Master cleanse American Apparel PBR&B letterpress, mumblecore fingerstache tousled Thundercats hashtag Wes Anderson quinoa. Yr Brooklyn messenger bag scenester, wolf beard sustainable chia cred sriracha flannel Truffaut Tonx. Butcher 3 wolf moon Vice Banksy, gentrify sartorial XOXO farm-to-table PBR gastropub pop-up. YOLO plaid mustache small batch flannel chambray. Typewriter swag Marfa forage, biodiesel Cosby sweater pork belly McSweeney's fap kale chips ugh. Cornhole hoodie chambray Truffaut, you probably haven't heard of them next level flannel. Plaid cred cray, next level trust fund pork belly vegan gastropub Blue Bottle artisan. Before they sold out ugh stumptown, bitters wolf banjo YOLO forage direct trade Marfa kitsch try- hard mixtape vegan small batch. Truffaut artisan deep v pickled biodiesel, chambray synth pop-up bicycle rights squid gluten-free mlkshk Godard photo booth roof party. DIY bicycle rights Marfa actually, Blue Bottle normcore Pitchfork organic tofu authentic Austin ennui post-ironic. Synth gastropub church-key, small batch art party 3 wolf moon disrupt cornhole quinoa Thundercats biodiesel Williamsburg Schlitz.


04. Make All the Headers
Make All the Headers
Websites have different ways to show you, the user, what is important. Take for example…
Big Important Words!
This style of text Big Important Words! is called a header. This should look familiar because almost every website uses headers.
The New York Times mobile site uses them. Check out all of the images below. The heading has a red square around each heading.
Main Headings and Subheadings
It's also pretty common to see more than one kind of header being used. Here's an example of two headers on Medium.
TechCrunch using headers to show the titles of featured stories:
Let's experiment with headers in a real HTML document
How to Complete this Exercise
See look, I just used a header to help you figure out why this section is here :)
- Look at the Workspace on this page. You'll find
index.html
inside. - Edit
index.html
in the workspace and watch your website change in the preview panel.
Workspace
This section contains either a workspace (it can be a Jupyter Notebook workspace or an online code editor work space, etc.) and it cannot be automatically downloaded to be generated here. Please access the classroom with your account and manually download the workspace to your local machine. Note that for some courses, Udacity upload the workspace files onto https://github.com/udacity, so you may be able to download them there.
Workspace Information:
- Default file path:
- Workspace type: html-live
- Opened files (when workspace is loaded): n/a


Commonly used functions used by drivers. More...
#include "firmwareVersion.h"
Go to the source code of this file.
Macros | |
| #define | __COMMON_H_SENSOR_CHECK__ 1 |
| #define | MAX_ARR_SIZE 17 |
| #define | min2(a, b) (a < b ? a : b) |
| #define | min3(a, b, c) (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c) |
| #define | max2(a, b) (a > b ? a : b) |
| #define | max3(a, b, c) (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c) |
| #define | clip(a, b, c) min2(c, max2(b, a)) |
Typedefs | |
| typedef ubyte | tByteArray [MAX_ARR_SIZE] |
| typedef sbyte | tsByteArray [MAX_ARR_SIZE] |
| typedef ubyte | tMassiveArray [128] |
| typedef ubyte | tHugeByteArray [64] |
| typedef ubyte | tBigByteArray [32] |
| typedef ubyte | tIPaddr [4] |
| typedef int | tIntArray [MAX_ARR_SIZE] |
Functions | |
| void | clearI2CError (tSensors link, ubyte address) |
| bool | waitForI2CBus (tSensors link) |
| bool | writeI2C (tSensors link, tByteArray &request, tByteArray &reply, int replylen) |
| bool | writeI2C (tSensors link, tByteArray &request) |
| long | getUID () |
Commonly used functions used by drivers.
common.h provides a number of frequently used functions that are useful for writing drivers. License: You may use this code as you wish, provided you give credit where its due.

Changelog:


---
layout: post
type: post
status: publish
tags:
- console
- debug
- php
- Technical
meta:
_wpbitly: http://q.bibhas.in/Hq0hVA
_edit_last: "1"
published: true
title: PHP Console Inside Your Browser
---
I was looking for a tool where I can write a little snippet in PHP and test it out/debug really quickly. First thought of something like these online compilers, like IDEONE. But it's too heavy for my taste. I needed something faster. Yesterday, came across this blog post from Jordi Boggiano, who saved some work of mine(and lot of other developers) and made a tool that can run inside your browser, and let you run and debug PHP codes with ease, and it's also FAST.Here is a screenshot -
[caption id="" align="aligncenter" width="622" caption="PHP Console"][/caption]
Looks good, right? You can grab the tool from github and use it on your localhost or your personal server, wherever you want. :)


Tuesday, April 20, 2004
Dear Mike,
I am writing this e-mail to you as we are not quite sure just what to do. I don’t think that you should share this letter with anyone else at this time. I will try to explain what we know and have pieced together and maybe even configured within our own minds, then ask you to think about it and pray about it, and then advise us.
During the past few weeks we have got information or hints of information, some from Jeff, in a vague way and some from Gale and some from other comments made from others. These have quite upset us as to just what is happening, to the point that your mother is in tears very often and very upset, we are both concerned. We have even wondered if we need to return home to see for our self what is happening. As you might know, that while Mom’s Uncle Van and Aunt Allison were on there mission, their one son left the church and severed all family relationship. They were heart broken, as you can imagine. I think this memory is adding to your mothers worries.
Anyway, let me try to tell you what we have learned.  He is trying to tell Gale that he loves her but he can’t get himself to believe it. We think that he has never forgotten his feelings for Nicky and is possibility even blaming the Lord that he gave two years to serve and during that time lost Nicky. What ever his concerns are, they are affecting his schooling, and he is having a lot of depression. Gale, again through private e-mails, has indicated that, though their love is growing deeper, she is very concerned about Jeff. She said that Jeff is having problems with depression; also she feels that he is having problems with his testimony. Jeff will pray and have scripture study with her, but is not doing these on his own. He doesn’t want to attend the Temple and he is studding some books that question the church, at school. She said that Jeff has talked to David and he, David, is also having some of the same feelings about the church. Gale indicated that she feels that Jeff is questioning his testimony at to the Church being true.
Mike, my feelings are that my first responsibility is to my wife and my second is to my family. At this point I am not sure just what to do, but if I am needed at home, then that is where I will be. Will you please assess the situation and give me some feedback? Our concerns for Sandi have been hard to know just how to help, but this may even be more serious.
We love and appreciate all you do for us,
Dad


--- layout: base ---
Cache stores are part of the core Infinispan distribution and therefore are developed and released in-sync with Infinispan itself. Most of these cache stores are included in the infinispan-embedded JAR. Those which require additional dependencies are available in separate artifacts.
Hot Rod is a wire protocol that Infinispan clients use to talk to a remote grid. It is a binary, platform-independent protocol that was developed in the open as a part of Infinispan.
This Is a short description of the feature to give the user an idea of how Infinispan helps them with their data management.


Blackhawks-Penguins Sums
by EndPlayFirst Period_None. Penalties_Kane, CHI, (hooking), 19:24.
Second Period_1, Chicago, Kubalik 4 (Saad, Koekkoek), 7:09. 2, Chicago, Kane 6 (de Haan), 8:47. 3, Pittsburgh, Guentzel 8 (Malkin, McCann), 16:04. Penalties_Johnson, PIT, (tripping), 3:38; Tanev, PIT, (boarding), 4:04; Carpenter, CHI, (slashing), 11:51.
Third Period_4, Pittsburgh, Rust 5 (Marino, Malkin), 10:57. Penalties_Strome, CHI, (tripping), 5:43.
Overtime_None. Penalties_None.
Shootout_Chicago 1 (Toews NG, Kane G, DeBrincat NG), Pittsburgh 2 (Guentzel G, Malkin NG, McCann G).
Shots on Goal_Chicago 8-13-8-2_31. Pittsburgh 7-12-7-5_31.
Power-play opportunities_Chicago 0 of 2; Pittsburgh 0 of 3.
Goalies_Chicago, Crawford 2-4-2 (31 shots-29 saves). Pittsburgh, Murray 9-3-1 (31-29).
A_18,653 (18,387). T_2:36.
Referees_Kevin Pollock, Graham Skilliter. Linesmen_Darren Gibbs, Brad Kovachik.


Hi
I got an issue with Emonhub in the past days.
I have got a RPI+HDD running Emonhub + EmonCMS (V8.1.2, apt version)
Emonhub is forwarding data to the local EmonCMS server and to a remote server (Emoncms.org)
Firstly, data in both emoncms servers were being updated at a very low rate (every 100-200 seconds instead of every tens seconds). 12 hours later, I got no more update in both EmonCMS server. Everything is back to work now after having restarted the emonhub service. See attached graph. It's a power feed which is created in emoncms from a Wh feed sent by emonhub.
It seems to be a problem coming from the local emoncms that replied "sent!ok" to emonhub.
Please find attached the emonhub log file saved just before restarting the emonhub service.
Eric
EDIT : I just see a strange line at the end of the log file. It's the last line before emonhub stopped forwarding data :
2014-07-28 22:48:01,653 WARNING Discarded RX frame 'non-numerical content' : ['3', '146', '0', '124', '250', '36', '0', '250', '255', '', '1', '184', '1', '0', '0', '205', '1', '0', '0', '73', '100', '0', '0']
Re: Emonhub failure
Hi Eric
Sorry to hear you've had a problem, I've had a look at the files and see the last line you refer to, the line previous to that is
2014-07-28 22:48:01,651 INFO NEW FRAME : 3 146 0 124 250 36 0 250 255 1 184 1 0 0 205 1 0 0 73 100 0 0
Which shows in the frame received from node 3, the 9th byte has been omited, why? I couldn't say but the "NEW FRAME" log is prior to any emonHub processing and is for showing the frame in it's original form, so it is probable the frame was received by emonHub that way. This is just one frame and it's occured sometime after the main issue so I wouldn't be concerned about it just yet.
The last good localhost receipt and first occurrence of the rogue "sent!ok" in your logs was at 18:42 on the 28th
2014-07-28 18:42:23,184 DEBUG Receipt acknowledged with 'ok' from http://localhost/emoncms
2014-07-28 18:42:44,592 WARNING Send failure: wanted 'ok' but got Message sent!ok
at this time the updates would of dropped significantly as emonHub would of been stuck trying to deliver the frame for a while then looped again, reading a single frame and getting stuck. so with 5 nodes each of these would get read every 5 post attempts - so very slow for both servers
its not clear when the actual first occurrence was, the post body belonging to the first occurrence in your logs contains 100 frames which is a batch limit set in emonhub so from that I can only tell there were at least 100 frames undelivered at that point in time.
This particular situation should not occur with newer revisions of emonhub as threading is implemented so emonHub is no longer at the mercy of each target server being contactable and able to respond correctly. This does not explain why it stopped reporting all together though and unfortunately your logs do not extend into the period of no updates.
When emonHub was restarted all the buffers were cleared so normal intervals resumed, did you restart emoncms or just emonhub?
I really don't know how or why the acknowledgement message would change without outside influence, this would appear to be the cause.
Did the data slow and top at the same times on each server or did the emoncms.org server continue to log data at a slow rate beyond the last update on the local server? if they are the same then the local emoncms was being updated and the "incorrect" response of "sent! ok" could be catered for in emonhub by expecting the response to "contain" ok rather than "be equal to" ok, but that seems like a work around rather than a fix.
Paul
Re: Emonhub failure
PS another concern is the actual value reported, your graph shows a significant drop in power across the slow updates period. the wh accumulator is designed to avoid this, so that should also be looked into also as a network outage or sketchy network connection could present data the same way.
Paul
Re: Emonhub failure
Hi Paul,
Thank for being always ready !
This does not explain why it stopped reporting all together though and unfortunately your logs do not extend into the period of no updates.
>> I got no logs during the period with no updates. The next lines in my emonhub.log file are about the emonhub restart that I did on the 30th of july
When emonHub was restarted all the buffers were cleared so normal intervals resumed, did you restart emoncms or just emonhub?
>> I just restarted the emonhub service. I did nothing on the local emoncms. Since I have restarted emonhub, there is no more "sent!ok" message in the logs.
Did the data slow and top at the same times on each server or did the emoncms.org server continue to log data at a slow rate beyond the last update on the local server?
>> Please find a graph to understand what happened on both server. It's the same feed which represents the total number of kWh elapsed. (There is an offset but don't look at it). The node 4 sends the Wh elapsed every ten seconds and then the total number of kWh elapsed is calculated in emoncms with a accumulator process.
One can see that during the slow update period, the total number of kWh was increasing at a slow rateonemoncms.org. That's ok. But during that period, the total number of kWh increased at an abnormal rate (4-5 times more that expected). IT looks like data were posted several times.
Hope this help to understand what happened.
Eric
Re: Emonhub failure
Okay, so the graphs clearly show the data was being delivered to the local emoncms, therefore had the unexplained "sent!ok" confirmation been sent or accepted as "ok" then emonhub would of deleted the sent data from the buffer and moved on, issue 1 is where or why did the message change?
and the repeated posting caused the wh accumulators to continue accumulating, which led to exaggerated totals I don't think that should happen so that's another issue.
It sounds like emonHub just stopped after a while, maybe it crashed what size are your buffers? did you have your stats php running? could it of been a RAM shortage?
I think we need to look at the confirmation process, emonhub has changed alot over the last couple of months, can you post the confirmation code from emonhub_dispatcher.py so we know exactly what you have? the current version has
reply = self._send_post(post_url, post_body)
if reply == 'ok':
self._log.debug("Receipt acknowledged with '" + reply + "' from " + self._settings['url'])
return True
else:
self._log.warning("Send failure: wanted 'ok' but got "+reply)
When the confirmation is "ok" returning "True" tells emonHub it's ok to delete the sent data from the buffer, the _send_post() code is
def _send_post(self, post_url, post_body=None):
reply = ""
request = urllib2.Request(post_url, post_body)
try:
response = urllib2.urlopen(request, timeout=60)
except urllib2.HTTPError as e:
self._log.warning("Couldn't send to server, HTTPError: " +
str(e.code))
except urllib2.URLError as e:
self._log.warning("Couldn't send to server, URLError: " +
str(e.reason))
except httplib.HTTPException:
self._log.warning("Couldn't send to server, HTTPException")
except Exception:
import traceback
self._log.warning("Couldn't send to server, Exception: " +
traceback.format_exc())
else:
reply = response.read()
finally:
return reply
Trying to track the origin, I have searched the python modules for "sent!ok" and not found it, nor is it in emonhub or emoncms. I did however find the only occurrences of "sent!" with an exclamation mark are in emoncms locale files "Message successfully sent! and user module "Password recovery email sent!" did you change local or reset password in emoncms recently? Even if you did this doesn't explain how the 2 could get lumped together though.
Re: Emonhub failure
I didn't modify the default configuration : bufferMethod = memory and bufferSize = 1000.
Regarding the RPI's stat, I was only logging the RAM used (ram used + ram cached + buffers) and the CPU temp. It shows that it seems not be a RAM issue (see attached).
My version of the emonhub_dispatcher.py file seems to be older as I have no _send_post() function
Here is my confirmation code :
else:
reply = response.read()
if reply == 'ok':
self._log.debug("Receipt acknowledged with '" + reply + "' from " + self._settings['url'])
return True
else:
self._log.warning("Send failure: wanted 'ok' but got "+reply)
Attached is a copy of my emonhub_dispatcher.py file.
I didn't change local or reset password in emoncms recently.
Eric
Re: Emonhub failure
PS : in my logs, you can also find such message :
WARNING Send failure: wanted 'ok' but got Message sent!Message sent!ok
Re: Emonhub failure
Do you still have the events module installed? and do you have any events configured ? I recall you did install it and That is the one and only place I can find "Message sent!"
https://github.com/emoncms/event/blob/186539af82a78e6cff844365618443bc1d95bec9/event_model.php#L302
I've been over the emonHub code and can see no other place it could come from other than emoncms, whether it's possible for the events module to interfere with the request response I cannot say, but it certainly seems the most feasible source .
Looking at your graphs, it doesn't look like a RAM issue but is it possible the heat was the final straw? there is a massive increase in temp in-line with the constant attempts to post which just suddenly drops and is probably where the posting finally stops.
Although I didn't find a definitive answer about the temp range of a Pi, I think general consensus is above 50 deg C is not good. This document says it may be possible to run at over 50 deg C but also states this
Which is cause enough to suspect heat could of been the final straw since you have recorded temps nearing 57 deg C at the GPU, plus the hdd is also in the same compartment and we don't know what temp that was at.
Paul
Re: Emonhub failure
i just looked at some of your previous graphs and maybe the temp isn't so extreme, it's still high but you have run at those temps before,
You have changed the graph on your last post so there is more detail now and I can see Pi still running after where you marked emonhub shut down, presumably the log files stopped at that time, Does the pi have the ability to end a process if its causing temp issues? Just wondering what changed after 12hrs of consistently trying to post the same data,
Re: Emonhub failure
Hi,
Sorry for my bad english. When I marked "emonhub halt" or "emonhub shutdown", I am talking about the emonhub service and not the RPI itself. At any moment, the RPI has stopped. I guess that emonhub service has stopped as there were no more logs until I restarted that service.
I managed to run a RPI many hours at 65°C (see here) without any problem. So, I'm not sure it is a temp issue. The temp is high (55°C) but stable. According to me, the temp is a consequence and not a cause of emonhub's state.
Regarding the event module, you must be on the right way as I'm using it on my local emoncms ! I'm not sure there is link but I was facing some problems with it. When a specific condition became TRUE, it sent me the corresponding alert by email. But, when the condition went back to FALSE, the event module kept on sending me email until I deleted the corresponding alert.
To prevent any other emonhub crash, I will temporary delete all alerts.
Eric
Re: Emonhub failure
Hi,
There's no issue with your english at all Eric,
I totally agree the high temp is a consequence of emonHub working so hard continually trying to the post data and get a valid response from emoncms, I didn't intend to imply otherwise, I was speculating as to what may have caused emonhub to eventually stop, we may never know!
I'm quietly confident the cause was from within the events module, your confirmation of a issue with it combined with it being the only place i can find "Message sent!" used is too coincidental to be ignored.
Paul
Re: Emonhub failure
Hi,
I had another emonhub failure few days ago with the configuration described above :
- One RPI (+HDD running) running Emonhub + EmonCMS (V8.1.2, apt version)
- Emonhub is forwarding data to the local EmonCMS server and to a remote server (Emoncms.org)
Firstly, data in both emoncms servers were being updated at a very low rate (every 100-200 seconds instead of every tens seconds). some hours later, I got no more update in both EmonCMS server. The root file system of the RPI was full :
pi@raspberrypi ~ $ df
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 2721336 2563696 0 100% /
/dev/root 2721336 2563696 0 100% /
devtmpfs 215824 0 215824 0% /dev
tmpfs 44820 240 44580 1% /run
tmpfs 5120 0 5120 0% /run/lock
tmpfs 89620 0 89620 0% /run/shm
/dev/mmcblk0p1 57288 19064 38224 34% /boot
I discovered that I got some very long and repetitive log in /var/log/apache2/error.log (see attached). I moved them to another machine and then deleted them, but it was growing immediately again and again. I had to stop my local emoncms.
In the emonhub log file, one can see that emonhub got a wrong reply from my local emoncms.
Again just before emonhub failure, I got the same message than above : "WARNING Discarded RX frame 'non-numerical content'"
Eric
Re: Emonhub failure
Hi Eric
I've had a browse through the logs and cannot explain the emoncms entries in the apache log, I'm not familiar enough with emoncms or apache.
I couldn't find the "WARNING Discarded RX frame 'non-numerical content'" message but if it came at the end prior to failing it wouldn't of been the root cause, the emoncms "unpack .. require 4 got 0" messages date back to 16th august which coincides with some phpmyadmin log entries did you trigger something then ?
Whilst emoncms was not returning "ok" this would cause emonhub to "gum up" as the early version you are using is single thread, regardless of the cause of this issue I would strongly recommend upgrading emonhub as multi-threading was introduced to prevent emonhub from being effected by no or slow responses from servers. Although the ever increasing log sizes would eventually stop anything working.
I didn't notice anything sinister in the emonhub.log beyond the massive "reply" from emoncms and it seems emonhub resumed operation and posted the data as the next reply from emoncms is "ok".
Maybe Trystan or someone well versed in emoncms or the data engines can shed some light on the apache logs for us.
Paul
Re: Emonhub failure
The "WARNING Discarded RX frame 'non-numerical content'" message is at the very end of the emonhub.log file. It's the last message before emonhub stops sendind data. I agree with you that the cause of the failure seems to come from my local emoncms.
BTW, I will move to the last version of emonhub.
Eric
Re: Emonhub failure
Hi
I encountered another Emonhub failure (third one...) with the June-apt-version. (I have to update it, I know)
Unlike the two first failures, I didn't get any message starting by "Send failure: wanted 'ok' but got ..."
Like the two first failures, the last message in the logs (attached) is :
2014-09-19 23:47:31,846 INFO NEW FRAME : 2 36 255 219 255 1 36 3 0 0 7 0 0 0 61 99 0 0
2014-09-19 23:47:31,849 WARNING Discarded RX frame 'non-numerical content' : ['2', '36', '255', '219', '255', '', '1', '36', '3', '0', '0', '7', '0', '0', '0', '61', '99', '0', '0']
Every thing was fine until that message (normal update in Emoncms, no send failure , ...)
So this message seems to be the unique cause of the three failures.
It looks like that a byte has been omited.
Some questions :
- how is it possible to loose a byte inside Emonhub ?
- how to prevent Emonhub to halt when such an event occur ?
Another strange thing in my logs. The buffer was always growing although I got "Receipt acknowledged with 'ok' from http://emoncms.org". Now everything is working fine after restarting the Emonhub service. The buffer is not growing all the time and data are sent to EMonCMS.
Eric
Re: Emonhub failure
Hi Eric, sorry to hear you're having troubles again.
I really do appreciate your early involvement with emonhub but many things have been changed in emonhub to improve it's functioning as well as improve it's error handling and reporting, if there is a problem with emonhub it may of already been resolved or not even be relative to the latest build. It is also difficult to support the early version you are using since it was "mid development" prior to any versioning so I cannot be sure what code you have so please update !
Unlike the first two occasions which logged an unexpected response from your local emoncms, you are not sending to a local emoncms for it to return an unexpected response.
No, this message seems to commonly be the last thing emonhub logs before the "failure". In both the previous occasions we have found emonhub was not the cause and we have no reason to suspect anything different at this time.
Since the first thing emonhub does is log the raw string to the log file and the byte is already missing at that point it is likely to of been missing on arrival to emonhub, perhaps emonhub is slower to be effected by the imminent failure and the serial port skips a beat or something (for example).
emonhub will not fail just because of a missing byte, if you try posting to emonhub from a sketch with a deliberately omitted value it would run indefinitely and fill the log file with the "discarded RX frame messages"
As discussed in our PM dated 1/7/2014, this was due to a small bug that was resolved back in june where only a single frame was deleted from the buffer rather than the number of frames successfully posted.
I think it would be unlikely that the larger buffer size would of been able to get to a size that could "choke" the Pi's RAM since it can only be 1000 items max and I doubt if emoncms would of failed due to duplicated data, so I'm currently at a loss as to the actual cause.
But I am absolutely sure updating emonhub would have a positive impact regardless.
I'm always happy to try and help, but it would be easier for us both if you updated emonhub.
Do you have any other info?
Paul
Re: Emonhub failure
Hi Paul,
sorry to hear you're having troubles again.
Make sure that I was not complaining at all ! My goal was just to share the bugs I had.
It is also difficult to support the early version you are using since it was "mid development" prior to any versioning so I cannot be sure what code you have so please update !
I haven't update yet my version because I can't physically access to the RPI but only by SSH. I'm afraid of losing the control on the RPI during the update if something goes wrong. I would rather have a version that that makes me loose 1 or 2 days of data each month than loosing the RPI. Maybe, I'm too paranoiac ...
If my version is very out of date, I agree that it doesn't make any sense to share the bugs I had .
I'm always happy to try and help, but it would be easier for us both if you updated emonhub.
I totally understand your point. If I were you I would say the same (in a less polite way).
Do you have any other info?
No but one more remark : it's unclear for me if emonhub is released or not and what is the last version number.
EDIT : For both, Emonhub and EmonCMS, it would be great to have release notes explaining the new features, the corrected bugs, the installation procedure, ... I know it's a long work.
Eric
Re: Emonhub failure
Hi Eric
i understand now why you haven't updated, I didn't realize it was that same project. however that confuses me a little as I'm sure we confirmed you had updated the system after I did that bug fix.
If you want we can just edit the dispatcher code to fix that bug, which may well ease the load enough to prevent further issues. But there again I guess you only have a week or so for that project to run now, so probably not worth doing.
Me too :-)
Our original intention was to release emonhub as a debian package, but as that looks less likely now and it's already in general use I guess it is already unofficially launched. I gave the version included on the latest SD card a version ID of rc1.0 and I have rc1.1 in testing at the moment, minor stuff really just settings validation, default settings and automatic baud selection for rfm type devices. There is a couple of things that need to be decided about installer scripts and the repo structure (to ease upgrading) before they are set in stone but aside from that and the lack of documentation I think v1.0 is good to go!
Paul


Appetizers Menu
Appetizers Menu
Crispy and savory edamame that serves as a light starter
Cumcumber Salad dazzled with red chili flakes, roasted peanuts, sesame oil, and garlic
Steamed, golden dumplings stuffed with ground pork of beef
Mouth-watering pork buns glazed with honey and spice
Fried spring rolls stuffed with pork, ginger, scallions, and mirin


Практическая работа 3
Filterable Table
Shopping Cart
#
Album
Performer
Genre
Year
Link
Filter!
Your Cart
Your cart is empty. Buy something!
Total: $
0
Remove All!


Some things are finalizing, and we'll redirect you to {{ State.Host }} in the next 30 seconds.
We've authorize and configure your Azure Dev Ops, and we'll walk you through creating new Data Applications on this infrastructure.
We have tons of great information and tutorials to get you started, so dive in!


A Bootstrap style sheet dedicated to Syracuse, NY.
The salt industry has a long history in and around Syracuse, New York. Jesuit missionaries visiting the region in 1654 were the first to report salty brine springs around the southern end of "Salt Lake," known today as Onondaga Lake. The majority of salt used in the United States in the 19th century came from Syracuse. Even today, Syracuse is sometimes known as "the Salt City."
This text is important.
This text indicates success.
This text represents some information.
This text represents a warning.
This text represents danger.
This text is important.
This text indicates success.
This text represents some information.
This text represents a warning.
This text represents danger.
Syracuse is the snowiest city in the country by far. Winter usually lasts six months. Sometimes more. It is in a perfect location to get an absurd amount of lake effect snow for months on end. The snow never seems to end in the winter. Then when the summer rolls around, it's as hot as the devil in a sweater on the surface of the sun.
Some guy shoveling snow. Syracuse, NY
The Jumbotron at the Carrier Dome is way better.
is a city in, and the county seat of, Onondaga County, New York, in the United States. It is the largest U.S. city with the name "Syracuse", and is the fifth most populous city in the state of New York. It is the economic and educational hub of Central New York, a region with over a million inhabitants. Syracuse was named after the original Greek city Syracuse.
The Syracuse area was first seen by Europeans when French missionaries came to the area in the 1600s. At the invitation of the Onondaga Nation, one of the five constituent members of the Iroquois confederacy, a group of Jesuit priests, soldiers, and coureurs des bois (including Pierre Esprit Radisson) set up a mission, known as Sainte Marie among the Iroquois, or Ste. Marie de Gannentaha, on the northeast shore of Onondaga Lake.
Westcott is a neighborhood in Syracuse, New York. Its proximity to Syracuse University makes for a diverse community, home to Syracuse University students, professors and other faculty and staff, as well as residents at all income levels. Westcott Street is the main retail street of the neighborhood, featuring numerous restaurants, stores and The Westcott Theater performing arts venue. Westcott is also home to Thornden Park, one of the largest parks in Syracuse.
Eastwood is a neighborhood in the east of Syracuse, New York. Eastwood was originally a village, and as a suburb of Syracuse, was named for its easterly direction from that place. The neighborhood was part of the last round of annexations by the City of Syracuse, in 1928. Today the neighborhood still has a strong sense of community, and its nickname is "the village within the city."
Tipperary Hill, also known as Tipp Hill, is a district in the city of Syracuse, New York, largely settled by immigrants from Ireland, especially from County Tipperary. It makes up half of Syracuse's Far Westside neighborhood.
| Firstname | Lastname | Position | Number |
|---|---|---|---|
| Carmelo | Anthony | Forward | 15 |
| Hakim | Warrick | Forward | 1 |
| Gerry | McNamara | Guard | 3 |
| Kueth | Duany | Guard/Forward | 13 |
| Josh | Pace | Guard/Forward | 5 |
| Billy | Edelin | Guard | 14 |
| Firstname | Lastname | Position | Number |
|---|---|---|---|
| Carmelo | Anthony | Forward | 15 |
| Hakim | Warrick | Forward | 1 |
| Gerry | McNamara | Guard | 3 |
| Kueth | Duany | Guard/Forward | 13 |
| Josh | Pace | Guard/Forward | 5 |
| Billy | Edelin | Guard | 14 |


class: center, middle, inverse, title-slide # Census and USGS Data ## (MPA 6020) ### Ani Ruhil ### 2018-03-01 --- ## Agenda Brief overview of useful Census and other data sources you may need - using the Census API with `tidycensus` and `censusapi` - data from the World Bank - data from the USGS --- class: inverse, middle, center ## `tidycensus` --- Kyle Walker has authored `tidycensus` to ease working with Census data and it is built to work well with the `tidyverse` and mapping libraries. * get a Census API key [from here](http://api.census.gov/data/key_signup.html) * install the `tidycensus` package ```r library(tidycensus) library(tidyverse) census_api_key("INSERT YOUR API KEY HERE") ``` Two functions of primary value -- (1) `get_decennial()` for decennial census data from 1990, 2000, and 2010 (2) `get_acs()` for data from the American Community Survey (ACS) series Typical starting point will be finding the table you want and an easy way to do this is by pulling a list of all tables available for a sopecific census product. Below you see the code for grabbing a list of the Summary File 1 tables from the 2010 decennial census, followed by the 1-year 2016 ACS and the 5-year ACS (2012-2016). ```r my.tables.d = load_variables(year = 2010, dataset = "sf1", cache = TRUE) my.tables.a1 = load_variables(year = 2016, dataset = "acs1", cache = TRUE) my.tables.a5 = load_variables(year = 2016, dataset = "acs5", cache = TRUE) ``` --- Each of these will show you what variables are available, and make it easier for you to choose the ones you want to work with. Assume we want total population, variable `P0010001`, from the decennial census ```r state.popn.d = get_decennial(geography = "state", variables = c(totpopn = "P0010001")) county.popn.d = get_decennial(geography = "county", variables = c(totpopn = "P0010001"), state = "OH") tract.popn.d = get_decennial(geography = "tract", variables = c(totpopn = "P0010001"), state = "OH", county = "Athens") ``` and then from the ACS. Note that the default for each is 2010 and the most recent ACS (2012-2016). ```r state.popn.acs = get_acs(geography = "state", variables = c(totpopn = "B01003_001")) county.popn.acs = get_acs(geography = "county", variables = c(totpopn = "B01003_001"), state = "OH") tract.popn.acs = get_acs(geography = "tract", variables = c(totpopn = "B01003_001"), state = "OH", county = "Athens") ``` --- You can also get an entire table instead of having to list variables, such as shown below, with the default decennial census for the package's current version (2010). ```r county.table.d = get_decennial(geography = "county", table = "P012", summary_var = "P0010001") state.table.d = get_decennial(geography = "state", table = "P012", summary_var = "P0010001") ``` Population data for all tracts in the country? ```r library(tidycensus) library(purrr) us <- unique(fips_codes$state)[1:51] totalpop <- map_df(us, function(x) { get_acs(geography = "tract", variables = "B01003_001", state = x, geometry = TRUE) }) ``` --- class: inverse, middle, center ## `censusapi` --- This package will allow you to grab a vast array of Census products, and very niftily as well I might add. ```r library(censusapi) apis <- listCensusApis() ``` Application Programming Interfaces (APIs) could have slightly varying parameters so it pays to check the API documentation [available here](https://www.census.gov/data/developers/data-sets.html). It is easy to find variable names via the built-in function `listCensusMetadata`. As an example, the bureau's small area health insurance estimates are shown below, as well as the small area income and poverty estimates. ```r sahie_vars <- listCensusMetadata(name = "timeseries/healthins/sahie", type = "variables") saipe_vars <- listCensusMetadata(name = "timeseries/poverty/saipe", type = "variables") ``` Want to see what geographies are available? Switch `type =` to `geography`: ```r sahie_geos <- listCensusMetadata(name = "timeseries/healthins/sahie", type = "geography") saipe_geos <- listCensusMetadata(name = "timeseries/poverty/saipe", type = "geography") ``` --- Grab the most recent county-level data but note that the latest SAHIE are for 2015 while the latest SAIPE are for 2016. Every variable is downloaded as a `chr` so you will need to flip what should be numeric into numeric. ```r sahie_counties <- getCensus(name = "timeseries/healthins/sahie", vars = c("NAME", "IPRCAT", "IPR_DESC", "PCTUI_PT"), region = "county:*", regionin = "state:39", time = 2015, key = CENSUS_KEY) head(sahie_counties, n = 12L) saipe_counties <- getCensus(name = "timeseries/poverty/saipe", vars = c("NAME", "SAEPOVRTALL_PT", "SAEMHI_PT"), region = "county:*", regionin = "state:39", time = 2016, key = CENSUS_KEY) head(saipe_counties, n = 12L) saipe_counties$prate = as.numeric(saipe_counties$SAEPOVRTALL_PT) saipe_counties$mdhinc = as.numeric(saipe_counties$SAEMHI_PT) ``` --- If you want data for a lot of geographies, the package will let you do it in seconds. For example, if you want tract-level data for `all tracts`, you can get it as shown below: ```r fips tracts <- NULL for (f in fips) { stateget <- paste("state:", f, sep = "") temp <- getCensus(name = "sf3", vintage = 1990, vars = c("P0070001", "P0070002", "P114A001"), region = "tract:*", regionin = stateget, key = CENSUS_KEY) tracts <- rbind(tracts, temp) } head(tracts) ``` Notice that you had to specify the `region`, and since tracts are nested within states, you had to add `regionin = stateget`. --- class: inverse, middle, center ## World Bank data with `data360r` and `wbstats` --- Two packages are available to access data gathered by the World Bank, [`data360r`](https://github.com/mrpsonglao/data360r) and [`wbstats`](https://github.com/GIST-ORNL/wbstats). Install both packages, and then we can start with `data360r`. We can start by seeing what indicators are available, some basic country-level information, and what data-sets are available. ```r library(data360r) # get all indicator metadata in Govdata360 df_indicators <- get_metadata360(site = "gov", metadata_type = "indicators") # get all country metadata in TCdata360 df_countries <- get_metadata360(metadata_type = "countries") # get all dataset metadata in TCdata360 df_datasets <- get_metadata360(metadata_type = "datasets") ``` --- Once you have identified a particular table, note it's ID, and then pull it. Say I want indicator 90 = `Can a married woman register a business in the same way as a married man?` I can do the same thing for more than one indicator by specifying the IDs. ```r df_ind90 = get_data360(indicator_id = c(90)) ``` ``` ## <simpleError in parse_block(g[-1], g[1], params.src): duplicate label 'setup'> ``` ```r df_indtwo = get_data360(indicator_id = c(28130, 28131)) ``` If I only want all data for a specific country or just the indicators we pull in `df_ind1` for a specific country you could do: ```r df_allone = get_data360(country_iso3 = "IND") df_ind1 <- search_360("woman business", search_type = "indicator", limit_results = 5) df_allindtwo = get_data360(indicator_id = df_ind1$id, country_iso3 = "IND") ``` ``` ## <simpleError in parse_block(g[-1], g[1], params.src): duplicate label 'setup'> ``` --- Now an example with two measures -- legal age of marriage for boys and girls. Note that the package allows you to specify the `long` format (preferred) than the default `wide` format you see earlier results being returned in. Note also the use of `timeframes = c()` that allows you to specify the specific time period you want the indicators for. ```r search_360("marriage", search_type = "indicator") ``` ``` ## id ## 1: 204 ## 2: 205 ## 3: 206 ## 4: 207 ## 5: 208 ## name ## 1: What is the legal age of marriage for boys? ## 2: What is the legal age of marriage for girls? ## 3: Are there any exceptions to the legal age of marriage? ## 4: Does the law prohibit or invalidate child or early marriage? ## 5: Are there penalties in the law for authorizing or knowingly entering into the child or early marriage?¥Ë_ ## slug type score dataset ## 1: age.marr.male indicator 0.11111111 Women, Business and the Law ## 2: age.marr.fem indicator 0.11111111 Women, Business and the Law ## 3: marry.age.except indicator 0.10000000 Women, Business and the Law ## 4: chld.marr indicator 0.10000000 Women, Business and the Law ## 5: h44ef57bd indicator 0.05882353 Women, Business and the Law ## redirect ## 1: FALSE ## 2: FALSE ## 3: FALSE ## 4: FALSE ## 5: FALSE ``` --- ```r df_marriage <- get_data360(indicator_id = c(204, 205), timeframes = c(2016), output_type = "long") library(ggplot2) ggplot(df_marriage, aes(x = Observation, group = Indicator, fill = Indicator)) + geom_bar() + theme(legend.position = "none") + facet_wrap(~Indicator, ncol = 1) + labs(x = "Legal Age of Marriage", y = "Frequency", title = "Legal Age of Marriage for Boys vs. Girls", subtitle = "(2016)", caption = "Source: World Bank Data") ```  --- The `wbstats` package does pretty much the same thing. Let us see the core functionality by loading the library and then seeing what is available in terms of indicators, topics, and so on. We can then set the most current list of information in `wb_cachelist` to be used via `new_cache`. Doing so speeds up the operations and ensures that you are getting the most uptodate data. ```r library(wbstats) str(wb_cachelist, max.level = 1) ``` ``` ## List of 7 ## $ countries :'data.frame': 304 obs. of 18 variables: ## $ indicators :'data.frame': 16978 obs. of 7 variables: ## $ sources :'data.frame': 43 obs. of 8 variables: ## $ datacatalog:'data.frame': 238 obs. of 29 variables: ## $ topics :'data.frame': 21 obs. of 3 variables: ## $ income :'data.frame': 7 obs. of 3 variables: ## $ lending :'data.frame': 4 obs. of 3 variables: ``` ```r new_cache <- wbcache() ``` --- What indicators are available? ```r corruption_vars <- wbsearch(pattern = "corruption") head(corruption_vars) ``` ``` ## indicatorID ## 6106 IC.CNS.CORR.ZS ## 6858 IC.FRM.ELEC.ZS ## 6873 IC.FRM.CORR.GRAFT2 ## 6874 IC.FRM.CORR.CRIME9 ## 6875 IC.FRM.CORR.CORR9 ## 6876 IC.FRM.CORR.CORR8 ## indicator ## 6106 Corruption (% of managers surveyed ranking this as a major constraint) ## 6858 Electricity (% of firms identifying this as a major constraint) ## 6873 Bribery index (% of gift or informal payment requests during public transactions) ## 6874 Percent of firms identifying the courts system as a major constraint ## 6875 Percent of firms expected to give gifts to get an import license ## 6876 Percent of firms expected to give gifts to get a construction permit ``` --- If I want information from a particular source, say Bloomberg, ```r blmbrg_vars <- wbsearch(pattern = "Bloomberg", fields = "sourceOrg") head(blmbrg_vars) ``` ``` ## indicatorID indicator ## 262 WHEAT_US_HRW Wheat, US, HRW, $/mt, current$ ## 766 SUGAR_US Sugar, US, cents/kg, current$ ## 2563 RUBBER1_MYSG Rubber, Singapore, cents/kg, current$ ## 9488 GFDD.SM.01 Stock price volatility ## 9496 GFDD.OM.02 Stock market return (%, year-on-year) ## 12003 BARLEY Barley, $/mt, current$ ``` --- Searching for indicators tied to multiple subjects is easy as well: ```r povemply_vars <- wbsearch(pattern = "poverty | unemployment | employment") head(povemply_vars) ``` ``` ## indicatorID ## 35 WP15177.9 ## 36 WP15177.8 ## 37 WP15177.7 ## 38 WP15177.6 ## 39 WP15177.5 ## 40 WP15177.4 ## indicator ## 35 Received government transfers in the past year, income, richest 60% (% ages 15+) [w2] ## 36 Received government transfers in the past year, income, poorest 40% (% ages 15+) [w2] ## 37 Received government transfers in the past year, secondary education or more (% ages 15+) [w2] ## 38 Received government transfers in the past year, primary education or less (% ages 15+) [w2] ## 39 Received government transfers in the past year, older adults (% ages 25+) [w2] ## 40 Received government transfers in the past year, young adults (% ages 15-24) [w2] ``` --- Once we identify what we want, downloading the data is easy as well, needing us to specify just the indicator(s) and then the start and end dates, and then specific country codes if you want data for specific countries. Below I am pulling total population. ```r pop_data1 <- wb(indicator = "SP.POP.TOTL", startdate = 1960, enddate = 2016) pop_data2 <- wb(country = c("ABW", "AF", "SSF", "ECA", "IND", "CHN"), indicator = "SP.POP.TOTL", startdate = 1960, enddate = 2016) pop_data3 <- wb(country = c("ABW", "AF", "SSF", "ECA", "IND", "CHN"), indicator = c("SP.POP.TOTL", "NY.GDP.MKTP.CD"), startdate = 1960, enddate = 2016) head(pop_data3) ``` ``` ## iso3c date value indicatorID indicator iso2c country ## 1 ABW 2016 104822 SP.POP.TOTL Population, total AW Aruba ## 2 ABW 2015 104341 SP.POP.TOTL Population, total AW Aruba ## 3 ABW 2014 103795 SP.POP.TOTL Population, total AW Aruba ## 4 ABW 2013 103187 SP.POP.TOTL Population, total AW Aruba ## 5 ABW 2012 102577 SP.POP.TOTL Population, total AW Aruba ## 6 ABW 2011 102053 SP.POP.TOTL Population, total AW Aruba ``` --- ```r pop_data4 <- wb(country = c("ABW", "AF", "SSF", "ECA", "IND", "CHN"), indicator = c("SP.POP.TOTL", "NY.GDP.MKTP.CD"), startdate = 1960, enddate = 2016, return_wide = TRUE) head(pop_data4) ``` ``` ## iso3c date iso2c country NY.GDP.MKTP.CD SP.POP.TOTL ## 1 ABW 1960 AW Aruba NA 54211 ## 2 ABW 1961 AW Aruba NA 55438 ## 3 ABW 1962 AW Aruba NA 56225 ## 4 ABW 1963 AW Aruba NA 56695 ## 5 ABW 1964 AW Aruba NA 57032 ## 6 ABW 1965 AW Aruba NA 57360 ``` --- By default `wb()` will return the data in long format but not necessarily in a tidy format. If you want the data returned on call in a wide format, specify `return_wide = TRUE` and you will have tidy data. If you will be working with dates, whether for plotting purposes or otherwise, then activate the `POSIXct = TRUE` switch. Otherwise you will have to do this manually. ```r pop_data5 <- wb(country = c("IND", "CHN"), indicator = c("SP.POP.TOTL"), startdate = 1960, enddate = 2016, return_wide = TRUE, POSIXct = TRUE) head(pop_data5) ``` ``` ## iso3c date iso2c country date_ct granularity SP.POP.TOTL ## 1 CHN 1960 CN China 1960-01-01 annual 667070000 ## 2 CHN 1961 CN China 1961-01-01 annual 660330000 ## 3 CHN 1962 CN China 1962-01-01 annual 665770000 ## 4 CHN 1963 CN China 1963-01-01 annual 682335000 ## 5 CHN 1964 CN China 1964-01-01 annual 698355000 ## 6 CHN 1965 CN China 1965-01-01 annual 715185000 ``` --- ```r library(scales) ggplot(pop_data5, aes(x = date_ct, y = SP.POP.TOTL)) + geom_line(aes(color = country)) + scale_y_continuous(labels = comma) + scale_x_date(date_breaks = "10 years") + theme(legend.position = "bottom") + labs(x = "Date", y = "Total Population") + theme_minimal() ```  --- class: inverse, middle, center ## USGS data with `dataRetrieval` --- The `dataRetrieval` package gives you easy access to water data gathered and warehoused by the USGS, USDA, EPA, and other entities. The package has an excellent [tutorial available here](https://owi.usgs.gov/R/dataRetrieval.html#1) so I will not go into too many details and nuances here. Start by installing the package and then loading it. ```r library(dataRetrieval) ``` You will need to know the site(s) you are interested in, as well as the parameters and statistics of interest. The package comes with a built-in data-set that shows you the parameters available, and the complete list of statistics [is available here](https://help.waterdata.usgs.gov/code/stat_cd_nm_query?stat_nm_cd=%25&fmt=html). Sites can be located [from this inventory](https://waterdata.usgs.gov/nwis/inventory). ```r parameterCdFile <- parameterCdFile names(parameterCdFile) ``` ``` ## [1] "parameter_cd" "parameter_group_nm" "parameter_nm" ## [4] "casrn" "srsname" "parameter_units" ``` --- If you are curious about a specific parameter, you can see what all is available for it. I'll look for anything related to the keyword `storm`, and also what parameter units are available. ```r stormq <- parameterCdFile[grep("storm", parameterCdFile$parameter_nm, ignore.case = TRUE), ] unique(stormq$parameter_units) ``` ``` ## [1] "nu" "hours" "minutes" "Mgal" "ft3/s" "mgd" "in" ``` Let us do a quick grab of some data for the Hocking River at Athens, Ohio. ```r siteNo <- "03159500" pCode <- "00065" start.date <- "2014-10-01" end.date <- "2018-02-26" hocking <- readNWISuv(siteNumbers = siteNo, parameterCd = pCode, startDate = start.date, endDate = end.date) ``` --- Since the column names are based on parameter codes and hence cryptic, you can clean them up, and also see other attributes embedded in the data-set. ```r names(hocking) ``` ``` ## [1] "agency_cd" "site_no" "dateTime" ## [4] "X_00065_00000" "X_00065_00000_cd" "tz_cd" ``` ```r hocking <- renameNWISColumns(hocking) names(hocking) ``` ``` ## [1] "agency_cd" "site_no" "dateTime" "GH_Inst" "GH_Inst_cd" ## [6] "tz_cd" ``` ```r names(attributes(hocking)) ``` ``` ## [1] "class" "row.names" "names" "url" ## [5] "siteInfo" "variableInfo" "disclaimer" "statisticInfo" ## [9] "queryTime" ``` --- If I wanted data for multiple sites, I could find the site numbers and then grab the data. ```r sites <- c("03158200", "03159246") pcode <- "00065" start.date <- "2014-10-01" end.date <- "2018-02-26" hocking2 <- readNWISuv(siteNumbers = sites, parameterCd = pcode, startDate = start.date, endDate = end.date) hocking2 <- renameNWISColumns(hocking2) ``` Now a simple time-series plot of gage height for both sites. Note that although I asked for data going far back, not all sites have all data for all time periods so it helps to check the site inventory first. (The code and plot are on the following slide) --- ```r parameterInfo <- attr(hocking2, "variableInfo") hocking2$station = ifelse(hocking2$site_no == "03158200", "Monday Creek at Doanville", "Sunday Creek Below Millfield") hocking2$mydates = as.Date(as.character(hocking2$dateTime), format = "%Y-%m-%d") ggplot(data = hocking2, aes(mydates, GH_Inst, color = station)) + geom_line() + xlab("") + ylab(parameterInfo$variableDescription) + scale_x_date(date_breaks = "2 weeks") + theme_minimal() + theme(legend.position = "bottom") ```


Arduino sketch
You must use arduino sketch from arduino folder each time when working with Involt. It contains variables and functions used for communication.
Involt sketch automatically updates the values received from app into involtPin array where length is total pin number +1. Undeclared array length may cause some errors in some cases so it's better to have it defined. involtString contains strings. Sometimes it's a good practice to define beginning values in void setup() to make the hardware state consistent to app beginning values (or avoid some bugs).
Keep in mind, as written in previous chapter that you can send more values than your device pin number. You can use more variables to operate inside sketch functions or send values to expanders or shift registers. For example in Arduino UNO, using involtPin index 14-20 to use with shift register. Check Send/receive more... tutorial.
Involt sketch uses only serial library. Everything should work fine as long as you don't try to use software serial. Some devices may need to change Serialto Serial1.
Small delays between multiple send functions are required.
Where did the data received from app go?
The received values are updated to involtPin[pinIndex] array. To use them just write digitalWrite or analogWrite using the desired variable. Button with pin P6 (stored in involt.pin.P[6]) will send value to involtPin[6]. You should keep the index consistent in your project for readability reasons.
void loop(){
involtReceive();
analogWrite(6, involtPin[6]);
}...
The S string pin from app will go to involtString[pinIndex] (S0 will be in involtString[0] and involt.pin.S[0] in app).
For sending 0-1 values for digitalWrite you need to add the pinMode.
Sending the value to app
For sending values use involtSend(pinIndex, value) function. The pinIndex will be same inside app. involtSend(0, analogRead(A0)) can be shown with A0 pin in app (for example: ard show A0).
void loop(){
involtReceive();
involtSend(0, analogRead(A0));
delay(2);
}...
For sending strings use involtSendString(pinIndex, string) function.
void loop(){
involtReceive();
involtSendString(10, "involt");
delay(8)
}...
How to avoid buffer overload
The larger the amount of data is transmitted, or when multiple send functions are in next few lines, the higher the delays between should be. However, you should consider changes in your project if you're trying to send string in real time like "I really want to update this string to app and show it in real time". It's important especially when sending multiple strings (sometimes 10,20 ms is required).
How to see the buffer overload? It's simple - it occurs when some numeric values are updated fast and some of them slow (or nothing happens). For strings, it's visible when you get some glitches or the data is updated slowly. It's more problematic on bluetooth and mobile devices.
Changing the bitrate may help. Remember to set it to same value in settings.js


Polling Station
Results
My Ballot
Active Polls
{{ eachPoll }}
Create Poll
{{ currentPoll }} Results
{{ eachCandidate}}
{{ currentPoll }} Ballot
↑
↓
{{ eachCandidate }}
Add
Submit


class Thumbnail extends QiniuAPIParameter
/thumbnail/!
/thumbnail/
Properties
| static | $name |
Methods
|
widthAndHeight($width, $height)
|
||
|
maxWidthAndHeight($width, $height)
|
||
|
minWidthAndHeight($width, $height)
|
||
|
scale($scale)
|
||
|
contain($bool = true)
|
||
|
keepRatio($bool = true)
|
Details
at line 57
public
widthAndHeight($width, $height)
at line 63
public
maxWidthAndHeight($width, $height)
at line 67
public
minWidthAndHeight($width, $height)
at line 71
public
scale($scale)
at line 83
public
contain($bool = true)
at line 88
public
keepRatio($bool = true)


Base Forms for Scales
This page includes the default base forms styles.
Default stacked form
Account #
(Cannot Change)
Email
Enter your email address
Password
Gender
Female
Male
Other
Introduce yourself
Send me the newsletter
Sign in
Using an unordered list
Account #
(Cannot Change)
Email
Enter your email address
Password
Gender
Female
Male
Other
Introduce yourself
Send me the newsletter
Sign in
Inline form
Account #
(Cannot Change)
Email
Password
Gender
Female
Male
Other
Introduce yourself
Send me the newsletter
Sign in
Inline input containers with stacked label/input
Account #
(Cannot Change)
Email
Enter your email address
Password
Gender
Female
Male
Other
Introduce yourself
Send me the newsletter
Sign in


For the first time in franchise history,your Cleveland Cavaliers are NBA Champions.
Earl Joseph "J. R." Smith grew up in the Clarksburg section of Millstone Township, New Jersey.
Learn MoreTristan Trevor James Thompson was born on March 13,1991 in Toronto,Ontario.
Learn MoreTimofey Pavlovich Mozgov was born on July 16,1986 in Saint Petersburg,Russian SFSR,Soviet Union.
Learn MoreMatthew Dellavedova was born on September 8,1990 in Maryborough,Victoria.
Learn More


Taking TerminusDB to the bank (Part II)
In the first installment we created a branch_office branch where we added some data. But the strength of the distributed model of TerminusDB is that others can work on data assets in parallel. To make use of this powerful feature, we need to make alterations in a different database.
Since we are using collaboration features, first you will need to log into hub. You can do that by clicking on “Connect to Hub” in the right hand corner.
We’ll start with the database as created in Part 1. If you don’t have this database anymore, you can rebuild it be following the steps in part 1 of this tutorial.
First step - make sure you share the database to hub.
Distributed updates
Click on your “Bank Balance Example” and go to the synchronise page. Select “Push”, and then select the branch we named branch_office
both locally and on the remote and click the button “Push Updates”.
Now we have the data on hub! If you go to the main “Bank Balance Example” page, you can see the remote URL in the box on the right which says “origin Remote”. Copy this URL, we’re going to make a clone.
Now go to the main TerminusDB page and click on clone. Then enter the URL of the database remote URL on Hub.
This operation could be done from any computer. It doesn’t have to be the same installation of TerminusDB, but if you only want to install once, then this is certainly easiest.
Now go to the manage page and click on pull. We’re going to pull the branch_office
branch to main locally. Once you’ve done this go to documents. You should see that the documents include doc:mike
and doc:jim
(as these were entered from the branch_office
branch)
Updating the Branch Office Database
Now that we have the data on our local we can go to the query screen again, and enter a new record:
WOQL.and(
WOQL.add_triple("doc:jill", "type", "scm:BankAccount"),
WOQL.add_triple("doc:jill", "owner", "jill"),
WOQL.add_triple("doc:jill", "balance", 87)
)
We now have Jill in our main branch in our new database. Now it’s time to push our changes to hub. Go to the “Branch Office” database, click on the Synchronize-tab and push changes to remote.
This time we want to push main to branch_office on the remote.
Bringing the Branch Office data to Head Quarters
Once you have pushed, you should back into your old “Bank Balance Example” database. From here we can get the changes back from the branch_office changes on hub.
Now let’s do another synchronize. Pull changes from hub from the branch_office
branch to the branch_office
branch. We now should have Jill on our local database. Let’s just check quickly by looking at documents (make sure you select the correct branch in the branch selector in the top right!).
We still don’t have the changes in main however (although we could have pulled directly) and so now we should do a merge operation again, just as we did in Part 1. We’ll leave this as an exercise for the reader… good luck!
Building the database of the future.


I decided to have a go at redesigning some of the signage and marketing that was put together by Rainbow Body Care in St. Marks Place.
My sense was that there was something rather charming, and playful about the rainbow coloured branding and playful use of typography - however there was way too much information being presented, without hierarchy or sufficient design organisation.
I thought it would be fun to inject some more self awareness into their branding, and provide a poster that would maybe wink at itself a little.
I first attempted to recreate the style of the Pachinko’s Big Bet, which was a failure.
I abandoned this before finishing, as I was running up against limitations in my abilities with Illustrator and graphic design.
My next step was to try something less ambitious, and to work with some of the existing references. I noticed that there were 7 proposed remedies in the initial signs, and also 7 colours of the rainbow. I proposed having these 7 remedies vanish with the rainbow. Instead of explaining ‘This is what we can help you with’, I considered that it would be simpler and more direct to represent the 7 ailments vanishing with the tail of the rainbow. The curving Rainbow typeface references the shape of the rainbow.
I used Arial for the type face, and a basic Rainbow colour scheme. All very boring, but it is a start.