 Okay, good morning. My name's Ian Stewart. I'm up from Hamilton and if you're in Hamilton We have a Hamilton Python user group. We meet on the second Monday of the month So if you're ever staying in Hamilton on a Monday night Then please come along. There's no cover charge or anything like that Then you can find the details on meetup.com Okay, this presentation is also posted on GitHub you can see the account there and If you want to download not only the present the slides which are in PDF format as well, but there's about 14 little demo Clips of code there that you can Use and the idea of this presentation is that the material is sort of a reference document So you should be able to using this slide show get yourself up and going in running work First thing is doing client-server Programming model the second one is that you'll be using the desktop bus for the communication and You'll be using the pi D bus python library And if you want to you can chuck in a bit of system D. So we've got to cover these things today In 30 minutes, so I'll do my best Right I won't go through all the parts of the presentation I'll just get on with it, which is we'll just look at the four Four components to the that we're looking at If you think of the client-server model, I'm pretty sure it came around with the beginning of the internet Where we've got clients out there communicating through the internet to a web server so your browsers like Mozilla Firefox and Chromium things like that connect them through the internet Another version of the client-server model can be internal to the computer where the software bus is is internal inside System and your client applications talk to the server application When you're doing this, there's probably something going on in the background like a message bus demon to take care of routing and This will be transparent to you and it'll also be launched automatically in the system boots So I just pointing it out that it's there, but you don't really need to worry about it. The D bus itself is a software bus that allows computer programs concurrently running on the same machine to communicate first stable release was 11 years ago and it was The work of three chaps two of them from red hat there and the latest update to the spec was this year at Zero dot 31. So it's been about 20 releases over 10 years. So every About two a year and you can actually go to that specification there. In fact, do you will need to Later on you'll see why okay? The D bus Just some of the aspects of it the free software Desktop Dot org project developed a free and open source software library called lib D bus that you may have heard of it's pretty standard distribution and When we're working with the D bus there is two buses that we actually can work with once the system The ones called the session bus will start off Looking at using a session bus and then later on do some system bus stuff It's been implemented the specifications being implemented using for example GD bus and there's also the QT libraries have a QT bus SD bus is system demon bus Colonel D bus and there's more right. So I'm going to focus on the G D bus and I guess you guys are familiar with you've got the Gio is a Bunt of C programs which the G object library can get to and There's a Python binding which allows you to go into the G object and then get to the GIO See code so anyway, that's fairly low level So hi D bus sits on top of this as a Python wrap rapper for getting to these Gio libraries that can do the D bus transactions Okay, so Pi D bus was created by this chap Linus from Poland. This is his web web page where you can see the source code He uses the MIT license if you've got a recent Distro, then you just be able to do a direct install like that Otherwise, if you're using pips free then I would suggest putting a target and And making it system-wide because if you later using the system D bus You'll you want it to be able to be controlled by route things like that. There's got to find it If I if I just look at what gets downloaded in the package a total of 18 files And they're all Python files and about 1.8 KV bytes per file There's a black duck There's analysis of code Here you can see he started the project around 2015 been reasonably stable the last 12 months and Only 1200 lines of code and It shows up as 81% Python the HTML. I think it's the comments within the within the code And so you might say well why pride ebus It's it's a high-level approach to doing this These transactions it's simple to implement Many aspects of debuffs Automatically assigned so that makes it even more simple Development can focus on clients server code Yeah, and and you don't have to worry so much about the intercommunications. So yeah You can also then have modular software development guys can be writing client code Other guys can be writing server code that approach and the data integrity My understanding on the debuffs is assured. So you're not sitting there checking that the validity of the data that comes through This is quite a common diagram that you'll see for trying to explain how the The debuffs works and I think the green is meant to be clients and the pink is meant to be Servers and then this breakdown of a server We have what's called the well-known name is there on the outside and then we go to the object layer and then the interface layer and then we get down the message and Also over here. We've got unique connection name when you're using pie debuffs you're basically Interested in the the bus name here or the well-known name and in the method Okay, all this other stuff just sort of gets You don't worry about it, which is kind of cool To get things working. There's a tool that ships called the gd bus tool It's included with most Linux distributions. It's written in seaside. I assume it's available in other oasis This tool will allow you to simulate method calls to a server install the server And in debug it before you you pop around with a client rather than have to a client in the server That are both buggy and you're trying to make make them work You get one working with this tool and the other one working with the tool and join them together So it allows you to test the code in isolation These are a couple of links to this particular Utility so let's start developing a server application and we can do Method calls to the server right and there's four types of method calls the simple one has no arguments So if you had a server that's playing music Then you would just send the client would just send stop or play or rewind It doesn't have to say rewind one minute doesn't need to send any data. It just sends a method with no arguments likewise you can send Send the client can send with an argument or data or Likewise the The client can not send any data, but the response from the server is to receive some data and The fourth alternative is both sending and receiving data for every method call Okay, the different from Python here the data type is static. So it must be declared You have to put in type equals s to indicate its string data you're passing I For 32 bit integer D for double precision and things like that. That's why I said you'd be back to the specification It's about ten different Codes that you need to look up to know Which data type Depending on which data type you're using okay, so we're going to write server demo number one and The first thing we'll need to do is from pie bus. We'll have to we've got to import the session bus. Okay, and We've instantiate it there and we've we set up a constant here of the well-known name for the server Okay, and when we go to start our program we publish the the bus and The next little bit is on the next slide to keep the whole server running. We're going to use the glib main loop and this this keeps it keeps it looping okay, and over here is where we Define the the services So as you can see here This is a doc string and then I've got debuff equals as a key word The it's like a reserved word that the pie debuff guy is flogged He you'll see examples where If you just make that the doc string if there's nothing between there and there it will still work So he kind of flogs the right to use a doc string and he uses it to actually define his code Which I didn't quite like so I found this keyword and I prefer to put the keyword and then have a doc string above it Okay, so I'm just going to have a little method on the server called server no args So it's going to receive my place stop or rewind commands Okay, and in fact what it what I'll do is whenever the client sends Calls the method server no args. There's nothing no arguments come in and all I'll do is print This is message one two three or whatever so using what we start the server as demo one and Using gd bus tool. We do a call. Okay. We're using the session bus We have to put in some of the stuff that I said we normally only have to worry about that But we have to add a bit more to keep gd bus happy and then right at the end. Here's my call to the method called server no args and each time I Redo this little tool it will produce as a message from the server Excuse me. Okay Next method was to get some data from the server So we're gonna have a method name called get time stamp and this time we have to say That it's sending a double precision but a data and it's the direction will be out of the server to the client Okay, so we here's our little method here get time stamp No input and all we return is time dot time function and When we run the server using this tool we we say get time stamp and back comes a time stamp We run it again and back comes a time stamp. Okay, the third method is we're gonna randomly Send a name to the server So we're we're expecting a script. We're gonna call it greeting. It's the method and we're expecting a string To be coming in to the server. Okay as So down here is our method greeting and now we've got name here So the data that comes in will be assigned to the variable name and when we go print. Hello and name Then we should see here. We're randomly We're sending names like Bob Fred Wendy. Okay, and the server is picking up the name and putting hello in front of it Okay, and the fourth one is to be able to echo so We now have to define two arguments here one for direction in one for direction out so what we're doing string in both and string out on both occasions and If we look here at echo string We're just gonna what the input string we're gonna turn it around and send it back out as and When we run our little tool we start the server run our little utility and when I say Call the method echo string to hello world Then it will come back with hello world once upon a time Like that. Okay, so that was doing those That's checking that the service work. The next thing we've got to do is is write a client. Okay, and There's only really one more step Or that one step that's different. We again we import the bus we prefer and session bus and we instantiate it here we've set up the the constant for the name of of the bus we're using and We create the server object Okay, using the get under PI D bus this get function and It instantiates the server object Just down here. We're going to When we start the program we're gonna Just every two seconds we're gonna call this little routine on the client and the server object will call the method server no args and We are gonna look for a reply. Well, then we're not expecting one and So that that will just and then we'll come out of there in two seconds later We'll come back and do it again so we start the server and This time when the client starts every two seconds it makes a call the server no args method through the session debuffs and Each time it will produce a little message on the console of the server in this case where we're getting the timestamp so The only bit of code a change is that Every two seconds. I'm gonna say Get the timestamp. I don't have to send anything to it But the reply will come back and we'll see what type it is and the timestamp data will come back So you can see the data type as a float that comes back and And this is the timestamps and they're going up incrementing by two second intervals the third type we send a random name from the client to the Server and the server is gonna just say hello, whatever your name is so we start the client here the service already been running and Here we go. We go to the greeting Method and we pass the name that we've randomly selected from this list and That name will get printed out by the server You remember the fourth type we've got an echo so We go backwards The fourth type we're just again going to pick a name We'll send that name to the server and the server will turn around and send it back So when we run that so the reply coming back here, this is a G code from server So name sent to server is Fred name echoed is Fred Okay, so that's it with with the Methods there's another feature of the bus and that's called to emit a signal of the D bus Okay Here's a piece of server code designed to emit signals and we've got One more line in our import statements where we import the signal class from the pi D bus code library Okay, and I don't think this and then down here We we just instantiate a wee bit differently and we bring out An object called emit here and we're going to emit every Two seconds we're going to call a little function called timer So we go to the bit of code that sits in the middle between here then when we set up Define our service. We now have a signal name called integer signal and the argument type is I and For integer or 32 bit and it's signed integer and We also have to instantiate integer signal equal the signal from the pi D bus library A little timer that we come to every second randomly gets it a number from zero to a hundred and it emits it here Okay, so let's see using our G D bus monitor. We can monitor the session bus should just carry on there and We start the server so at randomly emitting a integer value here and Using the G D bus to monitor it. We see that These are the this is the data being picked up Okay, so the we know that our server is is emitting okay over there The session D bus now we need to write a little client to subscribe and receive this emitted data emitted signals so We have to import we don't need to import anything more we were already importing the session bus We have to include bus dot subscribe Okay, and it will whenever once we've subscribed and applied the filter of What we're subscribing to then whenever a signal comes in that that matches that filter We will trigger call back signal emission. So this piece of code we we pass all the arguments of what came in and we hunt through it and argument number four argument number four is The data so the client will see random number and when we run our code This is the server emitting and that the client is picking up these the same numbers here The first one's missing because I start the server code and then I go to the other console start the next one It's my delay there. Okay. You probably don't believe you've heard so I'll just try and prove What I'm talking about We're gonna run server demo number six which combines everything Together is one thing. So when I start this server demo number six It's emitting the random numbers. Okay, if I go over here and I say just use the gd bus Monitor then at the moment the monitor can only monitor for What's emitted on to the bus so you should see We're emitting these numbers and the same numbers are being picked up. Whoops Okay, so now let's if I actually run a client Then the as well as this it's receiving these numbers now, but it'll also do the four Things so this is a message in the hello Wendy when we send things from the client to the to the server and when stuff comes from the server to the client we've got The timestamps are here coming through every four seconds of this I think yeah, and And I'm echoing just a letter instead of a name. So so It's not all smoke and mirrors Okay, that was all about using the session bus, which was like local to each user I'm now going to just talk about using the system bus. Okay, and This is this was it here. So we had like two session buses and they're independent of each other so What we want to look at with the system D bus is we could have Server applications here and different users can get to the to those Applications, okay, meanwhile, this is sort of happening in the background this message demon I think thing another thing that can happen is we want to pass the whole thing over. So for example, whenever the server starts up we want system D to launch the survey application and or Potentially a client application could also let's say back up It could be a client that runs every day or something So so that can launch and then users can log in and make use run client to make use of that So we're going through the system D bus So here's just how to set up the system D bus I'm in this case. I'm going to create a little Folder demo slash test of my home directory and and put in there that Server six, but I'm going to call it server seven same piece of code The only changes I have to make is I change the session bus here to be system bus Okay, and and I instantiate the system bus before I was instantiating the system so those are the only changes between version six and version seven of my little server code and when you run it, of course, it doesn't work and When you dig through a page of some of errors you get this thing here D bus era due to security policies And I can assure you putting sudo in front doesn't help So you have to look into why that's happening And you'll find that the D bus is configured in a file in user share D bus one system comp is Gets run every time the system boots and the D bus is set up And there's a note in there. You add a system local comp Rather than edit anything directly in this file and you can see the code tests for is there a ETC D bus one system local comp included on the system and if there is go run it and So to make it the easiest thing is to do is just copy the user shares. We've got comp to System local comp in ETC D bus and so we now got this file here, which is Identical and then go through it and chop out all the stuff you don't want and make a little change They call it punching holes into this file So there was deny own equals star and deny send type method core I comment that out and I change it to allow So those are the only two lines I change but I have to pass the whole Frame there's about ten lines missing here if you if you GitHub side if you go there and you look at the server demo seven dot pi File I've actually at the bottom of it in the comment section. I've added Exactly what I like this file is how I set it up Okay, so now when we go to This thing goes backwards. Okay Now we notice I reboot. There's probably a way of re-initializing the D bus but one of the easiest ways is to reboot and When I run my server demo, it's emitting Random numbers and when I start use the GD bus monitor, I'm picking up these random numbers, okay, and To now write a client Again all that all I really change is from pi D bus import the system bus and instantiate it and With now when I run my server as well as emitting the random numbers I'm picking up client method calls from the client So there's five things happening there you're getting your meeting and you're getting your four types of method calls okay, and Probably the last thing is that you want to be able to Get the System D to be able to launch your applications and You'll guess you know about the ETC system D slash system. That's where you put service services that you want Executed in there here. I've created server demo service and I'm saying go here and run server demo 7.pi whenever you boot up the system and I Can test it out first thing I must do is a demon reload and then start system control start Server demo service and I can check the status of it and if I was going to do it permanently So I want it every time it boots then the system control enable Okay, and If we look over here There's a wonderful thing called journal E if you've got journals that are that wide to get all the information that it has in it But if I've stripped off all the time stamping prior to the colon But you can see here here. This was me reloading the demon and then down here. I start up Start up my server Anyway, yeah Server demo service. Yeah, okay started server demo 7.pi Okay, notice my Because I print things my server prints things they end up in this log So I wouldn't actually recommend you write a server application that prints to a console Okay, so just some notes on system D Client applications may also start be started by the system control module An alternative is to insert into the server Code a sub process call to actually start the client So you as you come up you start the server through system D and then do a call within that Code to start your client Having The code in a user count means that you could edit the code Without having to have proof and things like that. So for debugging purpose It's a lot easier to keep things in your local account. Well, you get before you say move it system-wide Yeah, so you maybe your final mission you move files created by server Okay, if you if you've had it started by System D then it's owned by root. So if you're Say you create a log file and you write to the log file if your server application has to do that It will have been created with root privileges. So when you've you know fit want to go and get that log file You're trying to get a root file. You might need proof to get it So you may need to play around with them changing the ownership of the file easy enough to do Just work being a mind Okay, we still got some time Can I just go a little bit more? I've just got some demos Oh cool Okay, okay, I've started the server application and just so that I know it's running it pops out a number every second Okay, and now I'll just Start and the idea is my little server is is controls this brewery or pub You know and and this is the billboard sign outside the pub and it's it's saying that beer is priced at ten bucks and This is an emitted signal from the server and I'm using GTK clients and I'm using the GTK loop and and that's fine You know it works before you saw me using the GL main loop and I'm not obliged to be stuck with that What I can do is have a bar manager come along and he can declare its happy hour and and he sends a method call to the to the server and The price of beer has been dropped by three bucks to down to three dollars and that's broadcast to the display board or emitted okay, and At that point a lot of people will come to the pub imagine and And so next to this Our beer sales will be starting to get busy so Every two or three seconds we sell we get an order for like six beers or two beers at three dollars and And this is the receipts being issued and again, these are all client calls to the server okay and Of course along comes the accountant eventually and he wants to know You in business And so if we press that You can see that by selling beer at happy hour at three bucks. We're actually running at a loss so the accountant gets in touch with the bar manager and he increases happy hour prices to six bucks and What you should find now is that we've finished here at the three dollar beers and we've gone up to the six dollar beers and we're now making a profit so again This one here in blue is the only one where the client is receiving emitted data from the server The other three are working on doing a method call to the server and getting Some data back in some cases like this one. It's actually passing passing data to the method call and I guess it's getting some back as well. Yeah So it's bi-directional So that's one little thing there. I've just got one more thing. I'd like to show you guys There This is a practical example of using plant server if you're into electric bikes This is a little thing called a cycle analyst that you can plug on to an electric bike And it gives you things like, you know, your battery and your voltage and what you're consuming and your cumulatives per hour And things like that. It also this is sort of how it all connects together with your electric hub on your bike and your battery and Electric brakes for regenerative braking that sort of thing. But there's also a data out feed which sends out TTL data every second and the data out is about 70 characters and 14 14 a string of String data 70 characters, but 14 tab delimited Floating point numbers Okay, anyway, I built this little thing or no jacar electronics builder That's a little you are the Bluetooth converter. So I just plug that into their cycle analyst and it broadcasts the the packet every second to This little thing which is a raspberry pi 3 sitting inside a box with two loud speakers and they're meant to be waterproof and that's a little amplifier in there and so that it the this the Raspberry Pi 3 has Bluetooth capability and the the the the rolls here This for the server it receives the Bluetooth data from the cycle analyst transmitter every second. I'm actually using a sync I own Event loop which is in part of Python 3.5 onwards rather than the g-lib main loop to actually keep the Polling for my data coming in I verify the data, which is 70 characters or so and 14 tab Delimited floating point values. I log the data to disk Every second and I also once I verify that I've got good data I emit the data over the system D bus, okay? I then have a another program which is also launched on boot by system D called the client and He he's polling all the time for receiving data over the system D bus He'll filter all that data to see whether it matches a Couple of algorithms. I've got there I don't really want it basically the idea is that the loudspeakers will tell a guy that's sitting on the bicycle It will speak things to him For example down here the audio messages are one type will be something like speed 20 watts 800 And the other one will be distance 10 kilometers amp hours for and voltage 52. So that's That those are the messages and I Depending on how you're riding when they're going up hills or downhill the messages come at a rate of between say every 15 seconds or could be five minutes if you were Cruising along steadily and there's nothing much changing, but I can tweak those algorithms and means all I'm tweaking is the client code I don't have to worry look at the server code or anything like that the algorithms are totally in the client code and You might ask what why would you do this? this is a couple of the guy and his wife she's Sighted so she does the driving He's blind so he sits on the back and this photo was taken before I made a machine but he then has the little speaker on the back and every few seconds it tells him gives him an update of His speed and things like that. So and I don't need to run any wires the cycle analysts here's them the trailer pushes along and The there's a cable running up to that cycle analysts which is up here So the driver can see and then it's transmitted back to the Raspberry Pi here and he can just hear it and know How much reserve capacity he's got on his battery and things like that and that's his dog Okay, so I think I haven't gone over my time. I think that's about about it Okay, as I mentioned all my These presentations are at this link here So I think that's about it. Does anyone got any questions about a presentation Couldn't follow. Yeah, one question. Thanks for a presentation So when would you say it's a good idea to use like D-Bus in general because as far as I understand when you're using D-Bus You're essentially Kind of limiting yourself. It's like for Linux only right because the Linux only thing So why not why I don't know use Sockets like or just network. What do you want to use D-Bus instead? I Admittedly, I don't use I only use Linux But as far as I know D-Bus is not a specification just for the Linux. I think it's been adopted by Microsoft and maybe That's my understanding and the Pi D bus And the the G object libraries. I'm pretty sure they they will run on on a Windows platform So so I think that's you know, I just think the flexibility is there. It's just I I haven't personally Played around with it Look one thing I perhaps could mention is Latency if you were really wanting your data fast off a database The server brings it off the database and then there may be a one millisecond to get it through from server to client or something like that. I did try Get a timestamp send the timestamp to the server add a timestamp Send both timestamps back add a third time stamp and then look at the differences to see and it was within a millisecond You know In the case of say like the bicycle scenario Doesn't matter, you know With the delay and going through the buses Yeah, I haven't I haven't actually looked through how the spec guarantees the You know the integrity of the data But as far as I know it is I mean just about everything that's happening on the On the on your screen these days, but you know the little clock ticking over You can actually go to the get the D bus and you can see the packets going through to say Increment the seconds on your clock on the desktop so I've never seen the clock suddenly say 61 seconds I've never seen it getting there the data for the clock being corrupted or and that's going on day in day out But each have a unique bus you see so I Think the server can it conserved you could instantiate different buses on the same server I think so so that then you would I think that's feasible and so but but even Even so I guess if you had like depending on the data going back you could say message one and whatever This is in your for for client one. You know you could have an identifier on your packet going back And then you filter your client would be filtering So your clients receiving everything that's coming back for both clients for example Then you put a filter in on your your client Yeah Yeah, I haven't tried any load tests. Yeah, I mean I'm playing around with one second one one packet per second No problem Yeah, that's right. That's what yeah It's really a combination. Yeah. Okay. Well, thanks very much guys