e7d51fa372c2bd3c7ebf27397d63ed65f198b8a4
[smartapi.git] / Examples / Python / AdaptDataService / AdaptDataService.py
1 #!/usr/bin/python
2
3 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
4 from io import BytesIO
5 import traceback
6
7 from SmartAPI.agents.RegistrationAgent import RegistrationAgent
8 from SmartAPI.agents.SearchAgent import SearchAgent
9
10 from SmartAPI.common.Tools import Tools
11 from SmartAPI.common.RESOURCE import RESOURCE
12
13 from SmartAPI.factory.ResponseFactory import ResponseFactory
14
15 from SmartAPI.model.Activity import Activity
16 from SmartAPI.model.Authorization import Authorization
17 from SmartAPI.model.Entity import Entity
18 from SmartAPI.model.InterfaceAddress import InterfaceAddress
19 from SmartAPI.model.Organization import Organization
20 from SmartAPI.model.Service import Service
21 from SmartAPI.model.TimeSeries import TimeSeries
22 from SmartAPI.model.ValueObject import ValueObject
23
24
25 myIdentity = "http://adapt.asema.com/demos/python/datasource/"
26 adaptServiceIdentity = "http://adapt.asema.com"
27 registrationServerUri = "http://find.smart-api.io/smart/v1.0e1.0/access"
28
29 PORT = 8111
30
31
32
33 class SampleRegistration(object):
34         
35
36         def __init__(self):
37                 pass
38
39         def run(self):
40                 agent = RegistrationAgent(myIdentity)
41                 agent.setServerAddress(registrationServerUri)
42                 agent.setDebugMode(True)
43
44                 # registrate
45                 try:
46                         org = Organization()
47                         org.setName("Asema Electronics Ltd")
48                         
49                         sampleService = Service(myIdentity)
50                         sampleService.setName("Asema Adapt demo data service")
51                         sampleService.setDescription("Demo code for a data source that is compatible with Adapt")
52                         sampleService.setCoordinates(latitude=60.180824, longitude=24.832116)
53                         sampleService.setOwner(org)
54         
55                         auth = Authorization()
56                         auth.addMethod(RESOURCE.COOKIE);
57                         auth.addMethod(RESOURCE.HTTPSTANDARD);
58         
59                         iface = InterfaceAddress()
60                         iface.setHost("adapt.asema.com")
61                         iface.setPath("/test/")
62                         iface.setPort(80)
63                         iface.setScheme("http")
64
65                         read = Activity()
66                         read.setMethod(RESOURCE.READ)
67                         read.setInterface(iface)
68                         read.setAuthorization(auth)
69
70                         dataSource = Entity()
71                         dataSource.setIdentifierUri(myIdentity + "devices/Cdemodevice")
72                         dataSource.setName("Demo Adapt datasource")
73                         dataSource.addCapability(read)
74                         dataSource.setManagedBy(myIdentity)
75                         dataSource.setServedBy(adaptServiceIdentity)
76                         dataSource.setCoordinates(latitude=60.180824, longitude=24.832116)
77
78                         dataSource.addCapability(read)
79                         
80                         power = ValueObject(myIdentity + "service/Ppower")
81                         power.addType(RESOURCE.READABLE)
82                         power.setQuantity(RESOURCE.POWER)
83                         power.setUnit(RESOURCE.AMPERE)
84                         power.setMaximum(1000.0)
85                         power.setMinimum(0.0)
86
87                         dataSource.addValueObject(power)
88
89                         agent.addEntity(sampleService)
90                         agent.addEntity(dataSource);
91
92                         r = agent.registrate()
93                         if r is None or r.hasErrors():
94                                 print "Demo data service registration FAILED"
95                                 return False
96                         return True
97                 
98                 except:
99                         print "Error in registration code:"
100                         traceback.print_exc()
101                         return False
102
103
104 class SampleDataService(BaseHTTPRequestHandler):
105         
106         def __init__(self, request, client_address, server):
107                 BaseHTTPRequestHandler.__init__(self, request, client_address, server)
108                 
109         # HANDLE GET REQUESTS
110         def do_GET(self):
111                 self.send_response(200)
112                 self.end_headers()
113                         
114                 print("GET " + self.path)
115                         
116                 req_path = self.path.rstrip('/')
117                         
118                 if req_path.endswith("/identify"):
119                         self.wfile.write(str.encode(myIdentity))
120                 elif req_path.endswith("/authorize"):
121                         response_activity = Activity()
122                         response = response_activity.toString()
123                         print("GET " + response)
124                         self.wfile.write(str.encode(response))
125                 else:
126                         print("unhandled request received!")
127         
128         # HANDLE POST REQUESTS
129         def do_POST(self):
130                 content_length = int(self.headers['Content-Length'])
131                 body = self.rfile.read(content_length)
132                 self.send_response(200)
133                 self.end_headers()
134                 response_bytes = BytesIO()
135                 
136                 print("POST" + self.path)
137                 print("POST DATA: " + body)
138                 
139                 req_path = self.path.rstrip('/')
140                 
141                 if req_path.endswith("/authorize"):
142                         # Reply with empty activity to authorize
143                         response_activity = Activity()
144                         response_text = response_activity.toString()
145                         print("POST AUTHORIZE" + response_text)
146                         response_bytes.write(response_text)
147                         
148                 elif req_path.endswith("/access"):
149                         request = Tools.parseRequest(body)
150                         print("request: " + request.toString())
151                                 
152                         activity = request.getActivities()[0]  # type: Activity
153                                 
154                         # Handle timeseries request
155                         if activity.hasTemporalContext():
156                                 response_bytes.write(self.handleTemporalContext(activity, request))
157                         else:
158                                 print("unhandled request received!")
159                 
160                 else:
161                         print("unhandled request received!")
162                 
163                 # Write output to client
164                 self.wfile.write(response_bytes.getvalue())
165         
166         
167         def handleTemporalContext(self, activity, request):
168                 print("Timeseries request: ")
169                 print("start")
170                 print(activity.temporalContext.start)
171                 print("end")
172                 print(activity.temporalContext.end)
173                 
174                 # For the client to recognize from which activity this result is, the response
175                 # activity will carry the same identifier that was in the request
176                 response = ResponseFactory.create(myIdentity, request)
177                 response_activity = Activity(activity.getIdentifierUri())
178                 
179                 """
180                 The way results are obtained is up to the server. This could
181                 for instance be a result from a database query,
182                 """
183                 results = [
184                         {'time': '2019-06-10T15:18:54.842', 'power': 25},
185                         {'time': '2019-06-01T02:11:54.842', 'power': 21},
186                         {'time': '2019-05-25T11:11:54.842', 'power': 32}]
187                 
188                 time_series = TimeSeries()
189                 
190                 # Add data to response timeseries
191                 for r in results:
192                         value_object = ValueObject()
193                         value_object.setInstant(r["time"])
194                         value_object.setValue(r["power"])
195                         
196                         time_series.addListItem(value_object)
197                         
198                         # Add timeseries to respose activity
199                         response_activity.addTimeSerie(time_series)
200                         
201                         response.addActivity(response_activity)
202                         
203                         print("Reply:")
204                         print(Tools.serializeResponse(response)[0])
205                         return Tools.serializeResponse(response)[0]
206
207
208 def main():
209         registrator = SampleRegistration()
210         registrator.run()
211         
212         httpd = HTTPServer(('', PORT), SampleDataService)
213         httpd.serve_forever()
214
215
216 if __name__ == '__main__':
217         main()
218