Example #1
0
		public static Record operator + (Record Rec1, Record Rec2)
		{
			if (Rec1 == null)
				return Rec2;
			else if (Rec2 == null)
				return Rec1;
			else
			{
				Record Result = new Record (Rec1.timestamp > Rec2.timestamp ? Rec1.timestamp : Rec2.timestamp,
					Rec1.temperatureC + Rec2.temperatureC,
					Rec1.lightPercent + Rec2.lightPercent,
					Rec1.motion | Rec2.motion);

				Result.rank = Math.Max (Rec1.rank, Rec2.rank);

				return Result;
			}
		}
Example #2
0
        public static Record operator +(Record Rec1, Record Rec2)
        {
            if (Rec1 == null)
            {
                return(Rec2);
            }
            else if (Rec2 == null)
            {
                return(Rec1);
            }
            else
            {
                Record Result = new Record(Rec1.timestamp > Rec2.timestamp ? Rec1.timestamp : Rec2.timestamp,
                                           Rec1.temperatureC + Rec2.temperatureC,
                                           Rec1.lightPercent + Rec2.lightPercent,
                                           Rec1.motion | Rec2.motion);

                Result.rank = Math.Max(Rec1.rank, Rec2.rank);

                return(Result);
            }
        }
Example #3
0
		public static int Main (string[] args)
		{
			Log.Register (new ConsoleOutEventLog (80));
			Log.Information ("Initializing application...");

			HttpSocketClient.RegisterHttpProxyUse (false, false);	// Don't look for proxies.

			DB.BackupConnectionString = "Data Source=sensor.db;Version=3;";
			DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider";
			db = DB.GetDatabaseProxy ("TheSensor");

			Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) =>
			{
				e.Cancel = true;
				executionLed.Low ();
			};

			// Initializing hardware and retrieving current sensor values

			try
			{
				tmp102.Configure (false, TexasInstrumentsTMP102.FaultQueue.ConsecutiveFaults_6, TexasInstrumentsTMP102.AlertPolarity.AlertActiveLow,
					TexasInstrumentsTMP102.ThermostatMode.ComparatorMode, false, TexasInstrumentsTMP102.ConversionRate.Hz_1, false);

				temp = (short)tmp102.ReadTemperatureRegister ();
				temperatureC = temp / 256.0;

				for (int i = 0; i < 10; i++)
					tempAvgWindow [i] = temp;

				sumTemp = temp * 10;
			} catch (Exception ex)
			{
				Log.Exception (ex);

				sumTemp = 0;
				temperatureC = 0;
				errorLed.High ();
			}

			try
			{
				adc.Configure (true, false, false, false, false, false);

				light = adc.ReadRegistersBinary () [0];
				lightPercent = (100.0 * light) / 0x0fff;

				for (int i = 0; i < 10; i++)
					lightAvgWindow [i] = light;

				sumLight = light * 10;
			} catch (Exception ex)
			{
				Log.Exception (ex);

				sumLight = 0;
				lightPercent = 0;
				errorLed.High ();
			}

			// Loading historical Sensor Values

			Log.Information ("Loading Minute Values.");
			perMinute.AddRange (Record.LoadRecords (Rank.Minute));

			Log.Information ("Loading Hour Values.");
			perHour.AddRange (Record.LoadRecords (Rank.Hour));

			Log.Information ("Loading Day Values.");
			perDay.AddRange (Record.LoadRecords (Rank.Day));

			Log.Information ("Loading Month Values.");
			perMonth.AddRange (Record.LoadRecords (Rank.Month));

			// Resuming average calculations

			int Pos = perSecond.Count;
			DateTime CurrentTime = DateTime.Now;
			DateTime Timestamp;

			while (Pos-- > 0)
			{
				Record Rec = perSecond [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Minute == CurrentTime.Minute && Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date)
				{
					sumSeconds += Rec;
					nrSeconds++;
				} else
					break;
			}

			Pos = perMinute.Count;
			while (Pos-- > 0)
			{
				Record Rec = perMinute [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date)
				{
					sumMinutes += Rec;
					nrMinutes++;
				} else
					break;
			}

			Pos = perHour.Count;
			while (Pos-- > 0)
			{
				Record Rec = perHour [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Date == CurrentTime.Date)
				{
					sumHours += Rec;
					nrHours++;
				} else
					break;
			}

			Pos = perDay.Count;
			while (Pos-- > 0)
			{
				Record Rec = perDay [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Month == CurrentTime.Month && Timestamp.Year == CurrentTime.Year)
				{
					sumDays += Rec;
					nrDays++;
				} else
					break;
			}

			// Sampling of new Sensor Values

			Timer Timer = new Timer (SampleSensorValues, null, 1000 - DateTime.Now.Millisecond, 1000);	// Every second.

			// HTTP Interface

			HttpServer HttpServer = new HttpServer (80, 10, true, true, 1);

			Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ());

			HttpServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash));
			HttpServer.RegisterAuthenticationMethod (new SessionAuthentication ());

			credentials = LoginCredentials.LoadCredentials ();
			if (credentials == null)
			{
				credentials = new LoginCredentials ();
				credentials.UserName = "******";
				credentials.PasswordHash = CalcHash ("Admin", "Password");
				credentials.SaveNew ();
			}

			HttpServer.Register ("/", HttpGetRoot, HttpPostRoot, false);							// Synchronous, no authentication
			HttpServer.Register ("/html", HttpGetHtml, false);										// Synchronous, no authentication
			HttpServer.Register ("/historygraph", HttpGetHistoryGraph, false);						// Synchronous, no authentication
			HttpServer.Register ("/credentials", HttpGetCredentials, HttpPostCredentials, false);	// Synchronous, no authentication
			HttpServer.Register ("/xml", HttpGetXml, true);											// Synchronous, http authentication
			HttpServer.Register ("/json", HttpGetJson, true);										// Synchronous, http authentication
			HttpServer.Register ("/turtle", HttpGetTurtle, true);									// Synchronous, http authentication
			HttpServer.Register ("/rdf", HttpGetRdf, true);											// Synchronous, http authentication
			HttpServer.Register ("/event/xml", HttpGetEventXml, true, false);						// Asynchronous, http authentication
			HttpServer.Register ("/event/json", HttpGetEventJson, true, false);						// Asynchronous, http authentication
			HttpServer.Register ("/event/turtle", HttpGetEventTurtle, true, false);					// Asynchronous, http authentication
			HttpServer.Register ("/event/rdf", HttpGetEventRdf, true, false);						// Asynchronous, http authentication

			// HTTPS interface

			// Certificate must be a valid P12 (PFX) certificate file containing a private key.
			// X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD");
			// HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate);
			//
			// HttpsServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash));
			// HttpsServer.RegisterAuthenticationMethod (new SessionAuthentication ());
			// 
			// foreach (IHttpServerResource Resource in HttpServer.GetResources())
			//    HttpsServer.Register (Resource);
			// 
			// Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ());

			// Main loop

			Log.Information ("Initialization complete. Application started...");

			try
			{
				while (executionLed.Value)
				{
					System.Threading.Thread.Sleep (1000);
				}
			} catch (Exception ex)
			{
				Log.Exception (ex);
				executionLed.Low ();
			} finally
			{
				Log.Information ("Terminating application.");
				Log.Flush ();
				Log.Terminate ();
				Timer.Dispose ();
				HttpServer.Dispose ();
				//HttpsServer.Dispose ();
				executionLed.Dispose ();
				measurementLed.Dispose ();
				errorLed.Dispose ();
				networkLed.Dispose ();
				motion.Dispose ();
				i2cBus.Dispose ();
			}

			return 0;
		}
Example #4
0
		private static void SampleSensorValues (object State)
		{
			measurementLed.High ();
			try
			{
				lock (synchObject)
				{
					DateTime Now = DateTime.Now;
					Record Rec, Rec2;

					// Read sensors

					temp = (short)tmp102.ReadTemperatureRegister ();
					light = adc.ReadRegistersBinary () [0];

					// Calculate average of last 10 measurements, to get smoother momentary values

					sumTemp -= tempAvgWindow [avgPos];
					sumLight -= lightAvgWindow [avgPos];

					tempAvgWindow [avgPos] = temp;
					lightAvgWindow [avgPos] = light;

					sumTemp += temp;
					sumLight += light;
					motionDetected = motion.Value;

					temperatureC = (sumTemp * 0.1 / 256.0);
					lightPercent = (100.0 * 0.1 * sumLight) / 0x0fff;
					avgPos = (avgPos + 1) % 10;

					// Update history

					Rec = new Record (Now, temperatureC, lightPercent, motionDetected);		// Rank 0

					perSecond.Add (Rec);
					if (perSecond.Count > 1000)
						perSecond.RemoveAt (0);

					sumSeconds += Rec;
					nrSeconds++;

					if (Now.Second == 0)
					{
						Rec = sumSeconds / nrSeconds;		// Rank 1
						perMinute.Add (Rec);
						Rec.SaveNew ();

						if (perMinute.Count > 1000)
						{
							Rec2 = perMinute [0];
							perMinute.RemoveAt (0);
							Rec2.Delete ();
						}

						sumMinutes += Rec;
						nrMinutes++;

						sumSeconds = null;
						nrSeconds = 0;

						if (Now.Minute == 0)
						{
							Rec = sumMinutes / nrMinutes;
							perHour.Add (Rec);
							Rec.SaveNew ();

							if (perHour.Count > 1000)
							{
								Rec2 = perHour [0];
								perHour.RemoveAt (0);
								Rec2.Delete ();
							}

							sumHours += Rec;
							nrHours++;

							sumMinutes = null;
							nrMinutes = 0;

							if (Now.Hour == 0)
							{
								Rec = sumHours / nrHours;
								perDay.Add (Rec);
								Rec.SaveNew ();

								if (perDay.Count > 1000)
								{
									Rec2 = perDay [0];
									perDay.RemoveAt (0);
									Rec2.Delete ();
								}

								sumDays += Rec;
								nrDays++;

								sumHours = null;
								nrHours = 0;

								if (Now.Day == 1)
								{
									Rec = sumDays / nrDays;
									perMonth.Add (Rec);
									Rec.SaveNew ();

									sumDays = null;
									nrDays = 0;
								}
							}
						}
					}

					// Check pending events

					PendingEvent Event;
					int i = 0;
					int c = pendingEvents.Count;

					while (i < c)
					{
						Event = pendingEvents [i];

						if (Event.Trigger (temperatureC, lightPercent, motionDetected))
						{
							pendingEvents.RemoveAt (i);
							c--;

							HttpGetSensorData (Event.Response, Event.ContentType, Event.ExportModule, new ReadoutRequest (ReadoutType.MomentaryValues));
							Event.Response.SendResponse ();	// Flags the end of the response, and transmission of all to the recipient.

						} else
							i++;
					}
				}

				errorLed.Low ();

			} catch (Exception)
			{
				errorLed.High ();
			} finally
			{
				measurementLed.Low ();
				RemoveOldSessions ();
			}
		}
Example #5
0
		public static Record operator / (Record Rec, int N)
		{
			Record Result = new Record (Rec.timestamp, Rec.temperatureC / N, Rec.lightPercent / N, Rec.motion);
			Result.rank = (byte)(Rec.rank + 1);
			return Result;
		}
Example #6
0
		private static void SampleSensorValues (object State)
		{
			measurementLed.High ();
			try
			{
				lock (synchObject)
				{
					DateTime Now = DateTime.Now;
					Record Rec, Rec2;

					// Read sensors

					temp = (short)tmp102.ReadTemperatureRegister ();
					light = adc.ReadRegistersBinary () [0];

					// Calculate average of last 10 measurements, to get smoother momentary values

					sumTemp -= tempAvgWindow [avgPos];
					sumLight -= lightAvgWindow [avgPos];

					tempAvgWindow [avgPos] = temp;
					lightAvgWindow [avgPos] = light;

					sumTemp += temp;
					sumLight += light;
					motionDetected = motion.Value;

					temperatureC = (sumTemp * 0.1 / 256.0);
					lightPercent = (100.0 * 0.1 * sumLight) / 0x0fff;
					avgPos = (avgPos + 1) % 10;

					// Update history

					Rec = new Record (Now, temperatureC, lightPercent, motionDetected);		// Rank 0

					perSecond.Add (Rec);
					if (perSecond.Count > 1000)
						perSecond.RemoveAt (0);

					sumSeconds += Rec;
					nrSeconds++;

					if (Now.Second == 0)
					{
						Rec = sumSeconds / nrSeconds;		// Rank 1
						perMinute.Add (Rec);

						if (perMinute.Count > 1000)
						{
							Rec2 = perMinute [0];
							perMinute.RemoveAt (0);
						}

						sumMinutes += Rec;
						nrMinutes++;

						sumSeconds = null;
						nrSeconds = 0;

						if (Now.Minute == 0)
						{
							Rec = sumMinutes / nrMinutes;
							perHour.Add (Rec);

							if (perHour.Count > 1000)
							{
								Rec2 = perHour [0];
								perHour.RemoveAt (0);
							}

							sumHours += Rec;
							nrHours++;

							sumMinutes = null;
							nrMinutes = 0;

							if (Now.Hour == 0)
							{
								Rec = sumHours / nrHours;
								perDay.Add (Rec);

								if (perDay.Count > 1000)
								{
									Rec2 = perDay [0];
									perDay.RemoveAt (0);
								}

								sumDays += Rec;
								nrDays++;

								sumHours = null;
								nrHours = 0;

								if (Now.Day == 1)
								{
									Rec = sumDays / nrDays;
									perMonth.Add (Rec);

									sumDays = null;
									nrDays = 0;
								}
							}
						}
					}
				}

				errorLed.Low ();

			} catch (Exception)
			{
				errorLed.High ();
			} finally
			{
				measurementLed.Low ();
			}
		}
Example #7
0
		public static int Main (string[] args)
		{
			Log.Register (new ConsoleOutEventLog (80));
			Log.Information ("Initializing application...");

			HttpSocketClient.RegisterHttpProxyUse (false, false);	// Don't look for proxies.

			DB.BackupConnectionString = "Data Source=sensor.db;Version=3;";
			DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider";
			db = DB.GetDatabaseProxy ("TheSensor");

			Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) =>
			{
				e.Cancel = true;
				executionLed.Low ();
			};

			// Initializing hardware and retrieving current sensor values

			try
			{
				tmp102.Configure (false, TexasInstrumentsTMP102.FaultQueue.ConsecutiveFaults_6, TexasInstrumentsTMP102.AlertPolarity.AlertActiveLow,
					TexasInstrumentsTMP102.ThermostatMode.ComparatorMode, false, TexasInstrumentsTMP102.ConversionRate.Hz_1, false);

				temp = (short)tmp102.ReadTemperatureRegister ();
				temperatureC = temp / 256.0;

				for (int i = 0; i < 10; i++)
					tempAvgWindow [i] = temp;

				sumTemp = temp * 10;
			} catch (Exception ex)
			{
				Log.Exception (ex);

				sumTemp = 0;
				temperatureC = 0;
				errorLed.High ();
			}

			try
			{
				adc.Configure (true, false, false, false, false, false);

				light = adc.ReadRegistersBinary () [0];
				lightPercent = (100.0 * light) / 0x0fff;

				for (int i = 0; i < 10; i++)
					lightAvgWindow [i] = light;

				sumLight = light * 10;
			} catch (Exception ex)
			{
				Log.Exception (ex);

				sumLight = 0;
				lightPercent = 0;
				errorLed.High ();
			}

			// Loading historical Sensor Values

			Log.Information ("Loading Minute Values.");
			perMinute.AddRange (Record.LoadRecords (Rank.Minute));

			Log.Information ("Loading Hour Values.");
			perHour.AddRange (Record.LoadRecords (Rank.Hour));

			Log.Information ("Loading Day Values.");
			perDay.AddRange (Record.LoadRecords (Rank.Day));

			Log.Information ("Loading Month Values.");
			perMonth.AddRange (Record.LoadRecords (Rank.Month));

			// Resuming average calculations

			int Pos = perSecond.Count;
			DateTime CurrentTime = DateTime.Now;
			DateTime Timestamp;

			while (Pos-- > 0)
			{
				Record Rec = perSecond [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Minute == CurrentTime.Minute && Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date)
				{
					sumSeconds += Rec;
					nrSeconds++;
				} else
					break;
			}

			Pos = perMinute.Count;
			while (Pos-- > 0)
			{
				Record Rec = perMinute [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date)
				{
					sumMinutes += Rec;
					nrMinutes++;
				} else
					break;
			}

			Pos = perHour.Count;
			while (Pos-- > 0)
			{
				Record Rec = perHour [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Date == CurrentTime.Date)
				{
					sumHours += Rec;
					nrHours++;
				} else
					break;
			}

			Pos = perDay.Count;
			while (Pos-- > 0)
			{
				Record Rec = perDay [Pos];
				Timestamp = Rec.Timestamp;
				if (Timestamp.Month == CurrentTime.Month && Timestamp.Year == CurrentTime.Year)
				{
					sumDays += Rec;
					nrDays++;
				} else
					break;
			}

			// Sampling of new Sensor Values

			Timer Timer = new Timer (SampleSensorValues, null, 1000 - DateTime.Now.Millisecond, 1000);	// Every second.

			// HTTP Interface

			HttpServer HttpServer = new HttpServer (80, 10, true, true, 1);

			Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ());

			HttpServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash));
			HttpServer.RegisterAuthenticationMethod (new SessionAuthentication ());

			credentials = LoginCredentials.LoadCredentials ();
			if (credentials == null)
			{
				credentials = new LoginCredentials ();
				credentials.UserName = "******";
				credentials.PasswordHash = CalcHash ("Admin", "Password");
				credentials.SaveNew ();
			}

			HttpServer.Register ("/", HttpGetRoot, HttpPostRoot, false);							// Synchronous, no authentication
			HttpServer.Register ("/html", HttpGetHtml, false);										// Synchronous, no authentication
			HttpServer.Register ("/historygraph", HttpGetHistoryGraph, false);						// Synchronous, no authentication
			HttpServer.Register ("/credentials", HttpGetCredentials, HttpPostCredentials, false);	// Synchronous, no authentication
			HttpServer.Register ("/xml", HttpGetXml, true);											// Synchronous, http authentication
			HttpServer.Register ("/json", HttpGetJson, true);										// Synchronous, http authentication
			HttpServer.Register ("/turtle", HttpGetTurtle, true);									// Synchronous, http authentication
			HttpServer.Register ("/rdf", HttpGetRdf, true);											// Synchronous, http authentication
			HttpServer.Register ("/event/xml", HttpGetEventXml, true, false);						// Asynchronous, http authentication
			HttpServer.Register ("/event/json", HttpGetEventJson, true, false);						// Asynchronous, http authentication
			HttpServer.Register ("/event/turtle", HttpGetEventTurtle, true, false);					// Asynchronous, http authentication
			HttpServer.Register ("/event/rdf", HttpGetEventRdf, true, false);						// Asynchronous, http authentication

			// HTTPS interface

			// Certificate must be a valid P12 (PFX) certificate file containing a private key.
			// X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD");
			// HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate);
			//
			// HttpsServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash));
			// HttpsServer.RegisterAuthenticationMethod (new SessionAuthentication ());
			// 
			// foreach (IHttpServerResource Resource in HttpServer.GetResources())
			//    HttpsServer.Register (Resource);
			// 
			// Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ());

			// CoAP Interface

			CoapEndpoint CoapEndpoint = new CoapEndpoint ();
			Log.Information ("CoAP endpoint receiving requests on port " + CoapEndpoint.Port.ToString ());

			//CoapEndpoint.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal, true));
				
			CoapEndpoint.RegisterResource ("temp/txt", "Current Temperature, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, true, (Request, Payload) =>
				{
					return FieldNumeric.Format (temperatureC, "C", 1);
				});

			motionTxt = CoapEndpoint.RegisterResource ("motion/txt", "Motion detection, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 10, true, (Request, Payload) =>
				{
					return motionDetected ? "1" : "0";
				});

			CoapEndpoint.RegisterResource ("light/txt", "Current Light Density, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 2, true, (Request, Payload) =>
				{
					return FieldNumeric.Format (lightPercent, "%", 1);
				});

			foreach (CoapBlockSize BlockSize in Enum.GetValues(typeof(CoapBlockSize)))
			{
				if (BlockSize == CoapBlockSize.BlockLimit_Datagram)
					continue;

				string Bytes = (1 << (4 + (int)BlockSize)).ToString ();

				CoapEndpoint.RegisterResource ("xml/" + Bytes, "Complete sensor readout, in XML. Control content using query parmeters. Block size=" + Bytes + " bytes.", 
					BlockSize, false, 30, false, CoapGetXml);

				CoapEndpoint.RegisterResource ("json/" + Bytes, "Complete sensor readout, in JSON. Control content using query parmeters. Block size=" + Bytes + " bytes.", 
					BlockSize, false, 30, false, CoapGetJson);

				CoapEndpoint.RegisterResource ("turtle/" + Bytes, "Complete sensor readout, in TURTLE. Control content using query parmeters. Block size=" + Bytes + " bytes.", 
					BlockSize, false, 30, false, CoapGetTurtle);

				CoapEndpoint.RegisterResource ("rdf/" + Bytes, "Complete sensor readout, in RDF. Control content using query parmeters. Block size=" + Bytes + " bytes.", 
					BlockSize, false, 30, false, CoapGetRdf);
			}

			// MQTT

			mqttThread = new Thread (MqttThread);
			mqttThread.Name = "MQTT";
			mqttThread.Priority = ThreadPriority.BelowNormal;
			mqttThread.Start ();

			// Main loop

			Log.Information ("Initialization complete. Application started...");

			try
			{
				while (executionLed.Value)
				{
					System.Threading.Thread.Sleep (1000);
				}
			} catch (Exception ex)
			{
				Log.Exception (ex);
				executionLed.Low ();
			} finally
			{
				Log.Information ("Terminating application.");
				Log.Flush ();
				Log.Terminate ();
				Timer.Dispose ();

				HttpServer.Dispose ();
				//HttpsServer.Dispose ();

				CoapEndpoint.Dispose ();

				if (mqttThread != null)
				{
					mqttThread.Abort ();
					mqttThread = null;
				}

				executionLed.Dispose ();
				measurementLed.Dispose ();
				errorLed.Dispose ();
				networkLed.Dispose ();
				motion.Dispose ();
				i2cBus.Dispose ();
			}

			return 0;
		}