Tutorial: Create Twin from tags list

Organizing the Data Hub from scratch can be challenging in the case a complete production line or plant is connected to the application. With Wizata API, this processed can be automatized to generate all the organization with a few lines of code.

Data schema

Wizata organizes process data with 3 types of items: Areas, Machines, Equipment. This hierarchy should be respected when digitizing a process. According to that, a simple table can be used as a starting point to create that hierarchy for the data sample sample data file from GitHub. Each datapoint must be attributed to a specific twin item, which can also be defined from that table:

areamachineequipmentdatapoint
Cement_plant_1crusher1motor1mt1_bearing1
Cement_plant_1crusher1motor1mt1_bearing2
Cement_plant_1crusher1motor1mt1_bearing3
Cement_plant_1crusher1motor1mt1_bearing4
Cement_plant_1crusher1motor2mt2_bearing1
Cement_plant_1crusher1motor2mt2_bearing2
Cement_plant_1crusher1motor2mt2_bearing3
Cement_plant_1crusher1motor2mt2_bearing4

The data table indicates that there are 8 measures of bearings vibrations, on 2 motors located in 1 crushing machine, located in a cement plant.

Data Hub programmatic creation

A simple loop can navigate through the above table, create the twin items in the Data Hub, and attach the related datapoints to the created twin entities. The following code iterates through areas, machines, equipment and creates related twin units and datapoints.

📘

The above table must be saved into a .csv file in order to execute the code bellow.

datahub = pd.read_csv("datahub_bearings.csv")
areas = datahub["area"].unique()
machines = datahub["machine"].unique()
equipments = datahub["equipment"].unique()

for area in areas:
    # Create area twin item
    area_twin = wizata_dsapi.Twin(
        hardware_id=area,
        name=area,
        ttype=wizata_dsapi.TwinBlockType.AREA
    )
    # Upload twin item to Data Hub
    try:
        wizata_dsapi.api().upsert_twin(area_twin)
    except Exception as e:
        print(e)
        continue

    temp_area = datahub[datahub["area"] == area]
    machines = temp_area["machine"].unique()
    for machine in machines:
        # Create machine twin item
        machine_name = area + "_" + machine
        machine_twin = wizata_dsapi.Twin(
            hardware_id=machine_name,
            name=machine_name,
            parent_id=area_twin.twin_id,
            ttype=wizata_dsapi.TwinBlockType.MACHINE
        )
        try:
            wizata_dsapi.api().upsert_twin(machine_twin)
        except Exception as e:
            print(e)
            continue

        # Filter equipments for this machine
        temp_machine = temp_area[temp_area["machine"] == machine]
        equipments = temp_machine["equipment"].unique()
        for equipment in equipments:
            # Create equipment
            equipment_name = area + "_" + machine + "_" + equipment
            equipment_twin = wizata_dsapi.Twin(
                hardware_id=equipment_name,
                name=equipment_name,
                parent_id=machine_twin.twin_id,
                ttype=wizata_dsapi.TwinBlockType.EQUIPMENT
            )
            try:
                wizata_dsapi.api().upsert_twin(equipment_twin)
            except Exception as e:
                print(e)
                continue
            # Filter datapoints of that equipment
            temp_equipment = temp_machine[temp_machine["equipment"] == equipment]
            for datapoint in temp_equipment["datapoint"]:
                # Update existing datapoint
                try:
                    dp = wizata_dsapi.api().search_datapoints(hardware_id=datapoint).results[0]
                    dp.twin_id = equipment_twin.twin_id
                    wizata_dsapi.api().upsert_datapoint(dp)
                # Create datapoint if not existing yet
                except Exception as e:
                    print("Datapoint doesn't exist yet, creating...")
                    dp = wizata_dsapi.DataPoint()
                    dp.hardware_id = datapoint
                    dp.name = datapoint
                    dp.twin_id = equipment_twin.twin_id
                    wizata_dsapi.api().upsert_datapoint(dp)
                    
            print(f"Created {area}, {machine}, {equipment} and attached datapoints")

After executed, the result can be observed directly on the Wizata Data Hub, with:

  1. Root twin corresponding to "area" field from the table
  2. Crusher 1 created from "machine" field
  3. Motor 1 and 2 created from "equipment" fields
  4. Datapoints attached to corresponding equipment