Skip to content

Instantly share code, notes, and snippets.

@remceTkedaR
Created June 2, 2019 20:10
Show Gist options
  • Save remceTkedaR/db9bc5218aedb900900f7e4f719a91a6 to your computer and use it in GitHub Desktop.
Save remceTkedaR/db9bc5218aedb900900f7e4f719a91a6 to your computer and use it in GitHub Desktop.
Python and S7 1200 Siemens
#
#
import snap7.client
from snap7.snap7types import *
from snap7.util import *
class DBObject(object):
pass
offsets = { "Bool":2,"Int": 2,"Real":4,"DInt":6,"String":256}
db=\
"""
Temperature Real 0.0
Cold Bool 4.0
RPis_to_Buy Int 6.0
Db_test_String String 8.0
"""
def DBRead(plc,db_num,length,dbitems):
data = plc.read_area(areas['DB'],db_num,0,length)
obj = DBObject()
for item in dbitems:
value = None
offset = int(item['bytebit'].split('.')[0])
if item['datatype']=='Real':
value = get_real(data,offset)
if item['datatype']=='Bool':
bit =int(item['bytebit'].split('.')[1])
value = get_bool(data,offset,bit)
if item['datatype']=='Int':
value = get_int(data, offset)
if item['datatype']=='String':
value = get_string(data, offset)
obj.__setattr__(item['name'], value)
return obj
def get_db_size(array,bytekey,datatypekey):
seq,length = [x[bytekey] for x in array],[x[datatypekey] for x in array]
idx = seq.index(max(seq))
lastByte = int(max(seq).split('.')[0])+(offsets[length[idx]])
return lastByte
if __name__ == "__main__":
plc = snap7.client.Client()
plc.connect('192.168.1.121',1,0)
itemlist = filter(lambda a: a!='',db.split('\n'))
deliminator='\t'
items = [
{
"name":x.split(deliminator)[0],
"datatype":x.split(deliminator)[1],
"bytebit":x.split(deliminator)[2]
} for x in itemlist
]
#get length of datablock
length = get_db_size(items,'bytebit','datatype')
meh = DBRead(plc,10,length,items)
print(""")
Cold:\t\t\t{}
Tempeature:\t\t{}
RPis_to_Buy:\t{}
Db_test_String:\t{}
""".format(meh.Cold,meh.Temperature,meh.RPis_to_Buy,meh.Db_test_String),
plc.disconnect()
#
#
#
import snap7
import PLC
myplc = snap7.client.Client()
myplc.connect('192.168.1.121', 0, 1)
myplc.get.plc.get_connected()
myplc.get_connected()
#########################################
# by Radosław Tecmer #
# https://www.serwis-elektroniki.cba.pl #
#########################################
import requests
# import BeautifulSoup
from bs4 import BeautifulSoup
# # Tested with S7 1212C AC/DC/Rly and FW Version 4.2.1
#########################################
# Login #
#########################################
payload_login = {'Login': 'rt69', 'Password': 'zzaa19rt', 'Redirection': ''}
posturl_login = 'https://192.168.1.121/FormLogin'
headers = {
'Host': '192.168.1.121',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'pl,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://192.168.1.121/Portal/Portal.mwsl',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '45',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
session = requests.Session()
login_response = session.post(posturl_login, data=payload_login, headers=headers, verify=False)
print(login_response.status_code)
print(login_response.headers)
# print login_response.cookies.get_dict() # will stay empty
webpage = login_response.content
#########################################
# Extract authentication Cookie #
#########################################
webpage_soup = BeautifulSoup.BeautifulSoup(webpage)
auth_cookie_part = webpage_soup.find('input', attrs={'name': 'Cookie'})
auth_cookie_part = str(auth_cookie_part)
auth_cookie = auth_cookie_part.split('"')[5]
print("Authentication cookie: "), auth_cookie
#########################################
# Set Authentication Cookie #
#########################################
s7cookies = dict(siemens_ad_session=auth_cookie, coming_from_login='true')
#########################################
# Run Actions (require authentication) #
#########################################
payload_control = {'"webHMIData".webHMI_DO1_User': '1', '"webHMIData".webHMI_DO0_User': '1'}
usage = session.post('https://192.168.1.121/awp/AnalogInputs/api.io', cookies=s7cookies, data=payload_control, verify=False)
print(usage.status_code)
print(usage.headers)
print(usage.content)
#########################################
# Logout #
#########################################
payload_logout = {'Cookie': auth_cookie, 'Redirection': ''}
posturl_logout = 'https://192.168.1.121/FormLogin?LOGOUT'
logout = session.post(posturl_logout, cookies=s7cookies, headers=headers, data=payload_logout, verify=False)
print(logout.status_code)
print(logout.headers)
print(logout.content)
#########################################
# by Radosław Tecmer #
# https://www.serwis-elektroniki.cba.pl #
#########################################
import requests
# import BeautifulSoup
from bs4 import BeautifulSoup
# # Tested with S7 1212C AC/DC/Rly and FW Version 4.2.1
#########################################
# Login #
#########################################
payload_login = {'Login': 'rt69', 'Password': 'zzaa19rt', 'Redirection': ''}
posturl_login = 'https://192.168.1.120/FormLogin'
headers = {
'Host': '192.168.1.120',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://192.168.1.120/Portal/Portal.mwsl',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '45',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
session = requests.Session()
login_response = session.post(posturl_login, data=payload_login, headers=headers, verify=False)
print(login_response.status_code)
print(login_response.headers)
# print login_response.cookies.get_dict() # will stay empty
webpage = login_response.content
#########################################
# Extract authentication Cookie #
#########################################
webpage_soup = BeautifulSoup.BeautifulSoup(webpage)
auth_cookie_part = webpage_soup.find('input', attrs={'name': 'Cookie'})
auth_cookie_part = str(auth_cookie_part)
auth_cookie = auth_cookie_part.split('"')[5]
print("Authentication cookie: "), auth_cookie
#########################################
# Set Authentication Cookie #
#########################################
s7cookies = dict(siemens_ad_session=auth_cookie, coming_from_login='true')
#########################################
# Run Actions (require authentication) #
#########################################
payload_control = {'"webHMIData".webHMI_DO1_User': '1', '"webHMIData".webHMI_DO0_User': '1'}
usage = session.post('https://192.168.1.120/awp/AnalogInputs/api.io', cookies=s7cookies, data=payload_control, verify=False)
print(usage.status_code)
print(usage.headers)
print(usage.content)
#########################################
# Logout #
#########################################
payload_logout = {'Cookie': auth_cookie, 'Redirection': ''}
posturl_logout = 'https://192.168.178.50/FormLogin?LOGOUT'
logout = session.post(posturl_logout, cookies=s7cookies, headers=headers, data=payload_logout, verify=False)
print(logout.status_code)
print(logout.headers)
# print(logout.content)
# implementacja stosu 3
"""
Implementacja tablicowa stosu jest stosowana w językach programowania, które oferują tablice elementów jednego typu.
Przy inicjalizacji stosu trzeba podać jego rozmiar, czyli maksymalną liczbę elementów, które ma przechowywać.
Nowe elementy umieszczamy na coraz dalszych pozycjach w tablicy i zapamiętujemy liczbę elementów na stosie
(jest to również indeks miejsca, do którego wstawimy następny element). Przy zdejmowaniu elementu ze stosu
pomniejszamy numer indeksu, a na zwolnione miejsce wstawiamy bezpieczną wartość (w Pythonie jest nią None,
a w C/C++ zero lub NULL). W języku Python możemy łatwo zasymulować taką konstrukcję.
"""
class Stack:
def __init__(self, size=10):
self.items = size * [None] # utworzenie tablicy i wstawiamy bezpieczną wartość None
self.n = 0 # liczba elementów na stosie
self.size = size
def is_empty(self):
return self.n == 0
def is_full(self):
return self.size == self.n
def push(self, data):
self.items[self.n] = data
self.n += 1
def pop(self):
self.n -= 1
data = self.items[self.n]
self.items[self.n] = None # usuwam referencję
return data
# koniec
@engmsilva
Copy link

How did you find out that the link 'https://192.168.1.120/awp/AnalogInputs/api.io' accesses the io file in the PLC web folder? I tried to look for some reference in the documentation and found nothing.

@remceTkedaR
Copy link
Author

remceTkedaR commented Aug 20, 2020 via email

@engmsilva
Copy link

My question is whether there is any documentation from Siemens that led him to arrive at the assembly of the endpoint below:

https://192.168.1.120/awp/AnalogInputs/api.io

https://192.168.1.120 = PLC IP
awp = Automation Web Programming
AnalogInputs = application name
api.io = would be the file that is in the web folder defined for the PLC

Another question is why you used the .io file extension, as I tried to read this file with a javascript client and it returns an empty key.

Have you tried to make this communication using a javacript library with, for example, axios?

@remceTkedaR
Copy link
Author

remceTkedaR commented Aug 20, 2020 via email

@engmsilva
Copy link

I had already looked at this site, but the author also does not mention any documentation from Siemens that refers to the construction of the endpoint., But I am grateful anyway.

@remceTkedaR
Copy link
Author

I had already looked at this site, but the author also does not mention any documentation from Siemens that refers to the construction of the endpoint., But I am grateful anyway.

Sorry but for a long time my Github was not supported by me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment