Good morning. Okay, everyone's paying attention. I know it's just before lunch So today Doug and I are going to help you learn how to write an AngularJS plugin And since this is a hands-on lab, we are going to actually write an AngularJS plugin So the things we are going to cover today First we will talk about the overview of an AngularJS plugin and then talk about how this Workshop is going to be structured. So you have an idea of what to expect After that, we are going to talk about some basics of the AngularJS plugin And the plugin structure that you need to understand and Then we'll move on to lab one which is basically where you'll start to enhance on coding So I hope you all got your coding hats on Hands-on sure So in the first lab, we're going to start out by writing an AngularJS plugin Which is going to put up a panel in horizon. So just your basic things and from that point on we are going to talk about some Development tools and tips that you'll be using or you can be using when you're doing development Then we'll move on to lab two which is going to build on what we did in lab one So for lab two, we're going to talk about how you can modify a table that you put up on a panel More often than not people are going to be putting up tables on on panel So this is a very common use case that you'll run into We'll then deep dive into the AngularJS and service interactions So this is where we will tie in how you're interacting with your API's and services so that you're getting back data and interacting And then we'll use the concepts that we are going to learn into lab three and Basically add a table row action So we'll provide you with some code that you can use as a starting point and then add some actions to the table rows Once we are done with that lab We'll talk about some other things that you need to know about when writing an AngularJS plug-in like How to do a DevStack plug-in as well as updating the horizon plug-in registry And then we'll talk a little bit about what we did with the load balance as a service version to plug-in That is now released as part of the Mitaka release and then we'll have some references that you can take with you And then we'll wrap it up for the day Okay Plug-ins are basically a way where they allow you to extend an existing functionality as a general rule and That allows you to not only control what content you have But it also isolates you from some of the base changes that may be going on in the underlying code So in our case for example if there's changes going on in Horizon Then you know you have a way of isolating yourself somewhat And I'll talk about that a little bit into your plug-in So one thing you need to understand is Horizon Has been on a path to move to AngularJS the base code that is and Because there's a lot of code in Horizon. It's not something that's going to happen in one release It's a you know work in progress There are parts of Horizon that have moved to AngularJS, but not all of it has moved So for example, the launch instance wizard is completely AngularJS now so That's very important for you to keep in mind when you're writing an AngularJS plug-in because you may run into issues Because of changes happening in the underlying code in Horizon So the best way to do your AngularJS plug-in development is to sort of you know Coordinate with the Horizon team if you run into issues Be there in the channel with them open stack dash Horizon It's you know, the Horizon team is really good. They're very active in the IRC channel as well So, you know just to work with them Okay, so let's say you're trying to write an AngularJS plug-in The first thing you need to do is create a separate repository all the AngularJS plugins are in their own repository and Make sure you give it a meaningful name and what do I mean by a meaningful name? It means that it should have one of the suffixes that are well recognized So one of the dash dashboard dash UI or dash Horizon That's a good suffix to have for your for your repo name Because the infra project will then recognize it as a Django project So it is important to make sure you give it a name that abides by this Your AngularJS plug-in is going to be a collection of JavaScript files and static resources So what we want to do is we want to make sure we put all our static resources In the static folder and so you'll see that when we go over the plug-in structure and what the tree looks like on where the files are residing and it's important because the Django static collector then knows where to pick it up and Distribute to the browser correctly Okay, workshop overview so things to know about the workshop first of all Everyone that had RSVP'd up until Friday Should have gotten an email from me asking for you to do a setup a pre-labs setup on your laptops So make sure you've already done that if you haven't go ahead and start it now It does take a few minutes. So it's important that you get that down going The workshop is going to be covering AngularJS from a code perspective So the things we are not going to cover are you know unit testing or How to integrate your plug-in into the infra project or the details of how the translation process is going to work Or how can you package your plug-in? So the goal here is to write code. So all the peripheral things are not Something that we'll cover in this workshop The workshop is geared towards writing an AngularJS plug-in in horizon It's not a general AngularJS plug-in workshop and now Doug is going to Take us into more details about an AngularJS plug-in and the artifacts that we need to understand from a base Concept perspective Great. Thanks So if you want to follow along locally on your PC If you're looking at the code, this might be a good time to do a get check out lab dash one is the tag that corresponds to this code and so The first bit of code if you look at the the dashboards tree You're gonna see it see a lot of pys suffixes and you might be thinking Doug what gives I thought this was gonna be an AngularJS plug-in workshop Horizon is still uses Django on the server side the plug-in plug-in mechanism is still Django Python based So the way that horizon is going to find out about your plug-in is still through Django and some of the older Mechanisms if you've written horizon plug-ins before as we go down in particular. We'll talk about this file This is the one that ties Your plug-in to horizon and really tells it where to find the other parts As we look down here under the static bit This is where this is where the fun is going to begin. You'll see we have a couple of JavaScript files There's an HTML file and that's actually our first little bit of angular and our small angular Template that we'll take a look at So the enabled file this is again the file that tells horizon about your plug-in and what kinds of things are in it it has It's prefixed with an alpha numeric string that tells that the order is going to be loaded By horizon so later plug-ins could overwrite Previous plug-ins. It also tells horizon what order in the tree. You'd like your plug-in to show up again, this is Python code and This is going one of that that key elements in this file is it's going to point to your panel P y Which again if you're if you've written horizon plug-ins in Python before Tells horizon exactly how to represent your panel in the tree and when it should be displayed So let's take a look at that panel P y so the panel P y specifies the Name that's going to show up in the navigation and at the point where I took this Screen capture you can see you know the name sample here would actually show up in the left side navigation of horizon It includes a slug which is a panel's unique identifier. It's going to end up in the URL for some of the Python Django related interactions and Finally it says who can see this panel or what services need to be available for my panel to be relevant All right here the the the sample we're building is actually built on Interacting with the neutron service So we've I've indicated that the network service should be available in order for this plug-in to show up URLs that P y is a file that again is familiar if you've written a Python plug-in before it tells Django where to find the URLs to get to the resources in the code We're gonna see here that that four up for a Angular-based plug-in. There's actually only one URL that that's gonna be that's gonna be mapped and where it's you know The mapping is happening right here, and we are telling horizon how to find our index File so that angular routing can take over. We'll take a look at that later as the lab goes on so the views dot P y is is the thing that's referenced by the URLs and it's you know pointing into our our our Project sample index dot HTML As we take a look inside we're gonna find that that's actually still at a Django template all of the horizon angular code Inherits from this Django template to have appropriate places for the angular code to plug in So here is the Django template it includes places that are gonna be overridden by Angular code and here's here's our very first little bit of Angular we're looking at right here We're telling angular that the things that go inside the main block here are going to be a view It's our first our first tie-in point A couple of things that might be unique to your plug-in you do we do still get to set the the title here Yeah, that should that should be it So now we're getting to the good stuff. We're actually looking at some some angular code at this point Table that HTML for for the lab one example is is straightforward. It should look a lot like HTML If you've looked at angular, you might recognize that this HZ page header is actually a An angular directive, so there's actually a little bit of code that ties in behind that Let's just do this sort of templating thing as well Is angular we'll touch on that during the first lab Sample module.js is our top top level angular file It's a You know, it's a module. It's always the thing that tells angular how to find the other JavaScript parts In the code and it's a good place to put any anything that is going to be scoped to your entire plug-in Constance you may want to use throughout the throughout the application Or routing information or that sort of thing. That's really high-level type information. So with that let's crack open the code Hopefully everybody's done this setup. I'm happy to walk around and help with that if anybody's had trouble later But what we're going to do is we're going to go into the check out lab one starting point And we're going to take a look at that You know panel PY like we talked about and go in and just change that the left navigation so that you can See your name in the left in the left navigation and we'll go into the angular template and go ahead and just Change the text to be hello your name or some other clever text So we'll go ahead and take maybe five or a minute five or ten minutes now your turn to write code We'll walk around and answer questions. Thanks Make sure that you do get check out lab one because we've provided some base code for you to build on to do this lab So that'll get you to the point where you're ready to work on this lab Good point. Thanks, right So, oh, I'm sorry. I'm sorry. Yeah, I see I see I see So Martin has asked a good question that what I'm saying to do get check out lab one You should see D into where the the code has been checked out with the instructions and so that would be under opt stack Sample dashboard sample dashboard. Yeah sample underscore dashboard. So change to that directory where this and this is the where the Plug-in code lives and go ahead and click Check out lab one Thanks, Martin. Other basic questions that people have before getting started And just so we are more clear about what we're asking to do Once you do a good checkout lab one, you should see this page so right here under Lab one is a new panel that you should see that has text of hello lab one So what we want you to do is basically change that so that you have your first name here instead of lab one And you have your hello first name here instead of hello lab one So this will help you understand what files are being used Where? Yeah, I'm sorry. Could you repeat the questions? Are the slides posted anywhere? So the slides are not posted anywhere yet, but once the recording is available We'll make the slides available as well either You know, I think in the previous releases I mean previous summits in the schedule They have provided place where you can post slides or as part of the video recording We could put a comment where the slides will be posted So one way or the other they will be available, but later on you'll have to check back Were you hoping and the lab repo is also available? So, you know if you want to continue working on the lab after you go back, you know You have the link to the repo so that will be available Were you hoping to have the slides available to help step through the lab or just for reference later? hand out So in case you're wondering what the password is to log in it's open stack one or lowercase So if someone is not seeing their changes reflected on the browser Make sure that you're running that update underscore static script that's provided So so so one awkwardness that is apparently built into our lab There's a goodies directory that has a useful script for updating when you're running from Apache and there's a file That I don't see in front of me update Static ssh or something like this it would be really great to copy that out of the git repository Put it maybe in your home directory and run it there because as we step through the labs That file is going to disappear my apologies. I've got a question so a problem that a couple people have had if you set up last night in your dev stack directory the local comp will have a problem line in it and It's offline equals true and if you find that you are are having trouble running dev stack or you're running dev stack and it's not Not finishing Remove that line and then run stack dot sh again. That should move people along How is progress through the first lab going it does anybody looking at their name and their web browser yet? Martin our hero Let's take it. Let's let's take a few minutes and get through I think it's I think it's important that we get to this first exercise that you so you have an environment That's working. So I'll just start at the front again. Let's ask your questions and let's let's get people through it So you can so you can see what's going on? so, can I get a show of hands on how many people are done with the lab or at least are able to see the The skeleton dashboard that we had the place that we had put in Just trying to get a feel of how far along people are or are people struggling Because we do have lab two and three that will basically give you a more angular. Yes core feel is Anyone done with the lab one? Okay, just I'm sorry Kind of sort of is okay, too. Okay, so if you're stuck then raise your hands Didn't find the module Run this command and then try to start the web And They couldn't find the module right so then I get cloned it Directory these two directories and So how do I run this run that last command so it finds the sample dashboard? The last Okay, so I see some people have had some success from the lab Maybe some others haven't we've slightly surpassed our five minutes allotted to get through the lab So I think we'll go ahead and move forward and so we were looking forward taking this modifying it so your name could be seen here and Both in the the left side navigation as well as within the page that has the angular in it And these are these are the code change. I was okay code changes. I was looking for us to make Here under in the Opstack sample dashboard directory. I was looking for Going into the panel py and just you know putting in your name here for the name of the panel That'll that'll that's what we'll show up in the left side navigation and then inside Underneath the static directory. So that's where the angular goodies live Going down to the table html and just messing with this markup and maybe you know putting your name inside the markup So some things that some of us discovered along the way. They were useful is using chrome Is a night as a nice way to get JavaScript debugging Firefox certainly has a debugger My personal experience is that when I'm debugging angular I get better error messages from chrome It's more what shows up in the console is more Helpful there are some horizon horizon settings that Some of us may have adjusted I want you to be aware of them So compress enabled false if we get if we get to the point where we're debugging JavaScript This is a useful thing to do When your JavaScript is being served by Django without it It's being all slammed together into one big file with a random looking name That can be really hard to debug if you set compress enabled equals false and it's going to keep those separate and It makes the debugging much easier because what you see in the debugger actually matches your source Also, if you're using the development server, which I covered for some of you and separately You're going to change need to change your web route to slash so it matches what's being used You'll see that sort of information and the horizon developer getting started information And again once we get into writing JavaScript Sometimes it's really simple a simple debug tool is just to throw a console log inside your code It'll spit out an object to the console or set of objects and you can see what's going on that way So again, so we some of us went through this already But you can run the Django development server from horizon and to do this to do this you would go into the op stack horizon directory and horizon has a The Django development server. It does some nice things for you like Reloading code automatically. It's also very easy to run it in a virtual environment if you need to by leaving out the dash n parameter And so this would start serving up horizon on port 8081 Again, if you do this you need to use the configuration settings I showed on the previous chart to change the web route to slash and Also, here's the content of the script. I think some people actually got to break inside of that already To Updates when you to do the updates when you're using a patchy So you're gonna find as you do this development and you put a patch out for review If you have people who are not really familiar with that horizon angular looking at it They'll pull down your patch and it won't work until they do these steps That's why I provided those steps in a script under the Miss goodies directory It'll be used for you to make so your own version of that script and pass it out to your friends as they're reviewing your code So let's go ahead and move on and talk about some of the lab to Materials you can go ahead and from the the opt stack sample plug-in directory Check out lab to if you want to follow along locally so Sample network P y is a file. It's Defining the rest interfaces to the plug-ins client And so it's actually it's it's actually providing a service from the server that your horizon is going to talk to from angular to get information People use the word horizon API for this sometimes our rest API Because it is a point we are getting you're gonna be serving up Jason from Yes, should we Commit the changes. Oh, oh, oh, oh So I so the question is about how to do get check out lab two because I already had you make some changes in lab one Two two ways you can handle that I'll leave that to your discretion One is to do get stash that'll shove off your changes to the side so you can take a look at them later Or if you think that you understood what you changed and don't want to necessarily refer to that code again You can just do get get reset dash dash hard Origin master and that'll bring you back to the master branch the master set of code and then you can do get check out lab two So horizon has some back back to serving up Jason from horizon for your angular code to consume Horizon has some utilities that are useful to help do this And if you look at the at the file I've provided You know a couple of the points to note here are this Python decorator you are URLs register Tells horizon that the class inside is implementing a rest API that's going to be consumed by dang jang it by by angular and Turns out the class name is almost irrelevant, but give it a good name and extend generic view The URL Specifies at what URL is my rest API going to be serving from and then inside there's another decorator rest Utils Ajax that tells horizon. This is where one of my Rest methods are going to be implemented implemented for the first sample. I've just implemented a get so when we want to get the Networks, you know, I'm making a Python call to do that What one of the things we do in horizon as we wrap the Python calls in an extra level of abstraction I've said a bit a bit about it here We didn't actually implement one of these for this sample in the same way that we didn't for albast dashboard because we were just able to import the existing horizon API wrapper I'll leave the chart here. Not gonna spend much time on it at this point So now stepping back to the angular side So the networks controller JS file it's important one to take a look at this is that angular Controller and it's gluing the what happens with the view, which is the HTML that we were messing with before To the model, which is where you know data is coming from so it's it's gluing together the pieces Some things you're going to see in this file are that we're telling We're telling angular in this case You know this this this code should be part of the of the horizon dashboard project sample networks module and I am providing a controller So that means I'm I'm matching up this text which I can put into my HTML as a controller with this JavaScript class name So here I've got dependencies that are being injected There's more than one way to do this in angular if you're writing a horizon plug-in It's important that you choose this style of dependency injection So we're calling out dependencies by by name here And we're saying angular when you when you build my sample network table controller object Please provide me with with an angular no service API sample network object and a horizon dashboard sample Actions batch actions object and a row actions object And so we tell angular this and angular is very compliant that way so when our Are our controllers being instantiated it passes in the objects that we requested in the order that we asked for them so this First API parameter in our JavaScript will correspond to what angular found for this object and so on for the other three The other three dependencies a table HTML So one of the things you'll find now is that the table HTML is updated for lab to We've called out the controller Sample networks controller as table. This is the name that needs to match the name that we registered before Horizon uses a smart table angular Package and so here we're we're interacting with with that. This is an important interaction for your table What this means is that table that source is where your controller is going to put the data that you want to be in the table and Smart table is oddly enough smart So it's going to do things like Understand that you've sorted your table or you've maybe done some filtering and you're not showing all the items in the table And so smart table is going to place The sorted and filtered list of items that we're actually working with into table items so that when we go through later and we're Looping through with NG repeat, which is an actual angular directive when we're looping through this table We're going to loop over only the items that are filtered and in the order that they're sold that they're sorted as the smart table informed us and One other file to take a look at is this sample network service JS file So this is a wrapper on the JavaScript code that knows how to interact with the the rest API So at this point our intent was to skip was to go into lab 2 and I think I maybe need to consult with Neela briefly about how we handle our last few minutes and get out the most useful information we can I Don't think we'll finish lab 2 in our allotted time So so Give it given our late time, which we'll wrap up in just a few minutes. I'm gonna skip ahead a bit Certainly we'll make this chart available. You can work through the exercises I think it's intended to be a step-by-step wait To get familiar with some of the angular plug-in stuff Good stuff here. Don't be sure to take a look at but but I want to make sure we have a few minutes to point out the resources The places you're going to go To get extra help to get extra information One thing to think about as you're writing your plug-in is Putting a DevStack plug-in inside your repository is very helpful It's an easy way to go out and get your plug-in installed in the right context You don't have to worry about PIP installs remembering to copy over that enabled file all the time You know write a DevStack DevStack plug-in. It's very simple And there's one included in the sample project that that should serve as a good template The horizon team keeps a registry of of plug-ins. It's really just a file where they list everybody who's working on a horizon plug-in It's a helpful communication mechanism. It lets people know that your plug-in is out there They can be aware of it as you start work and you have a repository available take a look there Register your plug-in so the horizon team knows you're there My team has worked on We're here because we worked on a load balancer as a service v2 angular js plug-in And so a lot of our sample material was taken from that plug-in If you have questions about how to do more advanced things after you've worked through the tutorial I think our plug-in is a good place to go and take a look and See some more advanced usage of how to really fill out a table or do a more advanced form And so again, here's the repository for the lab There's there's a Horizon tutorial the horizon team has written a tutorial sort of their perspective on how to think about angular plug-ins I think you'll find it's very compatible what we've talked about today And our teams new trying neutron albast dashboard plug-in is available again. Here's the URL. I Appreciate your time working through the lab today. It's been a pleasure. I hope you learned a lot and Angular goes well for you


Meantime, the action-aligned House of Representatives candidate for Eboni Ohoku Federal Constituentry, Chine Du Ardum, has defected to the Labor Party in Eboni State. Ardum defeated or defected, rather, alongside the state women leader of the party, Ijei Ngozika, and over 100 loyalists. Speak in with newsmen shortly after the other faction that took place at the Nkago Ubala Grand Arena, located along Ode Abakaleke Inui Expressway, that said their former party, the A.A., has no future and plans for the people of Eboni State. The defectors revealed their preparedness to collapse the entire structure of the action aligned into the Labor Party ahead of the elections. Now, responding, the gubernatorial candidate of the Labor Party, Edward Nkago, said that the competes have been accepted and adopted as party members.


On February 8th, 2018, a retired man living in suburban Georgia named Henry Norris was watching the evening news in his bedroom when he heard what sounded like a bomb go off inside his house. A team of more than two dozen police officers had set off flashbang grenades. They broke through every door of his home with battering rams. Norris, who was nearly 80 years old at the time, told the officers about his bad knees and his heart condition. One cop thrust him to the ground where the police kept him for several minutes. They arrested him and took him out of his house in handcuffs. The officers were doing a drug raid, but they had the wrong house. The actual suspect, according to the warrant, lived in an off-white house with a black roof. Norris's house was yellow with a gray roof, and he didn't resemble the man police were after, who was less than half Norris's age. When Norris sued, his lawsuit was thrown out because of a legal doctrine called qualified immunity, which makes it difficult for victims to hold state or local government employees accountable for violating their constitutional rights. Qualified immunity was first created by the Supreme Court in 1967. The court strengthened it in 1982, when the justices ruled that a victim cannot sue a state or local government employee unless nearly identical misconduct has been ruled unconstitutional in a prior court decision. The rationale is that if there isn't an existing case with almost the exact same facts, then how would public officials know what they're doing is wrong? I think you could compare it to, you know, a person bringing a lawsuit that they've slipped and fallen in a grocery store and are filing a lawsuit. And the court says, have you been able to find a prior court case in which someone slipped and fell on orange juice in the produce aisle? UCLA law professor Joanna Schwartz is the author of the new book, Shielded, How the Police Became Untouchable. Because if it was water in the dairy section, that's not enough. Because how could a grocery store possibly know that they had to clean up water from the produce, orange juice from the produce section based on prior precedent that said they had to clean up water from the dairy section? Qualified immunity is supposed to ensure that government employees have proper notice of what conduct violates the Constitution. But this assumes that police officers are reading case law in their spare time. I aimed to just to test that out, and I looked at hundreds of California policies and trainings and found that officers, perhaps no surprise, officers aren't educated about the facts and holdings of the cases that clearly established the law. There are hundreds if not thousands of them, they couldn't possibly learn all of those cases in the course of their limited training hours. Qualified immunity applies even in cases of straightforward police misconduct. So, for example, when Fresno California police officers allegedly stole over $225,000 in 2013 while executing a search warrant, a federal court ruled that they were still protected by qualified immunity because they didn't have, quote, clear notice that they were violating their victim's constitutional rights. We as a society, whether we like it or not, are providing these officers with their power, their discretion, their badges and their guns. And I believe that we as a society also have a responsibility, a shared responsibility to make those people whole when their rights have been violated under our authority and to try to prevent something from happening again in the future. To underscore how difficult it is to hold police accountable, Schwartz writes about Tony Tempa, a man who died during an arrest in Dallas in 2016. Vicki Tempa, Tony's mother, got a phone call in Dallas that her son had died, a call from a police officer, a police official, but had no information for Vicki about how Tony died. And she called the department multiple times, got different stories about what had happened to Tony, that he had had a heart attack, that he had fallen down somewhere near his car and no straight stories. She then went to the morgue to see him and discovered that there was grass in his nose. How was that possible? It turns out the Dallas police department had intervened during a mental health crisis Tempa experienced one evening in August of 2016. Officers kneeled on his back for about 14 minutes in violation of their own training and he subsequently died of, quote, cocaine and the stress associated with physical restraint, according to an autopsy. But Vicki Tempa didn't know exactly what happened because the police wouldn't tell her. They refused to turn over the body camera footage, which she needed to state what's called a plausible claim, the bare minimum standard to file a federal lawsuit against government actors. If she couldn't get more information on what happened that night, then her lawsuit would be dead on arrival before a judge could even evaluate whether those officers would get qualified immunity. When they filed the lawsuit, they didn't know who the officers were, uh, who had been at the scene and they didn't know what happened to Tony. So they wrote sort of a bare bones complaint that the Dallas police department moved to dismiss because it didn't state a plausible claim for relief, even though the Dallas police department had in their own possession the body camera videos and other information about what had happened in the case. Vicki went through a three-year legal battle, which finally forced the police to turn over the footage in August 2019. Only then did she have enough facts to write that plausible claim. The idea about this plausible pleading standard is to give defendants notice of what is being alleged against them. Well, the Dallas police department had all the notice in the world about what their officers had done and yet used this tool to try to get the case dismissed. Those Dallas police officers originally received qualified immunity. That was ultimately overturned on an appeal and the Supreme Court confirmed in 2022 the Tempest family could finally sue the police. But it took six years for Vicki Tempest to get there. The Supreme Court and state and local governments across the country have created barriers to relief in these cases at every stage of the litigation process that makes it very difficult to win in these cases. Justice Clarence Thomas has critiqued qualified immunity as an example of legislating from the bench while Justice Sonia Sotomayor has said it allows police to quote shoot first and think later. But some consider it necessary to protect relatively low-paid public employees who can't be too afraid to make mistakes. Policing is obviously a dangerous job. It is often low-paid. How do we know that allowing officers to be sued isn't going to provide yet another disincentive to policing in the first place? The idea that's been commonly stated that officers are going to be bankrupted for split-second mistakes without qualified immunity bears no relationship to reality because officers are virtually always indemnified by policy or law, meaning the employer pays for those settlements and judgments. And the Fourth Amendment protects against those split-second mistakes. So they don't have those things to be worried about. So let's say we adopt some of the reforms that you propose. What's stopping Joe Schmo down the street from sashaying into the federal courthouse because he has an axe to grind and just filing a suit? Joe Schmo can sashay into the courthouse today and file a lawsuit. Joe Schmo with his frivolous lawsuit is not going to be able to find a lawyer, I'm guessing. Part of that is the way in which they are paid for these cases. They are paid if they win, usually a percentage, a third of the recovery. If they lose, they're paid nothing. And these cases are far more complicated and time consuming and expensive to bring than your average slip and fall case. So I've talked to a number of lawyers who typically do take personal injury cases or medical malpractice cases, take their first civil rights case, invest tens of thousands of dollars in their time, lose everything and think, I'm going to go back to my other line of work where I'm more likely to be able to make enough to keep the lights on. So you're saying a lawyer could spend thousands of hours of his or her time working on a case and get paid nothing? Absolutely, absolutely. Lawyers do with regularity. Anytime a plaintiff's lawyer brings a civil rights case that goes to trial and they lose, they will get nothing for their time. Overcoming qualified immunity doesn't mean you've won your case. It simply gives you the right to take your claim to trial and ask a jury to determine if damages are deserved. While qualified immunity only applies to state and local actors, federal cops receive an even more robust set of protections and are shielded by what essentially amounts to absolute immunity. Take the 2016 case of a then 70 year old retired cop named Jose Aliva, who arrived for a dental appointment at a VA hospital in El Paso Texas. When unprovoked, according to surveillance footage, federal officers placed him in a choke hold and contorted to leave his hand behind his back, damaging his shoulder and requiring two surgeries. He was prohibited from suing because the cops were acting at neither the state nor local level. These sorts of abuses have put police under an intense scrutiny over the last several years, but Schwartz concedes that law enforcement conduct has improved in recent decades. One indication of that is that fatal police shootings are down nationwide. In New York City, for example, officers shot and killed an average of 62 people a year from 1970 to 1974, which went down to nine fatal shootings a year from 2015 to 2021, according to data compiled by Peter Moskos, a professor at the John Jay College of Criminal Justice. I do think that policing has improved in important ways. My inquiry with this book is not to set out to canvas all of the ways in which policing should function, but really to ask the question of what kind of justice is available to people when their rights are violated. It may be that people's rights are violated less frequently now than 10 or 20 years ago. We don't have comprehensive data, but I think everything that we do have suggests that that is likely true. But it remains true also that our systems for holding police accountable in those circumstances in which they violate the law and people's rights really fails to offer justice to a meaningful percentage of those people. So how do you respond to people that are saying, you know, we essentially expect police to be James Bond and just be the perfect shot? I don't think that our legal rules demand perfection from officers. And I think it's far from it. In situations where courts say that there could be a constitutional violation, there could be excessive force. Ultimately, again, this is a question for a jury to decide whether the force used was reasonable. There are many, many people whose names readers have never heard of, whose lives have been turned upside down, if not snuffed out, by law enforcement, and then have their efforts to seek justice in these cases denied. I think that is a caseload and a cost that we as a society should be willing to take on. This is the moment to sit back calmly, look at the information, look at all of the information, and design a better future.


This paper presents a new approach for optimizing the window length of steady-state visual evoked potential SSVP based brain-computer interface BCI. This approach is based on analysis of covariance and COVA, which is applied after feature extraction by conventional training free SSVP recognition approaches. The proposed method significantly outperforms the conventional approaches with fixed window in terms of accuracy and information transfer rate, ITR. It is also applicable to various SSVP-based BCI paradigms based on the criterion of significance level without offline analysis to find optimal hyperparameters. This article was authored by Taejun Lee, Sunkyun Nam, and Dongjin Hyun.


Welcome everybody. This was last minute exercise on Arduino CLI. So Arduino CLI is a technology preview by Arduino, which basically replaced the Arduino IDE. So who here has never used the Arduino IDE? Okay. And who here has never used Docker? Okay. So what I'm going to show, I hope at the end, if the internet connection is fine, is how to use GitLab CI. So GitLab CI, the original plan was to connect GitLab CI, build the container with the SDK, blink a LED, and package everything, put that into a Docker registry of GitLab, and then tell Raspberry Pi connected to the ESP8266 board that you can see here. So I don't know from far if you can see the LED blinking. So the typical way is to use the Arduino IDE. So the interesting thing is why use Docker in this setup is to be able to do caching. So one of the advantages of Docker is it does when you are developing, when you try to rebuild your Docker image, it uses layers of caching. And so previously I worked in a company like 10 years ago where I was scripting containers. And when Docker came out, the Docker file was very similar to the scripts I was doing. One of the disadvantages of my approach was if you had to change one comma, it was a 45 minutes rebuild. While with Docker, if the comma you change is at the end of the Docker file, then it would cache everything and just use the cache way faster. So here I have a simple, I use a simple blink. So I'm not going to, the code is very simple. So everybody knows that. So I took the Arduino CLI project and added the Docker file. So I've separated the structure in two layers. So the Arduino CLI is basically a Go application. It's a Go application, so I took the examples and basically in the first lines I compiled the Arduino CLI binary as a static and then in the second step, so this is called in Docker multi stage build. Basically I want to take the Arduino CLI binary and put it in another Alpine layer. So this is, I copy the Arduino CLI binary into my user bin. And then in order to use the support for the Wemos D1, which is an ESP8266, I have to specify CLI config.yaml, which contains the link to the, when you have to add a new type of board, you have to specify which URL, JSON URL, which will fetch the SDK. And then do an Arduino CLI core update, install the SDK, and then one thing I found during my development is that I tried to put that part into the second Docker file, but then it was pulling the SDK again. So I just put a blink example so that everything is cached. And then in the second example, I create a blink tool where I don't have this pulling of the SDK anymore. So I measured it was, this whole thing is 500 megabytes, and it's ghosted on GitHub. So if you do github.com.slashdubab. Arduino CLI, Arduino CLI, you will find the project. And there is, I put everything in the Docker file branch. So feel free to have a look at the code. So if you do Docker images on my disk, you should see that there is an image here. It's a bit bigger, an image called Zubab Arduino CLI. So if you do Docker search, Arduino CLI should find Zubab image, which is 1.2 gigabyte. So what I have prepared here is, so the actual, maybe I can talk about just the standalone. Here I've installed the Arduino CLI on my laptop, not inside Docker. So here if I have, here I'm blinking a light every 10 seconds. So this is 10,000 milliseconds, so 10 seconds. And I made a small script that basically calls the Arduino CLI, compiles everything and then do a flash over my DevTTY USB 0 here. So it throws this error, but it basically continues. So now it's flashing for people who are familiar with the Arduino. So now it should blink every 10 seconds if everything is fine. So that's, the flash has been successful. So that was basically, I listed the board, I created a new sketch. It's going to create a directory in the home Arduino blink 2 and I copy my blink 2.ino file over there. Then it does a compile where I have to specify my V1, my Wemos D1 mini board with the code I want to compile. And then it does a upload. So I did Docker file. So before I showed the Arduino CLI outside of Docker, now I want to use everything in Docker because my goal is to put everything into GitLab and GitLab has standard, let's say, container flow for deploying containers. So from the SDK which I called Arduino CLI, there's a small bug which I reported where you have to fix a Unix user called root. I copy this blink 2 to, here it's a slash root, Arduino blink 2, blink 2.ino. And then I launch the compilation. And so if everybody is familiar with the entry point, it's the entry point when I do Docker run the name of the image, then it should, by default, take this command and execute it. So when I will do Docker run my blink 2 image, then it will do the flashing. And inside this image, the binaries will be in the image. So this is something where it can be transported, like you give it to someone, you just say, hey, take this image and it will, the person can just run the image and have the same flashing results. Okay. So here I made another small shell script which is build, build and run. So the build is just doing a Docker build. And I call the image blink 2. And when the run is just doing Docker run. So in order to access the cell port, I need to be in privilege mode. So this kind of root access and image name. And I have another script which is called build and run, which is basically getting the time of the build, getting the time of the run. So if I modify my blink 2 and put it to 5 seconds, it's going to copy the INO file, do the compilation. So depending on the, sometimes it's fast, sometimes it's not. Okay. Normally there should be a time somewhere. Yeah. So 25 seconds to execute. And then it's going to try to flash it. Sometimes it's fast. I've been to situations where it takes 45 seconds to flash. But it basically does the same as the previous example, but everything in Docker. Okay. Fine. So we have, for the build it took 25. And for the run it took 25, so it was like 50 seconds. So the next step is to put that, everything in GitLab. So GitLab, since there was Microsoft acquisition of GitHub, a lot of people looked at GitLab.com. The advantage of GitLab is you have this CI, GitLab CI, which GitLab still doesn't have, where you have to use external service like Travis. And it's also the hosted version, it's the enterprise version, but you can also run the community edition on your, let's say on-premise, on your laptop. So here I used the, let's say the hosted free version. And what I did was, so you have to, next to the Docker file, you need to have, where is it? You need to have a .GitLab CI YAML file. And when you go into the web interface of GitLab CI, you create, you say a new file, and then you can choose .GitLab.YAML, and you have pre-configured template. I just took the Docker file, which is the standard one, and modified it a bit, so the first ones are the same as the template. And then I tried to use a Raspberry Pi and the ESP as a standalone. My first attempt was to send this slash-def-tty-usb-0 to a server on the internet where I could run a small Kubernetes cluster. And for that I used Ser2Net, which is a Serial2 network, Serial2 TCP program, and I could successfully send it and create a slash-def-tty-0 on my server with SoCAD that creates a virtual dev entry. But unfortunately, when I was using the Arduino CLI upload, it was throwing some weird errors. So it might be that I misconfigured somewhere some parameter in Ser2Net. So I didn't manage to get that working, so I rolled back to a design. Maybe I can show here in the diagram where I used the GitLab, which is connected to runners. So one of the issues, one thing I wanted to have was the caching because on my laptop it was cached. And the GitLab has, by default, shared runners. So you have eight runners available where it shoots the build. But they have the policy to not do any caching for security reasons that don't want to do any cache. But so I tried to install a small digital ocean machine with one gig of RAM and put the runner over there to try to have this caching mechanism of Docker, but I didn't succeed. So it means that the time of the CI will increase because it doesn't use the cache, so it's pulling one gig of the SDK for each build. But that's going to be a room for improvement for the near future. They provide GitLab compared to the community edition. They provide the Docker registry built-in. So on the right side of your GitLab, you see a registry entry. And I tried to put a small communities cluster, whether it's Minikube or KS3S, which is a stripped-down version of communities where they removed lots of features on my laptop, but it was not that stable. So at the end I said, okay, I do an SSH tunnel to my laptop which is connected to the ESP. Okay. So yeah, let's have a look at the GitLab YAML again. So here at the end in GitLab CI, in the settings of the project, you can put some environment variables. And over there I put a SSH private key. So when you build, you can get these environment variables and redirect to an SSH key file, fix the permissions, and then the GitLab runner is going to SSH to some host called zoobab.servio.net. So Zoobab.net is a free, let's say, free service with Linux binaries and everything just using simple SSH. But server-side, they have provided the binaries but not the source code. So that is used here in my tunnel.sh. So tunnel.sh is doing just a SSH remote port forwarding. So here I've said, yeah, I will try to modify the code. So if I go on files, I have my blink.ino. And I will put the delay to two seconds. And there I calculated that it takes roughly three minutes. So it triggered the CI CD pipeline. So the pipeline itself is split in two phases. There is a build of the Docker image and then there is a deploy. The deploy is basically SSH-ing to my machine and say, hey, pull this image to be the last one and then flush it. So the build is running. It's pulling the SDK. So maybe I can talk while it's building. Normally it should take three minutes. I can talk a bit about the GitLab, about the other problems or which other improvements I want to make. So I tried to, I made some simple YAML files. So with MiniCube, there is MiniCube, which spawns a VM. And I was looking for how to take this flash drive USB, TTY USB 0 on the host and put it inside the MiniCube VM, but I couldn't find out. MiniCube has also VM driver none, which is basically spawning community cluster without any virtualization. So if you have a Docker running, it's just going to spawn a list of Docker containers. But on that one, I don't think I could see the slash def TTY USB 0. So I tried another one, which is called kind, which is Kubernetes in Docker. And there it basically spawned one container and on that container, I could see the slash def TTY USB 0 from the host. And when I would spawn a container in privileged mode, I could see also the slash def TTY 0. But when I run, on here I can show maybe the YAML file for the flashing, basically saying, I spawned me a container with that image. Then my cluster blew up, so I still have to debug it. But basically the idea is to have a GitLab CI connected to a community cluster, whether it's local or in the cloud, and either send the serial port to there or having directly the community cluster running next to the machine where the hardware is. In the past, I've done some similar things with OpenWRT. So taking the building, the whole thing, put it into a big Docker image. The SDK right now seems to be fixed. So if you want to do a basic package for OpenWRT, you could use the same approach, which is to have the SDK in the upper layer and have your code, which is the package or the code you want to build for OpenWRT in the second layer. And nothing prevents to use GitLab CI as well. So where is it now? It's still running for two minutes. So the first part has succeeded, and the deploy has succeeded as well. So now I said it was how many seconds? Two seconds? So yeah, now it's two seconds. So you could see in the CI that it has been flashed correctly, that the pipeline says passed. If I can zoom in. Oh, yeah, here. And it took three minutes to complete. So this is definitely way longer than 50 seconds I had on my laptop because it has to pull the one dot gig each time. So I think I measured. It takes 50 seconds to download this. So you can remove it. But the advantage is when it does the pool in the deploy part, when it did the pool. So you can see that here it said all the... This is on my laptop. It says all the layers already exist and basically downloaded just a few layers which corresponds to the compile part on basically the last step of the process, but the rest was already cached. So it gained a lot of time. What else? Yeah, so that already showed. Yes, so there is also one issue. I tried to use GitLab CI, including for the SDK, but I couldn't figure out how to have the integration with both. So for your information, the Docker Hub is not integrated with GitLab. So you can't... In Docker Hub, if you log in, you can quickly create a build if it's hosted on GitHub. But if it's hosted on GitLab, you can't. Okay, some other ideas. I have tested another board for the BluePill, which is an STM32-1.0.50 board, much more powerful than the standard Arduino.  The project is called Dubboot. And it's a web interface which is using WebUSB and you can reflash directly if your browser allows it. You give the permission and it can reflash directly your USB device. So I also found another WebID called G5GS or something like this, used by processing where you could have, let's say, a better IDE and maybe a direct connection to your USB device. This has also some security implications, but...  Yeah, one option would be also to take the INO file and just send it to the container so that you would just wait and take it on the fly and build it. But it doesn't fit with the mantra that everything is container and reproducible. Yeah, I also used another project called G-Link which is taken in ESP and use it as a serial to TCP bridge and the idea would be to take a second ESP hook it there, send it to a server, a console server and then from there do the flashing. Another idea is to integrate the over-the-air update for the ESP. So the ESP has a Wi-Fi so you could flash the thing over the Wi-Fi. Yeah, so in the case of Raspberry Pi, use a QMU wrapper. So the binaries, all the containers here are AMD64 but if you want to run them on the Raspberry Pi, you might look at QMU wrapper and that's basically it. So if you have any questions? One of the concepts of CI-CD is being able to test what you are doing. In your case, I see you are preparing or flashing but how do you control the feedback loop to know what your push is for example? So for this example, it's the B-Link but if you look at the GIT history, I've added serial messages saying I blink at that speed and so if you would a third test step, you would just check the serial console if you see those messages for example. Are there any virtual images? May you have another in MIMU if that's simply running on QMU or some virtualization so that you could, instead of flashing something into real hardware, just test it on an invitation? That I don't know. Emulation of the MCU? It probably exists but I don't know by heart. I don't know. Well, thank you.


I knew your confident guy, but how good was it to see more balls coming your way? I know you don't want to see a teammate getting injured. You have to leave the game or anything like that. But I hope I have some opportunities for you, obviously. Yeah, that's what we are here to do, make plays when they come our way and take as much as the opportunity presented to you, take advantage of it. And that's what I'm just going to do every Sunday. And yeah, it's part of the game.  You know what I mean? And it's unfortunate, but that's the part that comes with the game. Talking to Arthur, he was really praising you for your versatility and how you're willing to do a number of different things and a number of different ways throughout the game. What's pride do you take in that? A lot. Do a lot of different things as a tight ender? A lot. Just being able to display my abilities and my talents in a lot of different positions, that's a fun job. I mean, just being able to line up in a lot of places and do a lot of things. And ultimately, most importantly, help our team win. So as much as many possessions I can play, as many spots they can line me up, I'm all for. So many rack plays, man, so far this year. I mean, does your mindset change when you get the ball in your hand?  Man, I become hungry when I get the ball in my hand. That's just what it is. As every ball carrier should be, that's the mindset. Every ball carrier should have. I mean, it's nobody that can stop me. That's the mindset you've got to have as a ball carrier. Just making plays, breaking tackles, and ultimately trying to get that end zone. What are you learning about Tampa's defense? They're a really good defense. Very good defense. It's going to be another challenge for us this week. They've got a lot of athletic guys, guys that fly around, guys that have a lot of high motor guys, and we're going to be ready. We're going to prepare, put in a great week of practice, and we're going to be ready.


As the sun rises over the capstone, announcing the end of our college journey, we envision a future shaped by the memories of our past. Memories that began four short years ago when we start our path at the University of Alabama. It was our first day of events. It was so much fun. I didn't realize there was going to be so many people. I think it's cool how many different stations they have set up with different organizations. I'm double-mandering in dance. I'm really excited to meet the dance people and get prepared for my life and your career path. I really just want to give it all I have with my classes. I really want to take advantage of all the student resources we have here on campus. I think it'll really contribute to my success here. After just one week on campus, we realize this truly is the place where legends are made. And we immediately proclaimed our role in upholding that tradition. We embraced campus life, met new people, and built a camaraderie through the social and cultural experiences that make life at UA unique. We got involved during clubs and organizations whose unrivaled dedication created miracles. Providing support for Tuscaloosa and beyond. We were ambitious, vested in achieving our goals and being the best we could possibly be. We explored our world and all that's beyond it. Driving innovation to transform what was once an idea into a reality. A reality that, with our help, can be enjoyed by all. But most importantly, when all seem lost, we adapt it. Never faltering in our commitment to remain tied together. While it does seem a lot has changed these past four years, our journey ends the same way it began, as champions. So, as we walk across the commencement stage, take a moment to reflect on the challenges we've accomplished and the memories we've made. Memories that will accompany us, influence our future, and empower us to become the next legends of the University of Alabama.


So, without further ado, we are going to dive into the open process automation topic. And to kick that off, I'm just going to have a little chat with a colleague of mine, Anil Ali. So, Anil is the forum director for the open process automation forum of the open group. He completed his undergraduate work at Texas A&M and is an MBA candidate at the University of London. He's based in Houston, Texas and has served in various engineering and business development roles within the process automation industry over the last 10 years, primarily working with manufacturers and system integrators to deliver solutions to end users around the globe. And you'll hear how relevant that experience is when we talk about what the forum was doing. So, first of all, as tradition would have a warm welcome from the open group for Anil Ali. You'll have to take my virtual applause, but welcome, Anil. Great to see you. Yeah. Thanks, Steve. So this is a day that you've helped put together, getting the messages out that we want and interesting topics for people. So tell us a little about the open process automation forum in the open group and what we're doing. So, good morning, Steve, and good morning, everyone. Thanks for the introduction. So the open process automation forum, Steve, is a consortium now of over 100 member organizations that have gathered to contribute to the development of the O-PASS standard. And I think that it's been ongoing. It's been an ongoing initiative now for nearly five years and even longer. So in the making, kind of in the run-up to beginning development of the O-PASS standard. Right. Right. So you mentioned the standard. That's clearly the main focus for the folks working in the forum. So tell us a little about it and, importantly, why do we need it? Okay. So the O-PASS standard, Steve, is the deliverable of the open process automation forum. And the standard is meant, is purposed to address interoperability and application portability and system orchestration. And kind of those are the three main themes, you know, for versions of 1.0, 2.0, 3.0. But more importantly, it allows current owners of process automation systems to inject new technology and it gives them more options for selecting best-in-breed technologies when looking to swap out components or upgrade or things like that. So that is what the O-PASS standard will accomplish. Okay. That's great to hear. I remember the early days of getting it going and some of the real hard business requirements and challenges that they were for the industry. So where are we at in the development of the standard? What stage are we at? Sure. Okay. So where the O-PASS standard now is in the stage of development is, and I'll just recap very quickly, you know, in 2019, the forum published version 1.0 of the standard, which was purposed to address configuration portability. That was the overarching theme. And then in 2020 and this year in 2021, the forum released versions 2.0 and 2.1. And when combined, those two versions of the standard address the theme of, sorry, configuration portability. Version 1.0 focused on the theme of interoperability. And the forum is now beginning the work of writing and developing version 3.0 of the standard. Purpose to address. The overarching theme will be system orchestration. So it's an exciting time, you know, within the development and the life cycle of the O-PASS standard.  Yeah. Yeah. It's a great piece of work so far and still much to be done. So what's on the horizon for the work on the standard? Sure. So version 3.0 of the standard, Steve, will have the overarching theme is system orchestration. There will be 3 underlying themes that will be addressed, 3 additional parts that will be added to the standard. Part 7 will focus on physical platforms, the actual physical manifestation of computing modules, computing resources and what that will look like. And part 8 will focus on application portability and part 9 will focus on system orchestration and kind of like automatically provisioning software and patching and updates and kind of things like that. That we'll get more into detail later on today. Okay. Good. Good. So it sounds like a lot of work's been done. How big is this standard and how can our audience get hold of it if they want to dive in? It's enormous. We're standing at just over 800 pages now and that's pure technical standard. And there's not one person that can consume the entire standard so it will take multiple engineers from organizations to consume that standard. It spans many different technical areas within process automation and control systems engineering and so it's an enormous standard and the audience can obtain a copy by going to the open group library and it's free to download and you can get a 90-day free evaluation copy and I recommend everyone to access it that in that manner and to get a copy of it. Okay. And hopefully many will. And when they do, they're bound to be questions. And I know there's a lot of questions that get worked on in the forum itself but for those who maybe aren't members of the forum, how would they get their questions answered? That's a really good question. You make a very good point, Steve. So when you're navigating your way through the OPAS standard and the 15, 16 different parts of the standard and the 800 or so pages, they're of course, they're bound to be questions of a technical nature and maybe also not of a technical nature as well. But folks within the industry or the readers can go to, they can send a query to ogspex at opengroup.org and that will be received by myself and we can distribute those within the forum to Ponderon and that's a really good avenue to get technical and non-technical questions answered while reading the standard. Right. And we really do have in this group, we really do have a great gathering of industry experts from with all sorts of specialties and experience. So it's a great place to get those answered. So okay, well, perfect intro to the day, Anil. Thank you. And I know we'll see you later on the first panel and then I think you're going to moderate the second one. So we'll see some more of Anil today, but in the meantime, thank you, Anil Alley. Thanks, Steve. Okay. Great. Thanks, Anil.