def test_4(self): """ This function performs checks for adding, updating and removing Actions to a web thing. Notice that to do so, it is required to test also DataSchema and FieldSchema updates. Those two classes are not made to be removed, because they can always be used by other things. TODO The procedure to remove them is more complex and involves some queries before performing the delete. In case reset==True, check jsons are updated. However, the plain 'res_query_all' is not overwritten, because the presence of new DataSchema and FieldSchema here requires the existance of a different file named 'res_query_all_new_dataschema.json'. True or False is returned for success or failure. """ THING_URI = "<http://TestThing.com>" # Adding the new thing dummyThing = Thing(self.engine, {"thing": THING_URI, "newName": "TEST-THING", "newTD": "<http://TestTD.com>"}).post() # Adding new Actions and then query the output actions = [] for aType in list(AType): actions.append(Action( self.engine, {"td": "<http://TestTD.com>", "action": "<http://TestAction_{}.com>".format(aType.value.lower()), "newName": "TEST-ACTION-{}".format(aType.value.lower()), "ids": "<http://XSDstringDataSchema.org>", "ods": "<http://XSDintegerDataSchema.org>"}, lambda: None, force_type=aType).post()) sparql_query = self.ysap.getQuery("DESCRIBE_ACTION").replace( "(UNDEF)", "(<http://TestAction_io.com>) (<http://TestAction_i.com>) (<http://TestAction_o.com>) (<http://TestAction_empty.com>)") query_result = self.engine.sparql_query(sparql_query) self.assertTrue(compare_queries( query_result, resource_filename(__name__, "res_new_actions_create.json"), show_diff=True)) # Deleting the actions for action in actions: action.delete() # Query all check dummyThing.delete() self.assertTrue(compare_queries( self.engine.query_all(), resource_filename( __name__, "res_query_all_new_dataschema_actions.json"), show_diff=True))
def rebuild_test_4(engine): setUp(engine) THING_URI = "<http://TestThing.com>" # Adding the new thing dummyThing = Thing( engine, { "thing": THING_URI, "newName": "TEST-THING", "newTD": "<http://TestTD.com>" }).post() # Adding new Actions and then query the output actions = [] for aType in list(AType): actions.append( Action(engine, { "td": "<http://TestTD.com>", "action": "<http://TestAction_{}.com>".format(aType.value.lower()), "newName": "TEST-ACTION-{}".format(aType.value.lower()), "ids": "<http://XSDstringDataSchema.org>", "ods": "<http://XSDintegerDataSchema.org>" }, lambda: None, force_type=aType).post()) sparql_query = engine.sap.getQuery("DESCRIBE_ACTION").replace( "(UNDEF)", "(<http://TestAction_io.com>) (<http://TestAction_i.com>) (<http://TestAction_o.com>) (<http://TestAction_empty.com>)" ) target = resource_filename(__name__, "res_new_actions_create.json") logging.warning("Rebuilding {}".format(target)) query_result = engine.sparql_query(sparql_query, destination=target) # Deleting the actions for action in actions: action.delete() # Query all check dummyThing.delete() target = resource_filename(__name__, "res_query_all_new_dataschema_actions.json") logging.warning("Rebuilding {}".format(target)) engine.query_all(destination=target)
def test_2(self): """ This test checks if the sparql insert of Thing3 and the sum of cocktail sparqls have the same effect in the rdf store. """ thing_descriptor = "<http://MyThirdWebThingDescription.com>" self.engine.sparql_update(read_all_file("insert_thing_3.sparql")) query_all_sparql = self.engine.query_all() self.engine.clear() thing1 = Thing( self.engine, {"thing": "<http://MyThirdWebThing.com>", "newName": "Thing3", "newTD": thing_descriptor}).post() action1 = Action( self.engine, {"thing": thing1.uri, "td": thing_descriptor, "action": "<http://MyThirdWebThing.com/Action1>", "newName": "Thing3_Action1"}, lambda: print("ACTION 1 HANDLER RUN")).post() event1 = Event( self.engine, {"td": thing_descriptor, "event": "<http://MyThirdWebThing.com/Event1>", "eName": "Thing3_Event1"}).post() query_all_cocktail = self.engine.query_all() self.assertTrue(compare_queries( query_all_cocktail, query_all_sparql, show_diff=True))
def test_0(self): """ This test checks if the sparql insert of Thing1 and the sum of cocktail sparqls have the same effect in the rdf store. """ self.engine.sparql_update(read_all_file("insert_dataschemas.sparql")) self.engine.sparql_update(read_all_file("insert_thing_1.sparql")) thing_descriptor = "<http://MyFirstWebThingDescription.com>" query_all_sparql = self.engine.query_all() self.engine.clear() self.engine.sparql_update(read_all_file("insert_dataschemas.sparql")) thing1_uri = "<http://MyFirstWebThing.com>" property1 = Property( self.engine, {"td": thing_descriptor, "property": "<http://MyFirstWebThing.com/Property1>", "newName": "Thing1_Property1", "newStability": "1000", "newWritability": "true", "newDS": ds_string, "newPD": "<http://MyFirstWebThing.com/Property1/PropertyData>", "newValue": "Hello World!"}) action1 = Action( self.engine, {"thing": thing1_uri, "td": thing_descriptor, "action": "<http://MyFirstWebThing.com/Action1>", "newName": "Thing1_Action1", "ids": ds_string, "ods": ds_genericWebResource}, lambda: print("ACTION 1 HANDLER RUN")) action2 = Action( self.engine, {"thing": thing1_uri, "td": thing_descriptor, "action": "<http://MyFirstWebThing.com/Action2>", "newName": "Thing1_Action2", "ods": ds_integer}, lambda: print("ACTION 2 HANDLER RUN"), forProperties=[property1]) event1 = Event( self.engine, {"td": thing_descriptor, "event": "<http://MyFirstWebThing.com/Event1>", "eName": "Thing1_Event1", "ods": ds_dateTimeStamp}) thing1 = Thing( self.engine, {"thing": thing1_uri, "newName": "Thing1", "newTD": thing_descriptor}).post( interaction_patterns=[property1, action1, action2, event1]) self.assertTrue(compare_queries(self.engine.query_all(), query_all_sparql, show_diff=True))
def rebuild_test_5(engine): setUp(engine) THING_URI = "<http://TestThing.com>" # Adding the new thing dummyThing = Thing( engine, { "thing": THING_URI, "newName": "TEST-THING", "newTD": "<http://TestTD.com>" }).post() # Adding new Actions and then query the output events = [] for eType in list(EType): events.append( Event(engine, { "td": "<http://TestTD.com>", "event": "<http://TestEvent_{}.com>".format(eType.value.lower()), "eName": "TEST-EVENT-{}".format(eType.value.lower()), "ods": "<http://XSDintegerDataSchema.org>" }, force_type=eType).post()) # Querying the events sparql_query = engine.sap.getQuery("DESCRIBE_EVENT").replace( "(UNDEF)", "(<http://TestEvent_o.com>) (<http://TestEvent_empty.com>)") target = resource_filename(__name__, "res_new_events_create.json") logging.warning("Rebuilding {}".format(target)) engine.sparql_query(sparql_query, destination=target) # Deleting the events for event in events: event.delete() # Query all check dummyThing.delete() target = resource_filename(__name__, "res_query_all_new_dataschema_events.json") logging.warning("Rebuilding {}".format(target)) engine.query_all(destination=target)
def rebuild_test_3(engine): setUp(engine) THING_URI = "<http://TestThing.com>" PROPERTY_URI = "<http://TestProperty.com>" NEW_PROPERTY_VALUE = "HIJKLMNOP" TEST_TD = "<http://TestTD.com>" dummyThing = Thing(engine, { "thing": THING_URI, "newName": "TEST-THING", "newTD": TEST_TD }).post() p_fBindings = { "td": TEST_TD, "property": PROPERTY_URI, "newName": "TEST-PROPERTY", "newStability": "1", "newWritability": "true", "newDS": "<http://XSDstringDataSchema.org>", "newPD": "<http://TestThing.com/Property1/PropertyData>", "newValue": "ABCDEFG" } testProperty = Property(engine, p_fBindings).post() target = resource_filename(__name__, "res_new_property_create.json") logging.warning("Rebuilding {}".format(target)) engine.query("DESCRIBE_PROPERTY", forcedBindings={"property_uri": PROPERTY_URI}, destination=target) # Updating property with a new writability and a new value p_fBindings["newWritability"] = "false" p_fBindings["newValue"] = NEW_PROPERTY_VALUE testProperty.update(p_fBindings) target = resource_filename(__name__, "res_new_property_update.json") logging.warning("Rebuilding {}".format(target)) engine.query("DESCRIBE_PROPERTY", forcedBindings={"property_uri": PROPERTY_URI}, destination=target) testProperty.delete() dummyThing.delete() target = resource_filename(__name__, "res_query_all_new_dataschema.json") logging.warning("Rebuilding {}".format(target)) engine.query_all(destination=target)
def test_2(self): """ This function performs checks for adding and removing all is needed for a new web thing. In case reset==True, the specific thing query result file is rebuilt. True or False is returned for success or failure. """ SUPERTHING = "<http://MyFirstWebThing.com>" THING_URI = "<http://TestThing.com>" # Adding new thing within the forced bindings dummyThing = Thing( self.engine, {"thing": THING_URI, "newName": "TEST-THING", "newTD": "<http://TestTD.com>"}, superthing=SUPERTHING).post() sparql_query = self.ysap.getQuery("DISCOVER_THINGS").replace( "(UNDEF UNDEF UNDEF)", "({} UNDEF UNDEF) ({} UNDEF UNDEF)".format(THING_URI, SUPERTHING)) query_result = self.engine.sparql_query(sparql_query) self.assertTrue(compare_queries( query_result, resource_filename(__name__, "res_new_thing.json"), show_diff=True)) # Passing through this point also in reset case allows not to # refresh the RDF store into the following test. # Deleting the thing, and checking if the triples in all the store # are the same as if all the test never happened dummyThing.delete() # With this line, if it outputs True, we certify that the contents # of the RDF store are exactly the same as they were at the beginning # of this function. So, no need to call reset_testbase self.test_0()
def rebuild_test_2(engine): setUp(engine) target = resource_filename(__name__, "res_new_thing.json") logging.warning("Rebuilding {}".format(target)) SUPERTHING = "<http://MyFirstWebThing.com>" THING_URI = "<http://TestThing.com>" Thing(engine, { "thing": THING_URI, "newName": "TEST-THING", "newTD": "<http://TestTD.com>" }, superthing=SUPERTHING).post() query = engine.sap.getQuery("DISCOVER_THINGS").replace( "(UNDEF UNDEF UNDEF)", "({} UNDEF UNDEF) ({} UNDEF UNDEF)".format(THING_URI, SUPERTHING)) engine.sparql_query(query, destination=target)
def main(args): engine = YSAPEngine("./cocktail_sap.ysap") if "clear" in args: engine.clear() # # IDENTIFICATION AND DESCRIPTION OF INTERACTION PATTERNS # DEFINITION OF ACTIONS' BEHAVIOUR # def timeActionHandler(added, removed): print(added) if added != []: whatTimeIsIt.post_output( {"instance": added[0]["aInstance"]["value"], "oData": "<http://SmartClock.swot/TimeAction/Data_{}>".format(uuid4()), "oValue": datetime.fromtimestamp(time()).strftime('%Y-%m-%dT%H:%M:%S.%fZ'), "oDS": ds_datetime}) # Setup the Hot/Cold Action whatTimeIsIt = Action( engine, {"td": ClockTD, "action": TimeAction, "newName": "WhatTimeIsIt", "ods": ds_datetime}, timeActionHandler) def temperatureActionHandler(added, removed): print(added) if added != []: whatTimeIsIt.post_output( {"instance": added[0]["aInstance"]["value"], "oData": "<http://SmartClock.swot/TemperatureAction/Data_{}>".format(uuid4()), "oValue": str(simulate()), "oDS": ds_lambda}) whatsTheTemperature = Action( engine, {"td": ClockTD, "action": TemperatureAction, "newName": "WhatsTheTemperature", "ods": ds_lambda}, temperatureActionHandler) # # POSTING THE TRIPLES TO THE SWTE # # Setup and post the WebThing smartClock = Thing( engine, {"thing": ClockURI, "newName": "SmartClock", "newTD": ClockTD}).post(interaction_patterns=[whatTimeIsIt, whatsTheTemperature]) whatTimeIsIt.enable() whatsTheTemperature.enable() local_engine = YSAPEngine("./example.ysap") # adding context triples local_engine.update("ADD_THERMOSTAT_CONTEXT_TRIPLES", forcedBindings={"th": ClockURI}) # # DEVICE LOOP # while True: try: sleep(10) except KeyboardInterrupt: print("Got KeyboardInterrupt!") whatTimeIsIt.disable() whatsTheTemperature.disable() break return 0
def test_3(self): """ This function performs checks for adding, updating and removing a new Property to a web thing. Notice that to do so, it is required to test also DataSchema and FieldSchema updates. Those two classes are not made to be removed, because they can always be used by other things. TODO The procedure to remove them is more complex and involves some queries before performing the delete. In case reset==True, check jsons are updated. However, the plain 'res_query_all' is not overwritten, because the presence of new DataSchema and FieldSchema here requires the existance of a different file named 'res_query_all_new_dataschema.json'. True or False is returned for success or failure. """ THING_URI = "<http://TestThing.com>" PROPERTY_URI = "<http://TestProperty.com>" NEW_PROPERTY_VALUE = "HIJKLMNOP" TEST_TD = "<http://TestTD.com>" # Adding the new thing dummyThing = Thing( self.engine, {"thing": THING_URI, "newName": "TEST-THING", "newTD": TEST_TD}).post() # Adding the property p_fBindings = {"td": TEST_TD, "property": PROPERTY_URI, "newName": "TEST-PROPERTY", "newStability": "1", "newWritability": "true", "newDS": "<http://XSDstringDataSchema.org>", "newPD": "<http://TestThing.com/Property1/PropertyData>", "newValue": "ABCDEFG"} testProperty = Property(self.engine, p_fBindings).post() # Querying the property to check it query_result = self.engine.query( "DESCRIBE_PROPERTY", forcedBindings={"property_uri": PROPERTY_URI}) res_new_property_create = json.loads( read_all_file("res_new_property_create.json")) self.assertTrue(compare_queries( query_result, res_new_property_create)) # Updating property with a new writability and a new value p_fBindings["newWritability"] = "false" p_fBindings["newValue"] = NEW_PROPERTY_VALUE testProperty.update(p_fBindings) res_new_property_create["results"]["bindings"][0]["pWritability"]["value"] = "false" res_new_property_create["results"]["bindings"][0]["pValue"]["value"] = NEW_PROPERTY_VALUE res_new_property_update = resource_filename( __name__, "res_new_property_update.json") self.assertTrue(compare_queries( res_new_property_create, res_new_property_update, show_diff=True)) query_result = self.engine.query( "DESCRIBE_PROPERTY", forcedBindings={"property_uri": PROPERTY_URI}) self.assertTrue(compare_queries( query_result, res_new_property_update, show_diff=True)) # Deleting the property testProperty.delete() # Query all check dummyThing.delete() self.assertTrue(compare_queries( self.engine.query_all(), resource_filename(__name__, "res_query_all_new_dataschema.json"), show_diff=True))
def main(args): with open(args["ysap_file"], "r") as ysap_file: ysap = SAPObject(yaml.load(ysap_file)) engine = SEPA(sapObject=ysap, logLevel=logging.ERROR) try: if not args["subscribe"]: # Plain queries using the direct cocktail call if args["thing"]: print("Thing discovery:") print(Thing.discover(engine, nice_output=args["nice"])) if args["action"]: print("Action discovery:") print(Action.discover(engine, nice_output=args["nice"])) if args["event"]: print("Event discovery:") print(Event.discover(engine, nice_output=args["nice"])) if args["property"]: print("Property discovery:") print(Property.discover(engine, nice_output=args["nice"])) if args["dataschema"]: print("DataSchema discovery:") print(DataSchema.discover(engine, nice_output=args["nice"])) else: # subscriptions, using the ysap entries. # BTW, the queries call the same entries! They just use a different method subids = [] if args["thing"]: subids.append( engine.subscribe("DISCOVER_THINGS", "thing_discovery", handler=subscription_handler)) if args["action"]: subids.append( engine.subscribe("DESCRIBE_ACTION", "action_discovery", handler=subscription_handler)) if args["event"]: subids.append( engine.subscribe("DESCRIBE_EVENT", "event_discovery", handler=subscription_handler)) if args["property"]: subids.append( engine.subscribe("DESCRIBE_PROPERTY", "property_discovery", handler=subscription_handler)) if args["dataschema"]: subids.append( engine.subscribe("GET_DATASCHEMAS", "dataschema_discovery", handler=subscription_handler)) if subids != []: try: # Waits for subscription notifications while True: sleep(10) except KeyboardInterrupt: print("Got Ctrl-C! Bye bye!") finally: for subscription in subids: engine.unsubscribe(subscription) except Exception as ex: print("Got exception while trying to contact SEPA:\n{}".format(ex), file=sys.stderr) return 1 return 0
def main(args): global engine # opening the sap file, and creating the SEPA instance engine = YSAPEngine("./cocktail_sap.ysap") if "clear" in args: engine.clear() # # IDENTIFICATION OF INTERACTION PATTERNS # # Setup the Threshold Action threshold_Action = Action( engine, { "td": ThermostatTD, "action": "<http://MyThermostat.swot/ThresholdAction>", "newName": "ThresholdAction", "ids": ds_threshold }, threshold_update) # Setup the Event temperature_Event = Event( engine, { "td": ThermostatTD, "event": "<http://MyThermostat.swot/TemperatureEvent>", "eName": "TemperatureEvent", "ods": ds_lambda }) # # POSTING TRIPLES TO THE SWTE # # Setup and post the WebThing thermostat = Thing( engine, { "thing": ThermostatURI, "newName": "SmartThermostat", "newTD": ThermostatTD }).post(interaction_patterns=[threshold_Action, temperature_Event]) local_engine = YSAPEngine("./example.ysap") # # OPTIONAL THING DESCRIPTION JSON-LD # thermostat.tdServer_start("localhost", 8321) # adding context triples local_engine.update("ADD_THERMOSTAT_CONTEXT_TRIPLES", forcedBindings={"th": ThermostatURI}) # enabling threshold Action threshold_Action.enable() # main thermostat triggering logic local_engine.subscribe("THERMOSTAT_SMART_DISCOVERY", "thermostat_subscription", forcedBindings={"ds": ds_psi}, handler=available_actuators) # # DEVICE LOOP # # temperature Event triggering logic event_bindings = {"event": temperature_Event.uri, "newDS": ds_lambda} try: while True: sleep(2) unique_id = uuid4() event_bindings[ "newEInstance"] = "<http://MyThermostat.swot/TemperatureEvent/Instance_{}>".format( unique_id) event_bindings[ "newOData"] = "<http://MyThermostat.swot/TemperatureEvent/Data_{}>".format( unique_id) # in the real world this simulate() call would be a read to a temperature sensor! event_bindings["newValue"] = str(simulate()) temperature_Event.notify(event_bindings) with thresholdLock: if float(event_bindings["newValue"]) < T_low: message = '{{"target": {}, "now": "warming"}}'.format( T_low) trigger_action(message) elif float(event_bindings["newValue"]) > T_high: message = '{{"target": {}, "now": "cooling"}}'.format( T_high) trigger_action(message) except KeyboardInterrupt: print("Got KeyboardInterrupt!") except Exception as ex: print("Temperature simulation failed! Check the simulation server: {}". format(ex)) threshold_Action.disable() thermostat.tdServer_stop() return 0
def test_1(self): """ This test checks if the sparql insert of Thing2 and the sum of cocktail sparqls have the same effect in the rdf store. """ thing_descriptor = "<http://MySecondWebThingDescription.com>" # self.engine.sap.update_namespaces( # "foaf", "http://xmlns.com/foaf/0.1/") self.engine.sparql_update(read_all_file("insert_dataschemas.sparql")) self.engine.sparql_update(read_all_file("insert_thing_2.sparql")) query_all_sparql = self.engine.query_all() self.engine.clear() self.engine.sparql_update(read_all_file("insert_dataschemas.sparql")) thing1 = Thing( self.engine, {"thing": "<http://MySecondWebThing.com>", "newName": "Thing2", "newTD": thing_descriptor}).post() property1 = Property( self.engine, {"td": thing_descriptor, "property": "<http://MySecondWebThing.com/Property1>", "newName": "Thing2_Property1", "newStability": "0", "newWritability": "false", "newDS": ds_json, "newPD": "<http://MySecondWebThing.com/Property1/PropertyData>", "newValue": '{"json":"content"}'}).post() property2 = Property( self.engine, {"td": thing_descriptor, "property": "<http://MySecondWebThing.com/Property2>", "newName": "Thing2_Property2", "newStability": "75", "newWritability": "true", "newDS": ds_string, "newPD": "<http://MySecondWebThing.com/Property2/PropertyData>", "newValue": "Whatever kind of binary content"}).post() action1 = Action( self.engine, {"thing": thing1.uri, "td": thing_descriptor, "action": "<http://MySecondWebThing.com/Action1>", "newName": "Thing2_Action1", "ids": ds_foaf, "ods": ds_string}, lambda: print("ACTION 1 HANDLER RUN"), forProperties=[property1, property2]).post() event1 = Event( self.engine, {"td": thing_descriptor, "event": "<http://MySecondWebThing.com/Event1>", "eName": "Thing2_Event1", "ods": ds_integer}, forProperties=[property2]).post() event2 = Event( self.engine, {"td": thing_descriptor, "event": "<http://MySecondWebThing.com/Event2>", "eName": "Thing2_Event2", "ods": ds_genericWebResource}).post() query_all_cocktail = self.engine.query_all() self.assertTrue(compare_queries( query_all_cocktail, query_all_sparql, show_diff=True))
def main(args): global engine global HC_Property_bindings global HC_Property # opening the sap file, and creating the SEPA instance engine = YSAPEngine("./cocktail_sap.ysap") if "clear" in args: engine.clear() # # IDENTIFICATION AND DESCRIPTION OF INTERACTION PATTERNS # # Setup the Hot/Cold Action mainHC_Action = Action( engine, {"td": HotColdTD, "action": HotColdActionURI, "newName": "MainHotColdAction", "ids": ds_psi}, mainHotColdActionLogic) HC_Property_bindings = {"td": HotColdTD, "property": HotColdPropertyURI, "newName": "InternalStatusHotColdProperty", "newStability": "0", "newWritability": "false", "newDS": ds_psi, "newPD": "<http://HotCold.swot/MainHotColdProperty/Data>", "newValue": '{"now": "off", "target": "15"}'} HC_Property = Property(engine, HC_Property_bindings) # # POSTING TRIPLES TO THE SWTE # # Setup and post the WebThing thermostat = Thing( engine, {"thing": HotColdURI, "newName": "HotCold", "newTD": HotColdTD}).post(interaction_patterns=[mainHC_Action, HC_Property]) mainHC_Action.enable() local_engine = YSAPEngine("./example.ysap") # adding context triples local_engine.update("ADD_HOTCOLD_CONTEXT_TRIPLES", forcedBindings={"hc": HotColdURI}) # main hotcold event search logic local_engine.subscribe( "HOTCOLD_SMART_DISCOVERY", "hotcold_subscription", forcedBindings={"ds": ds_lambda}, handler=available_sensors) # # DEVICE LOOP # try: while True: sleep(10) print("Device status is currently {}".format(HC_Property.value)) except KeyboardInterrupt: print("Got KeyboardInterrupt!") mainHC_Action.disable() return 0