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