# Finding the role of a certain client in order to enable a physical pushbutton

**URL:** <https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773>\
**Category:** Ignition\
**Created:** [August 26, 2019, 6:40pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773 "2019-08-26T18:40:55Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 26, 2019, 6:40pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/1 "2019-08-26T18:40:55Z")

</div>

I have a client that is on the same computer as the gateway. I need to know if that client is logged in with a certain role in order to for them to be able to start a process. The process is started with physical push button through a PLC tag. The people at the facility this is at like to log in on their computers at their desks and don’t always log off so I need to filter them. I also need to filter designer on the computer in question.

So, I need to grab the IP address of a client that is also the gateway, check if its not in designer and check the role of the user logged on. That will then flip an OPC bit to tell the PLC that the user has the permissions to hit the start button. Has anyone done something like this?

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 26, 2019, 6:51pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/2 "2019-08-26T18:51:52Z")

</div>

It looks like GetSessionInfo is what I need but I am not the best python programmer around and don’t really know how to navigate the table to filter the information I need. I am looking further into this now.

---

<div class="post-metadata">

**Author:** ![grietveld](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/grietveld/32/6984_2.png) [@grietveld](https://forum.inductiveautomation.com/u/grietveld)\
**Post date:** [August 26, 2019, 7:05pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/3 "2019-08-26T19:05:12Z")

</div>

I think the first question is, are you using vision or perspective? GetSessionInfo would be a perspective function.

If you are using vision, this information should be available from the client tags.

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 26, 2019, 9:10pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/4 "2019-08-26T21:10:58Z")

</div>

Ahh. Yes you are right. I am using vision so that wouldn’t work. Here is where I am currently.

I created a client tag with the following expression:

If ({[System]Client/Network/IPAddress} == “192.168.0.250” && {[System]Client/User/RolesString} == “Administrator”,1,0)

I then created a value change script to write it to an OPC tag

if (currentValue == 1):  
system.tag.write(“OPCtag”, 1)  
else:  
system.tag.write(“OPCtag”, 0)

I put a multistate indicator on the screen just to see the value on my HMI and I am getting a bad evaluation overlay. I don’t see anything wrong with the expression but I could be wrong.

I did it all piece by piece also and no matter what I put into the client tag expression it throws a fit.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 26, 2019, 11:36pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/5 "2019-08-26T23:36:36Z")

</div>

> [@jparsons](#):
>
> I created a client tag with the following expression:
> 
> `If ({[System]Client/Network/IPAddress} == “192.168.0.250” && {[System]Client/User/RolesString} == “Administrator”,1,0)`

The roles string could potentially contain Administrator and other roles, so you really need to search for the role within the string, e.g.  
`if(indexof({[System]Client/User/RolesString}, "Administrator")>0, 1, 0)`  
Note: this may not always work, depending on the role you're looking for (other roles may contain the string you're looking for, in this case however it's probably unlikely)

Remember that you have multiple instances of these client tags on your other clients, all running the same change event script. These will all be writing to this OPC tag as well, potentially overwriting any "1" written by your special client.

It doesn't sound like a very robust or secure way to do this. Consider maybe using a button on SCADA with privileges set to enable it on logon/IP address, which enables the OPC tag for a time period.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 27, 2019, 12:33pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/7 "2019-08-27T12:33:23Z")

</div>

The expression he gave is in the client tag which uses the expression language, not python

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 27, 2019, 12:45pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/9 "2019-08-27T12:45:25Z")

</div>

I didn’t think about the overwriting. That tears this whole thing down. I would run into the same problem though with the button. It would rely on a client tag writing to the OPC tag with the IP address/login

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 27, 2019, 12:54pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/10 "2019-08-27T12:54:02Z")

</div>

I would split this requirement into two separate indicators, one for determining whether a client is running on the gateway or not, the other checking the required role.

I would implement the first requirement with a client startup script that interrogates the local network interfaces and checks for the mac IDs of the gateway (those could be hard-coded into the script). And then writes the result to a boolean tag like `[Client]RunningInGateway`. Such script only runs in a client, so designers would be excluded by default. (Note, a designer could just toggle that boolean to get around this, but you can't really stop anyone with designer privileges from going around your security.) This script might help you:

> [@Mobile Client MAC Address](http://forum.inductiveautomation.com/t/mobile-client-mac-address/23037/10):
>
> In a real Vision client, you can obtain the local MAC addresses with the following script: from java.net import NetworkInterface # Get list of local mac address as strings def myMacIds(): macs = [ni.hardwareAddress for ni in NetworkInterface.getNetworkInterfaces() if ni.hardwareAddress] return [":".join(["%02x" % (b & 0xff) for b in mac]) for mac in macs] Also, again in a real Vision client, you can obtain the outbound network interface and the corresponding local IP address the clien…

I would implement the latter requirement as a boolean custom property, `IsPrivileged` perhaps, on the window containing the restricted pushbuttons, bound to the [hasRole()](https://docs.inductiveautomation.com/display/DOC79/hasRole) expression function.

The pushbuttons in question would have the expression `{[Client]RunningInGateway} && {Root Container.IsPrivileged}` bound to their enable property.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 27, 2019, 1:16pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/11 "2019-08-27T13:16:58Z")

</div>

@pturmel Agree with you, but for the second part, I believe the OP is talking about physical push-buttons, not scada push buttons. Hence why I think there needs to be some sort of enable button on scada set by a user with privilege and from the correct client teeminal

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 27, 2019, 1:19pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/12 "2019-08-27T13:19:20Z")

</div>

Yes, this is correct. There are physical pushbuttons on the front of the panel this HMI is attached to.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 27, 2019, 1:45pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/13 "2019-08-27T13:45:30Z")

</div>

> [@jparsons](#):
>
> There are physical pushbuttons

Sorry, missed that. I would adjust the approach to include a client timer event script that repeatedly evaluates the current role and sends a heartbeat message to the gateway to maintain the physical enable. Then have a gateway timer event that regularly checks the timestamp of the last heartbeat and kills the physical enable if it expires.

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 27, 2019, 2:18pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/14 "2019-08-27T14:18:31Z")

</div>

If someone opened up a client on their laptop, couldn’t that still override the correct client (gateway client)

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 27, 2019, 3:40pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/15 "2019-08-27T15:40:17Z")

</div>

I ended up getting it to work using my original solution:

```auto
sessions = system.util.getSessionInfo()
for sess in sessions:
	if not sess["isDesigner"]:
		user = system.user.getUser("default",sess["username"])
		address = sess["address"]
		for role in system.user.getRoles("default"):
			if address == "comp name":
				if role == "Administrator": 
					system.tag.write("JparsonsTest/Start", 1)
					break
				else:
					system.tag.write("JparsonsTest/Start", 0)

```

Thank you all for your inputs. This has taught me a lot more about python and ignition for the future!

Edit: Just kidding. I just tested it fully and it didn’t work. Back to square one.

---

<div class="post-metadata">

**Author:** ![jparsons](https://avatars.discourse-cdn.com/v4/letter/j/ea666f/32.png) [@jparsons](https://forum.inductiveautomation.com/u/jparsons)\
**Post date:** [August 27, 2019, 7:20pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/16 "2019-08-27T19:20:48Z")

</div>

It works for real this time. Thanks again guys!

```auto
sessions = system.util.getSessionInfo()
for sess in sessions:
	if not sess["isDesigner"]:
		try:
			user = system.user.getUser("default",sess["username"])
		except:
			user = system.user.getUser("AD database",sess["username"])
		address = sess["address"]
		if address == "jparsons-vm":
			user.getRoles()
			for role in user.getRoles():
				if role == "Administrator":
					system.tag.write("JparsonsTest/Strt", 1)
				else:
					system.tag.write("JparsonsTest/Strt", 0)

```

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 27, 2019, 11:03pm UTC](https://forum.inductiveautomation.com/t/finding-the-role-of-a-certain-client-in-order-to-enable-a-physical-pushbutton/27773/17 "2019-08-27T23:03:47Z")

</div>

Just fyi, you can simplify your last part to:

```auto
if address == "jparsons-vm":
	if "Administrator" in user.getRoles():
		system.tag.write("JparsonsTest/Strt", 1)
	else:
		system.tag.write("JparsonsTest/Strt", 0)

```

If you had multiple cases that could make the condition true, you can use:

```auto
if any(role in user.getRoles() for role in ("Administrator", "Supervisor")):

```

or you can use `all(...)` in place of `any` to match all of the roles.

Python really is a beautiful language 🙂
