ceece97b55086935844bd33d460dd22c3d90de2a
[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.Condition import Condition
18 from SmartAPI.model.Entity import Entity
19 from SmartAPI.model.InterfaceAddress import InterfaceAddress
20 from SmartAPI.model.Offering import Offering
21 from SmartAPI.model.Organization import Organization
22 from SmartAPI.model.PropertyDependentPriceSpecification import PropertyDependentPriceSpecification
23 from SmartAPI.model.Service import Service
24 from SmartAPI.model.TimeSeries import TimeSeries
25 from SmartAPI.model.ValueObject import ValueObject
26
27
28 from SmartAPI.common.PROPERTY import PROPERTY
29 from SmartAPI.rdf.OrderedList import OrderedList
30 from SmartAPI.rdf.ItemizedList import ItemizedList
31 from SmartAPI.rdf.NudeList import NudeList
32
33
34 myIdentity = "http://adapt.asema.com/demos/python/datasource/"
35 adaptServiceIdentity = "http://adapt.asema.com"
36 registrationServerUri = "http://find.smart-api.io/smart/v1.0e1.0/access"
37 registrationServerKeyUri = "http://find.smart-api.io/smart/v1.0e1.0/key"
38 #registrationServerUri = "http://192.168.2.96:8080/smartapifind-core/smart/v1.0e1.0/access"
39 #registrationServerKeyUri = "http://192.168.2.96:8080/smartapifind-core/smart/v1.0e1.0/key"
40
41 PORT = 8111
42
43
44
45 class SampleRegistration(object):
46         
47
48         def __init__(self):
49                 pass
50
51         def run(self):
52                 agent = RegistrationAgent(myIdentity)
53                 agent.setServerAddress(registrationServerUri)
54                 agent.setServerKeyAddress(registrationServerKeyUri)
55                 agent.setDebugMode(True)
56
57                 # registrate
58                 try:
59                         org = Organization()
60                         org.setName("Asema Electronics Ltd")
61                         
62                         sampleService = Service(myIdentity)
63                         sampleService.setName("Asema Adapt demo data service")
64                         sampleService.setDescription("Demo code for a data source that is compatible with Adapt")
65                         sampleService.setCoordinates(latitude=60.180824, longitude=24.832116)
66                         sampleService.setOwner(org)
67         
68                         auth = Authorization()
69                         auth.addMethod(RESOURCE.COOKIE);
70                         auth.addMethod(RESOURCE.HTTPSTANDARD);
71         
72                         iface = InterfaceAddress()
73                         iface.setHost("adapt.asema.com")
74                         iface.setPath("/test/")
75                         iface.setPort(80)
76                         iface.setScheme("http")
77
78                         read = Activity()
79                         read.setMethod(RESOURCE.READ)
80                         read.setInterface(iface)
81                         read.setAuthorization(auth)
82
83                         dataSource = Entity()
84                         dataSource.setIdentifierUri(myIdentity + "devices/Cdemodevice")
85                         dataSource.setName("Demo Adapt datasource")
86                         dataSource.addCapability(read)
87                         dataSource.setManagedBy(myIdentity)
88                         dataSource.setServedBy(adaptServiceIdentity)
89                         dataSource.setCoordinates(latitude=60.180824, longitude=24.832116)
90
91                         dataSource.addCapability(read)
92                         
93                         power = ValueObject(myIdentity + "service/Ppower")
94                         power.addType(RESOURCE.READABLE)
95                         power.setQuantity(RESOURCE.POWER)
96                         power.setUnit(RESOURCE.AMPERE)
97                         power.setMaximum(1000.0)
98                         power.setMinimum(0.0)
99                         power.setName("Power reading")
100                         power.setDescription("This is the power reading of the unit.");
101                         
102                         offering = Offering()
103                         priceSpec = PropertyDependentPriceSpecification()
104                         priceSpec.setName("Sample pricing")
105                         priceSpec.addType(RESOURCE.PRICETYPEDISCOUNT)
106                         
107                         c1 = Condition()
108                         c1.addGreater(0)
109                         c1.addAction(10)
110                         priceSpec.addCondition(c1)
111                         
112                         c2 = Condition()
113                         c2.addGreater(10)
114                         c2.addAction(20)
115                         priceSpec.addCondition(c2)
116                         
117                         c3 = Condition()
118                         c3.addGreater(30)
119                         c3.addAction(40)
120                         priceSpec.addCondition(c3)
121                         
122                         c4 = Condition()
123                         c4.addGreater(40)
124                         c4.addAction(55)
125                         priceSpec.addCondition(c4)
126                         
127                         offering.addPriceSpecification(priceSpec)
128                         dataSource.addOffering(offering)
129                         dataSource.addValueObject(power)
130                         
131                         """
132                         il = ItemizedList()
133                         l = [x for x in range(10)]
134                         il.add_items(l)
135                         
136                         ol = OrderedList()
137                         ol.add_items(l)
138                         
139                         nl = NudeList()
140                         nl.add_items(l)
141
142                         dataSource.add(PROPERTY.ANGULARVELOCITYX, il)
143                         dataSource.add(PROPERTY.ANGULARVELOCITYY, ol)
144                         dataSource.add(PROPERTY.ANGULARVELOCITYZ, nl)
145                         """
146                         agent.addEntity(sampleService)
147                         agent.addEntity(dataSource);
148
149                         r = agent.registrate()
150                         if r is None or r.hasErrors():
151                                 print "Demo data service registration FAILED"
152                                 return False
153                         return True
154                 
155                 except:
156                         print "Error in registration code:"
157                         traceback.print_exc()
158                         return False
159
160
161 class SampleDataService(BaseHTTPRequestHandler):
162         
163         def __init__(self, request, client_address, server):
164                 BaseHTTPRequestHandler.__init__(self, request, client_address, server)
165                 
166         # HANDLE GET REQUESTS
167         def do_GET(self):
168                 self.send_response(200)
169                 self.end_headers()
170                         
171                 print("GET " + self.path)
172                         
173                 req_path = self.path.rstrip('/')
174                         
175                 if req_path.endswith("/identify"):
176                         self.wfile.write(str.encode(myIdentity))
177                 elif req_path.endswith("/authorize"):
178                         response_activity = Activity()
179                         response = response_activity.toString()
180                         print("GET " + response)
181                         self.wfile.write(str.encode(response))
182                 else:
183                         print("unhandled request received!")
184         
185         # HANDLE POST REQUESTS
186         def do_POST(self):
187                 content_length = int(self.headers['Content-Length'])
188                 body = self.rfile.read(content_length)
189                 self.send_response(200)
190                 self.end_headers()
191                 response_bytes = BytesIO()
192                 
193                 print("POST" + self.path)
194                 print("POST DATA: " + body)
195                 
196                 req_path = self.path.rstrip('/')
197                 
198                 if req_path.endswith("/authorize"):
199                         # Reply with empty activity to authorize
200                         response_activity = Activity()
201                         response_text = response_activity.toString()
202                         print("POST AUTHORIZE" + response_text)
203                         response_bytes.write(response_text)
204                         
205                 elif req_path.endswith("/access"):
206                         request = Tools.parseRequest(body)
207                         print("request: " + request.toString())
208                                 
209                         activity = request.getActivities()[0]  # type: Activity
210                                 
211                         # Handle timeseries request
212                         if activity.hasTemporalContext():
213                                 response_bytes.write(self.handleTemporalContext(activity, request))
214                         else:
215                                 print("unhandled request received!")
216                 
217                 else:
218                         print("unhandled request received!")
219                 
220                 # Write output to client
221                 self.wfile.write(response_bytes.getvalue())
222         
223         
224         def handleTemporalContext(self, activity, request):
225                 print("Timeseries request: ")
226                 print("start")
227                 print(activity.temporalContext.start)
228                 print("end")
229                 print(activity.temporalContext.end)
230                 
231                 # For the client to recognize from which activity this result is, the response
232                 # activity will carry the same identifier that was in the request
233                 response = ResponseFactory.create(myIdentity, request)
234                 response_activity = Activity(activity.getIdentifierUri())
235                 
236                 """
237                 The way results are obtained is up to the server. This could
238                 for instance be a result from a database query,
239                 """
240                 results = [
241                         {'time': '2019-06-10T15:18:54.842', 'power': 25},
242                         {'time': '2019-06-01T02:11:54.842', 'power': 21},
243                         {'time': '2019-05-25T11:11:54.842', 'power': 32}]
244                 
245                 time_series = TimeSeries()
246                 
247                 # Add data to response timeseries
248                 for r in results:
249                         value_object = ValueObject()
250                         value_object.setInstant(r["time"])
251                         value_object.setValue(r["power"])
252                         
253                         time_series.addListItem(value_object)
254                         
255                         # Add timeseries to respose activity
256                         response_activity.addTimeSerie(time_series)
257                         
258                         response.addActivity(response_activity)
259                         
260                         print("Reply:")
261                         print(Tools.serializeResponse(response)[0])
262                         return Tools.serializeResponse(response)[0]
263
264
265 def main():
266         registrator = SampleRegistration()
267         registrator.run()
268         
269         httpd = HTTPServer(('', PORT), SampleDataService)
270         httpd.serve_forever()
271
272
273 if __name__ == '__main__':
274         main()
275