//================================
//==== RTU VC6 Demo
//================================
//		please put the RTU_VC6_demo.exe and RTU Center in a folder
//		or RTU_VC6_demo.exe cannot read data from RTU Center
//================================

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include "M2M_RTU.h"

void main(void)
{
	int iAction=1, quit=1;
	unsigned int ver;
	char bVerDate[32] = {0};
	unsigned int stationN=0;
	int res=0;
	struct OPC_Total_Info staInfo = {0};
	int i, j;

	printf("==== RTU API demo ====\n");

	while(iAction!=0)
	{
		iAction=0;
		quit=0;
		
        printf("\n");
		printf("1) Get API version and date\n");
		printf("2) Get Station number\n");
		printf("3) Start to get station information\n");
		printf("4) get local IO\n");
		printf("5) write local IO\n");
		printf("6) get remote IO\n");
		printf("7) write remote DO\n");
		printf("8) write remote AO\n");
        printf("\n");
        printf("0) Exit\n\n");
        printf("Choose an option and press [Enter]: ");
        scanf("%d", &iAction);
        printf("\n");

		switch(iAction)
		{
		case 1:
			//-- Get API version and date
			ver = GetDllVersion();
			printf("API Ver = %X.%X\n", (ver&0xFF00)>>8, ver&0xFF);
			GetDllDate(bVerDate);
			printf("API Date = %s\n", bVerDate);
			
			break;

		case 2:
			//-- Get Station number
			res = GET_Total_Station_NUM(&stationN);
			if (res == 0)
				printf("Station Number = %d\n", stationN);
			else
			{
				printf("Initial Fails, Error code = %d\n", res);
				printf("\t1 -> RTU device is disconnected\n");
				printf("\t2 -> IO data error\n");
				printf("\t3 -> initial Error, maybe RTU Center is not active\n");
				printf("\t4 -> Station ID or Modbus Slave ID Error\n");
				printf("\t5 -> GPS function is not Enable\n");
				printf("\t6 -> Channel Number Error\n");
			}

			break;

		case 3:
			//-- Start to get station information
			for(i=0; i<(int)stationN; i++)
			{
				res = GET_StationID_Total_Info(i, &staInfo);
				if(res==0)//No Error
				{
					//- convert "Station Alias" to wide char format
					WCHAR wName[21] = {0};//station alias length = 40 --> wchar = 20
					for(j=0; j<20; j++)
					{
						wName[j] = staInfo.cModule_Name[2*j+1] << 8;	// high byte
						wName[j] |= staInfo.cModule_Name[2*j];	// low byte
					}
					printf("----\n");
					printf("Station ID = %u\n", staInfo.iStationID);
					printf("  device type = %u\n", staInfo.iModule);//module type: 0=G-4500, 1=GT-540
					//printf("  Module Name (Alias) = %s\n", staInfo.cModule_Name);//don't use "printf" directly
					wprintf(L"  Module Name (Alias) = %s\n", wName);
					printf("  Modbus Number = %u\n", staInfo.iModbus_Num);
					//- IO information
					for (j=0; j<(int)staInfo.iModbus_Num; j++)
					{
						char mbName[24]={0};
						printf("\t-- Modbus(%d) --\n", j);
						memcpy(mbName, staInfo.Modbus_Module_Name[j], 24);
						printf("\tName = %s\n", mbName);
						printf("\tsID = %d\n", staInfo.Slave_ID[j]);
						printf("\tDI x%d\n", staInfo.DI_Num[j]);
						printf("\tDO x%d\n", staInfo.DO_Num[j]);
						printf("\tAI x%d\n", staInfo.AI_Num[j]);
						printf("\tAO x%d\n", staInfo.AO_Num[j]);
						printf("\tCount x%d\n", staInfo.Counter_Num[j]);
						printf("\tenGPS = %d\n", staInfo.usEnGPS[j]);
						printf("\n");
					}
				}else
				{
					printf("!!!! cannot get Staintion Information !!!!, Error: %d\n", res);
				}
			}
			break;

		case 4:
			{
				//-- get local data
				unsigned int SID = 2;
				unsigned char mbSID = 255;
				unsigned char bValue = 0;
				unsigned short usValue = 0;
				unsigned int iValue = 0;
				unsigned long value = 0;
				BYTE mbName[] = "Local IO";
				int result;
				int YY=0, Mon=0, DD=0, hh=0, mm=0, ss=0;
				printf("----------\n");
				GET_DateTime(SID, &YY, &Mon, &DD, &hh, &mm, &ss);
				printf("--- %2d/%2d/%2d %2d:%2d:%2d ---\n", YY, Mon, DD, hh, mm, ss);
				printf("Station ID: %d, mbSlave ID:%d, Modbus Name=%s\n", SID, mbSID, mbName);

				// although, you will get a Error code, but function still return the last value
				//- DI, single channel
				result = GET_Modbus_DI_Channel(SID, mbName, mbSID, 0, &bValue);
				if (result == 0)
					printf("DI ch0 =%d\n", bValue);
				else
					printf("DI ch0 =%d, Error=%d\n", bValue, result);

				//- DIs
				result = GET_Modbus_DI(SID, mbName, mbSID, &value);
				if (result == 0)
					printf("DIs =%X\n", value);
				else
					printf("DIs =%X ,Error = %d\n", value, result);
				
				//- DO, single channel
				result = GET_Modbus_DO_Channel(SID, mbName, mbSID, 0, &bValue);
				if (result == 0)
					printf("DO ch0 =%d\n", bValue);
				else
					printf("DO ch0 =%d, Error=%d\n", bValue, result);
				
				//- DOs
				result = GET_Modbus_DO(SID, mbName, mbSID, &value);
				if (result == 0)
					printf("DOs =%X\n", value);
				else
					printf("DOs =%X ,Error = %d\n", value, result);

				//- counter, single channel
				result = GET_Modbus_Counter_Channel(SID, mbName, mbSID, 0, &iValue);
				if (result == 0)
					printf("Counter ch0 =%d", iValue);
				else
					printf("Counter ch0 =%d, Error=%d\n", iValue, result);
				
				//- don't care these two variable, just pass two variable to the function
				BYTE bDataFormat = 0;
				BYTE bType = 0;
				//- AI
				result = GET_Modbus_AI_Channel(SID, mbName, mbSID, 0,
					&bDataFormat, &bType, &usValue);
				if (result == 0)
				{
					printf("AI ch0 Hex =%X\n", usValue);
					double AI_value = usValue / 4095.0 * 20.0;//for GT-540, AI is 12 bits, 0~20mA
					printf("  Hex --> mA :%.3f mA\n", AI_value);
				}
				else
					printf("AI ch0 Hex =%X, Error=%d\n", usValue, result);
				
				//- AO
				result = GET_Modbus_AO_Channel(SID, mbName, mbSID, 0,
					&bDataFormat, &bType, &usValue);
				if (result == 0)
					printf("AO ch0 = %d\n", usValue);
				else
					printf("AO ch0 = %d, Error=%d\n", usValue, result);
				
				char bGPS[256] = {0};
				result = GET_Modbus_GPS(SID, mbName, mbSID, bGPS);
				if (result == 0)
				{
					printf("GPS :\n%s\n", bGPS);
				}
				else
					printf("GPS : Error = %d\n", result);
				
				printf("----------\n");

			}			
			break;

		case 5:
			//-- Write local IO
			{
				unsigned int SID = 2;
				unsigned char mbSID = 255;
				unsigned char bValue = 0;
				BYTE mbName[] = "Local IO";
				int result;
				
				GET_Modbus_DO_Channel(SID, mbName, mbSID, 0, &bValue);
				if (bValue == 0)
					bValue = 1;
				else
					bValue = 0;
				
				result = WRITE_Modbus_DO_Channel(SID, mbName, mbSID, 0, bValue);
				
				if (result == 0)
				{
					printf("success to write DO as %d\n", bValue);
					printf("the DO status will change later, because GPRS is slow...\n");
				}
				else
					printf("fails to write DO\n");

			}
			
			break;

		case 6:
			//-- Get remote IO
			{
				//-- get local data
				unsigned int SID = 2;
				unsigned char mbSID = 33;//!! set as your modbus ID
				BYTE mbName[] = "MB_33";//!! set as your modbus name
				unsigned char bValue = 0;
				unsigned short usValue = 0;
				unsigned int iValue = 0;
				unsigned long value = 0;
				int result;
				int YY=0, Mon=0, DD=0, hh=0, mm=0, ss=0;
				printf("----------\n");
				GET_DateTime(SID, &YY, &Mon, &DD, &hh, &mm, &ss);
				printf("--- %2d/%2d/%2d %2d:%2d:%2d ---\n", YY, Mon, DD, hh, mm, ss);
				printf("Station ID: %d, mbSlave ID:%d, Modbus Name=%s\n", SID, mbSID, mbName);
				
				// although, you will get a Error code, but function still return the last value
				//- DI, single channel
				result = GET_Modbus_DI_Channel(SID, mbName, mbSID, 0, &bValue);
				if (result == 0)
					printf("DI ch0 =%d\n", bValue);
				else
					printf("DI ch0 =%d, Error=%d\n", bValue, result);
				
				//- DIs
				result = GET_Modbus_DI(SID, mbName, mbSID, &value);
				if (result == 0)
					printf("DIs =%X\n", value);
				else
					printf("DIs =%X ,Error = %d\n", value, result);
				
				//- DO, single channel
				result = GET_Modbus_DO_Channel(SID, mbName, mbSID, 0, &bValue);
				if (result == 0)
					printf("DO ch0 =%d\n", bValue);
				else
					printf("DO ch0 =%d, Error=%d\n", bValue, result);
				
				//- DOs
				result = GET_Modbus_DO(SID, mbName, mbSID, &value);
				if (result == 0)
					printf("DOs =%X\n", value);
				else
					printf("DOs =%X ,Error = %d\n", value, result);
				
				//- counter, single channel
				result = GET_Modbus_Counter_Channel(SID, mbName, mbSID, 0, &iValue);
				if (result == 0)
					printf("Counter ch0 =%d\n", iValue);
				else
					printf("Counter ch0 =%d, Error=%d\n", iValue, result);
				
				//- don't care these two variable, just pass two variable to the function
				BYTE bDataFormat = 0;
				BYTE bType = 0;
				//- AI
				result = GET_Modbus_AI_Channel(SID, mbName, mbSID, 0,
					&bDataFormat, &bType, &usValue);
				if (result == 0)
				{
					printf("AI ch0 Hex =%X\n", usValue);
					double AI_value = usValue / 4095.0 * 20.0;//for GT-540, AI is 12 bits, 0~20mA
					printf("  Hex --> mA :%.3f mA\n", AI_value);
				}
				else
					printf("AI ch0 Hex =%X, Error=%d\n", usValue, result);
				
				//- AO
				result = GET_Modbus_AO_Channel(SID, mbName, mbSID, 0,
					&bDataFormat, &bType, &usValue);
				if (result == 0)
					printf("AO ch0 = %d\n", usValue);
				else
					printf("AO ch0 = %d, Error=%d\n", usValue, result);
				
				printf("----------\n");

			}
			
			break;

		case 7:
			//-- Write remote IO
			{
				unsigned int SID = 2;
				unsigned char mbSID = 33;//!! set as your modbus ID
				BYTE mbName[] = "MB_33";//!! set as your modbus name
				unsigned char bValue = 0;
				unsigned short usValue = 0;
				BYTE bDataFormat = 0;
				BYTE bType = 0;
				int result;
				
				//- write DO --> inverse
				GET_Modbus_DO_Channel(SID, mbName, mbSID, 0, &bValue);
				if (bValue == 0)
					bValue = 1;
				else
					bValue = 0;
				
				result = WRITE_Modbus_DO_Channel(SID, mbName, mbSID, 0, bValue);
				
				if (result == 0)
				{
					printf("success to write DO as %d\n", bValue);
					printf("the DO status will change later, because GPRS is slow...\n");
				}
				else
					printf("fails to write DO\n");
			}
			
			break;

		case 8:
			//-- Write remote IO
			{
				unsigned int SID = 2;
				unsigned char mbSID = 33;//!! set as your modbus ID
				BYTE mbName[] = "MB_33";//!! set as your modbus name
				unsigned char bValue = 0;
				unsigned short usValue = 0;
				BYTE bDataFormat = 0;
				BYTE bType = 0;
				int result;
				
				//- write AO --> increase 1
				result = GET_Modbus_AO_Channel(SID, mbName, mbSID, 0,
					&bDataFormat, &bType, &usValue);
				usValue++;
				
				result = WRITE_Modbus_AO_Channel(SID, mbName, mbSID, 0, usValue);
				
				if (result == 0)
				{
					printf("success to write AO_0 as %d\n", usValue);
					printf("\nthe AO status will change later, because GPRS is slow...\n");
				}
				else
					printf("fails to write AO_0\n");
				
			}
			
			break;

		case 0:
		default:
			quit=1;
			break;

		}//end switch()

		if(!quit)
		{
			printf("Press any key to continue...\n\r");
			getch();
		}
	}
	
} 