def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) stream_id = CONSTS['STREAM_ID'] # Ensure the stream exists on the SensorCloud endpoint. try: stream = pysc.models.Stream.single(stream_id) except KeyError: raise RuntimeWarning("""The stream named {:s} was not found.""".format(stream_id)) # Ensure sanity, check we got the stream that we asked for. assert (stream.id == stream.id) generated_results = [] obs = pysc.models.Observation(None, stream=stream) # The None just means we are creating a new observation # The following block just generates a chunk of 100 hourly observation results starting_time = datetime.now() - timedelta(hours=100) # an arbitrary starting time for i in range(1, 100): generated_results.append({"t": datetime_to_iso(starting_time + timedelta(hours=i)), "v": {"v": random.random() * 10.0}}) # add our list of results to the observation obs.results = generated_results obs.save() # Save here actually uploads the observation results to the stream. We don't get anything back.
def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) org_id = CONSTS['ORG_ID'] group_id = CONSTS['GROUP_ID'] # Ensure the organisation exists on the SensorCloud endpoint. try: organisation = pysc.models.Organisation.single(org_id) except KeyError: raise RuntimeWarning( """The organisation named {:s} was not found.""".format(org_id)) # Ensure sanity, check we got the organisation that we asked for. assert (org_id == organisation.id) # Ensure the group exists on the SensorCloud endpoint. try: group = pysc.models.Group.single(group_id) except KeyError: raise RuntimeWarning( """The group named {:s} was not found.""".format(group_id)) # Ensure sanity, check we got the group that we asked for. assert (group_id == group.id) # NOTE! We cannot delete a group that is assigned to any users or groups or anything. try: pysc.models.Group.delete( group_id, False ) # the second argument is `cascade`, we don't want to do that here. except KeyError: raise RuntimeError( "The group {:s} was not found on the SensorCloud endpoint!".format( group_id)) group = None try: group = pysc.models.Group.single(group_id) except KeyError: # We intend to hit this exception print("""The group named {:s} was deleted!.""".format(group_id)) # Final sanity check, ensure we didn't get an object returned from the Group.single() call above. assert group is None
def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) org_id = CONSTS['ORG_ID'] # Ensure the organisation exists on the SensorCloud endpoint. try: organisation = pysc.models.Organisation.single(org_id) except KeyError: raise RuntimeWarning( """The organisation named {:s} was not found.\n""" """Although the `pysc` api has functionality to create an organisation, it cannot """ """do so on the sensor-cloud.io instance on AWS.""".format(org_id)) # Ensure sanity, check we got the organisation that we asked for. assert (org_id == organisation.id) # use the organisation_id param to filter streams based on id stream_index = pysc.models.Stream.index(params={'organisation_id': org_id}) stream_count = 0 while True: stream_links = stream_index.links(rel="streams") # using the `.links()` helper on the index, we get a list of HALLink objects, not stream objects. # we have to do `.follow()` on each one to turn it into a HAL object. # Note, even after we do .follow() on the link, it is still not a `pysc` Stream() object, but a raw HAL object. # See the get_groups.py example for an example of using `.resolve_all()` rather than `.index()` for s in stream_links: stream_count += 1 stream = s.follow() stream_id = stream[ 'id'] # We have to use ['id'] because it is a raw HAL object, not a Stream() object. print("Found stream: {:s}".format(stream_id)) try: next_index = stream_index.link(rel="next") stream_index = next_index.follow() except LinkNotFoundError: break print( "Found a total of {:d} streams for {:s} on that SensorCloud endpoint.". format(stream_count, org_id))
def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) stream_id = CONSTS['STREAM_ID'] try: stream = pysc.models.Stream.single(stream_id) except KeyError: raise RuntimeWarning( """The stream named {:s} was not found.\n""".format(stream_id)) # Ensure sanity, check we got the stream that we asked for. assert (stream_id == stream.id) # get observations in chunks of 1000 results at a time chunk_size = 1000 offset = datetime.min while True: obs = stream.filtered_observations(limit=chunk_size, start=offset) c = len(obs.results) if c < 1: break results = obs.results last_time = offset for r in results: time = r['t'] time = datetime_from_iso(time) if time > last_time: last_time = time val = r['v'] if isinstance(val, dict): val = val['v'] print("Found observation result: {:s}: {:f}".format( str(time), val)) # add one second to the offset to avoid overlap with the final result in the last set offset = last_time + timedelta(seconds=1)
def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) org_id = CONSTS['ORG_ID'] new_group_id = CONSTS['NEW_GROUP'] # Ensure the organisation exists on the SensorCloud endpoint. try: organisation = pysc.models.Organisation.single(org_id) except KeyError: raise RuntimeWarning( """The organisation named {:s} was not found.\n""".format(org_id)) # Ensure sanity, check we got the organisation that we asked for. assert (org_id == organisation.id) new_group = pysc.models.Group( new_group_id ) # This is the equiv of calling `models.Group(None, 'group_id', None)` # This creates a new group in memory on the client side, but it is not pushed to SensorCloud yet. new_group.name = "My New Group" # Both the .name and .description properties of a Group are mandatory new_group.description = "Example of creating a new Group within my organisation in SensorCloud" new_group.organisation_id = org_id group = new_group.save( ) # This sends (saves) the new group to SensorCloud, and receives a Group object in return # Important! # If there was already a group with the same id on SensorCloud, the existing one will be overwritten! # But that is a good thing, because that is the only way you can change or update an existing model on SensorCloud. # and finally, sanity check that the group we got back has the same id as the group we sent. assert (new_group_id == group.id)
def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) org_id = CONSTS['ORG_ID'] # Ensure the organisation exists on the SensorCloud endpoint. try: organisation = pysc.models.Organisation.single(org_id) except KeyError: raise RuntimeWarning( """The organisation named {:s} was not found.\n""" """Although the `pysc` api has functionality to create an organisation, it cannot """ """do so on the sensor-cloud.io instance on AWS.""".format(org_id)) # Ensure sanity, check we got the organisation that we asked for. assert (org_id == organisation.id) # Here we use the Group.resolve_all helper with organisation_id param to filter groups based on id # The resolve_all command is similar to .index() however it also calls .follow() on found link automatically, # _and_ it converts the resulting HAL objects into real valid `pysc` Group() objects. org_groups = pysc.models.Group.resolve_all( params={'organisation_id': org_id}) # We are not likely to have more than 1000 groups, so we don't need to do return doc pagination here. for g in org_groups: group_id = g.id print("Found group: {:s}".format(group_id)) print( "Found a total of {:d} groups for {:s} on that SensorCloud endpoint.". format(len(org_groups), org_id))
def main(): """ Entrypoint for this example application :return: """ # Setup `pysc` to use BASIC auth, with a username, and password. Also sets the endpoint to use. setup_sensorcloud_basic(CONSTS['SC_USERNAME'], CONSTS['SC_PASSWORD'], CONSTS['SC_ENDPOINT'], CONSTS['PYSC_DEBUG']) org_id = CONSTS['ORG_ID'] location_id = CONSTS['LOCATION_ID'] stream_id = CONSTS['NEW_STREAM_ID'] # Ensure the organisation exists on the SensorCloud endpoint. try: organisation = pysc.models.Organisation.single(org_id) except KeyError: raise RuntimeWarning( """The organisation named {:s} was not found.\n""".format(org_id)) # Ensure sanity, check we got the organisation that we asked for. assert (org_id == organisation.id) # First we must ensure we have our location in the SensorCloud. If not, we will create it. try: location = pysc.models.Location.single(location_id) except KeyError: # it doesn't exist, so we will create it. We know the details new_location = pysc.models.Location(location_id) new_location.organisation_id = org_id new_location.geo_json = pysc.models.Location.GeoJSON(lat=-27.494743, lon=153.030034) new_location.description = "ESP Site in Brisbane" location = new_location.save( ) # Upload it to SensorCloud, and then use it for our stream. new_stream = pysc.models.Stream( stream_id ) # The equiv of calling `models.Stream(None, 'stream_id', None)` # This creates a new stream in memory on the client side, but it is not pushed to SensorCloud yet. new_stream.name = "My New Stream" # Both the .name and .description properties of a Stream are mandatory new_stream.description = "Example of creating a new Stream within my organisation in SensorCloud" new_stream.organisation_id = org_id new_stream.location_id = location.id new_stream.result_type = pysc.models.Stream.ResultTypes.scalar.value # Usually scalar new_stream.reporting_period = "PT1H" # Expected reporting_period period in ISO8601 duration format new_stream.sample_period = "PT1H" # Expected sample period in ISO8601 duration format # The rest of the metadata on the stream is stored in Metadata object. Lets create one. metadata = pysc.models.Stream.Metadata() # cumulative will be True or False. It is usually false unless you know it *is* cumulative. metadata.cumulative = False # Interpolation type will usually be either continuous, or discontinuous, but there are lots of others. metadata.interpolation_type = pysc.models.Stream.Metadata.InterpolationTypes.discontinuous.value # A text-version of a timezone. This is required when cumulative is True, optional otherwise. metadata.timezone = "Australia/Brisbane" # Unit of Measure and Observed Property are always required. # These URIs must match the white-listed sources of the SensorCloud instance. # Check for their existence on the SensorCloud vocabulary first metadata.unit_of_measure = "http://registry.it.csiro.au/def/environment/unit/CubicMetresPerCubicMetre" metadata.observed_property = "http://data.sense-t.org.au/registry/def/sop/soil_moisture" new_stream.stream_metadata = metadata stream = new_stream.save( ) # This sends (saves) the new stream to SensorCloud, and receives a Stream object # Important! # If there was already a stream with the same id on SensorCloud, the existing one will be overwritten! # But that is a good thing, because that is the only way you can change or update an existing model on SensorCloud. # and finally, sanity check that the stream we got back has the same id as the stream we sent. assert (stream_id == stream.id)