diff --git a/csharp/App/GpioTestingProject/GpioTestingProject.csproj b/csharp/App/GpioTestingProject/GpioTestingProject.csproj new file mode 100644 index 000000000..a4f20b48e --- /dev/null +++ b/csharp/App/GpioTestingProject/GpioTestingProject.csproj @@ -0,0 +1,16 @@ + + + + InnovEnergy.App.GpioTestingProject + + + + + + + + + + + + diff --git a/csharp/InnovEnergy.sln b/csharp/InnovEnergy.sln index 6c48122ab..91dc5abf0 100644 --- a/csharp/InnovEnergy.sln +++ b/csharp/InnovEnergy.sln @@ -1,27 +1,26 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Collector", "App\Collector\Collector.csproj", "{E3A5F3A3-72A5-47CC-85C6-2D8E962A0EC1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Collector", "App/Collector/Collector.csproj", "{E3A5F3A3-72A5-47CC-85C6-2D8E962A0EC1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenVpnCertificatesServer", "App\OpenVpnCertificatesServer\OpenVpnCertificatesServer.csproj", "{CF4834CB-91B7-4172-AC13-ECDA8613CD17}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenVpnCertificatesServer", "App/OpenVpnCertificatesServer/OpenVpnCertificatesServer.csproj", "{CF4834CB-91B7-4172-AC13-ECDA8613CD17}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteSupportConsole", "App\RemoteSupportConsole\RemoteSupportConsole.csproj", "{B1268C03-66EB-4486-8BFC-B439225D9D54}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteSupportConsole", "App/RemoteSupportConsole/RemoteSupportConsole.csproj", "{B1268C03-66EB-4486-8BFC-B439225D9D54}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SysTools", "Lib\SysTools\SysTools.csproj", "{4A67D79F-F0C9-4BBC-9601-D5948E6C05D3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SysTools", "Lib/SysTools/SysTools.csproj", "{4A67D79F-F0C9-4BBC-9601-D5948E6C05D3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebServer", "Lib\WebServer\WebServer.csproj", "{B2627B9F-41DF-44F7-A0D1-CA71FF4A007A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebServer", "Lib/WebServer/WebServer.csproj", "{B2627B9F-41DF-44F7-A0D1-CA71FF4A007A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeterDriver", "App\EmuMeterDriver\EmuMeterDriver.csproj", "{F65F33B0-3522-4008-8D1E-47EF8E4C7AC7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeterDriver", "App/EmuMeterDriver/EmuMeterDriver.csproj", "{F65F33B0-3522-4008-8D1E-47EF8E4C7AC7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BmsTunnel", "App\BmsTunnel\BmsTunnel.csproj", "{40B45363-BE34-420B-8F87-775EE6EE3513}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BmsTunnel", "App/BmsTunnel/BmsTunnel.csproj", "{40B45363-BE34-420B-8F87-775EE6EE3513}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "App", "App", "{145597B4-3E30-45E6-9F72-4DD43194539A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaliMax", "App\SaliMax\SaliMax.csproj", "{25073794-D859-4824-9984-194C7E928496}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaliMax", "App/SaliMax/SaliMax.csproj", "{25073794-D859-4824-9984-194C7E928496}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "Lib\StatusApi\StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "Lib/StatusApi/StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{4931A385-24DC-4E78-BFF4-356F8D6D5183}" EndProject @@ -31,35 +30,35 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Victron", "Victron", "{BD8C EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Trumpf", "Trumpf", "{DDDBEFD0-5DEA-4C7C-A9F2-FDB4636CF092}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertAc", "Lib\Devices\Trumpf\TruConvertAc\TruConvertAc.csproj", "{1F4B445E-459E-44CD-813E-6D725EBB81E8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertAc", "Lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj", "{1F4B445E-459E-44CD-813E-6D725EBB81E8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertDc", "Lib\Devices\Trumpf\TruConvertDc\TruConvertDc.csproj", "{F6F29829-C31A-4994-A698-E441BEA631C6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertDc", "Lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj", "{F6F29829-C31A-4994-A698-E441BEA631C6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBus", "Lib\Protocols\DBus\DBus.csproj", "{8C3C620A-087D-4DD6-B493-A47FC643F8DC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBus", "Lib/Protocols/DBus/DBus.csproj", "{8C3C620A-087D-4DD6-B493-A47FC643F8DC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus", "Lib\Protocols\Modbus\Modbus.csproj", "{E4AE6A33-0DEB-48EB-9D57-C0C7C63FC267}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus", "Lib/Protocols/Modbus/Modbus.csproj", "{E4AE6A33-0DEB-48EB-9D57-C0C7C63FC267}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeDBus", "Lib\Victron\VeDBus\VeDBus.csproj", "{50B26E29-1B99-4D07-BCA5-359CD550BBAA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeDBus", "Lib/Victron/VeDBus/VeDBus.csproj", "{50B26E29-1B99-4D07-BCA5-359CD550BBAA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VictronVRM", "Lib\Victron\VictronVRM\VictronVRM.csproj", "{FE05DF69-B5C7-4C2E-8FB9-7776441A7622}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VictronVRM", "Lib/Victron/VictronVRM/VictronVRM.csproj", "{FE05DF69-B5C7-4C2E-8FB9-7776441A7622}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ampt", "Lib\Devices\AMPT\Ampt.csproj", "{77AF3A64-2878-4150-BCD0-F16530783165}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ampt", "Lib/Devices/AMPT/Ampt.csproj", "{77AF3A64-2878-4150-BCD0-F16530783165}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Battery48TL", "Lib\Devices\Battery48TL\Battery48TL.csproj", "{1C3F443A-B339-4B08-80E6-8A84817FFEC9}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Battery48TL", "Lib/Devices/Battery48TL/Battery48TL.csproj", "{1C3F443A-B339-4B08-80E6-8A84817FFEC9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeter", "Lib\Devices\EmuMeter\EmuMeter.csproj", "{152A4168-F612-493C-BBEA-8EB26E6E2D34}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeter", "Lib/Devices/EmuMeter/EmuMeter.csproj", "{152A4168-F612-493C-BBEA-8EB26E6E2D34}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Lib\Utils\Utils.csproj", "{89A3E29C-4E57-47FE-A800-12AC68418264}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Lib/Utils/Utils.csproj", "{89A3E29C-4E57-47FE-A800-12AC68418264}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adam6060", "Lib\Devices\Adam6060\Adam6060.csproj", "{4AFDB799-E6A4-4DCA-8B6D-8C0F98398461}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adam6060", "Lib/Devices/Adam6060/Adam6060.csproj", "{4AFDB799-E6A4-4DCA-8B6D-8C0F98398461}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Channels", "Lib\Channels\Channels.csproj", "{AF7E8DCA-8D48-498E-AB3D-208061B244DC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Channels", "Lib/Channels/Channels.csproj", "{AF7E8DCA-8D48-498E-AB3D-208061B244DC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backend", "App\Backend\Backend.csproj", "{A56F58C2-B265-435B-A985-53B4D6F49B1A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backend", "App/Backend/Backend.csproj", "{A56F58C2-B265-435B-A985-53B4D6F49B1A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Units", "Lib\Units\Units.csproj", "{C04FB6DA-23C6-46BB-9B21-8F4FBA32FFF7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Units", "Lib/Units/Units.csproj", "{C04FB6DA-23C6-46BB-9B21-8F4FBA32FFF7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SystemControl", "Lib\Devices\Trumpf\SystemControl\SystemControl.csproj", "{B816BB44-E97E-4E02-B80A-BEDB5B923A96}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SystemControl", "Lib/Devices/Trumpf/SystemControl/SystemControl.csproj", "{B816BB44-E97E-4E02-B80A-BEDB5B923A96}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{AED84693-C389-44C9-B2C0-ACB560189CF2}" ProjectSection(SolutionItems) = preProject @@ -88,6 +87,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Doepke", "Lib\Devices\Doepk EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amax5070", "Lib\Devices\Amax5070\Amax5070.csproj", "{09E280B0-43D3-47BD-AF15-CF4FCDD24FE6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SofarInverter", "Lib\Devices\SofarInverter\SofarInverter.csproj", "{2C7F3D89-402B-43CB-988E-8D2D853BEF44}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SchneiderMeterDriver", "App\SchneiderMeterDriver\SchneiderMeterDriver.csproj", "{2E7E7657-3A53-4B62-8927-FE9A082B81DE}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Battery250UP", "Lib\Devices\Battery250UP\Battery250UP.csproj", "{F2967439-A590-4D5E-9208-1B973C83AA1C}" @@ -108,6 +109,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SinexcelCommunication", "Ap EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sinexcel 12K TL", "Sinexcel 12K TL\Sinexcel 12K TL.csproj", "{28C16B43-E498-40DB-8ACF-D7F2A88A402F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kaco92L3", "Lib\Devices\Kaco92L3\Kaco92L3.csproj", "{E60412AA-F88C-4CB7-AEFC-78427B1ADA13}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KacoCommunication", "App\KacoCommunication\KacoCommunication.csproj", "{0380E4B0-2A0C-4E3B-8536-499B72B23179}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PLVario2Meter", "Lib\Devices\PLVario2Meter\PLVario2Meter.csproj", "{D6D07FC5-2925-4B13-9F65-22123E07F8CC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPIORaspberryPI4", "Lib\Devices\GPIORaspberryPI4\GPIORaspberryPI4.csproj", "{5E7A867E-D026-43B4-BDB9-240E4331CA23}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GpioTestingProject", "App\GpioTestingProject\GpioTestingProject.csproj", "{C6E3B901-3730-4B04-B821-85A6673C3D25}" +EndProject + Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -246,6 +258,10 @@ Global {09E280B0-43D3-47BD-AF15-CF4FCDD24FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {09E280B0-43D3-47BD-AF15-CF4FCDD24FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {09E280B0-43D3-47BD-AF15-CF4FCDD24FE6}.Release|Any CPU.Build.0 = Release|Any CPU + {2C7F3D89-402B-43CB-988E-8D2D853BEF44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C7F3D89-402B-43CB-988E-8D2D853BEF44}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C7F3D89-402B-43CB-988E-8D2D853BEF44}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C7F3D89-402B-43CB-988E-8D2D853BEF44}.Release|Any CPU.Build.0 = Release|Any CPU {2E7E7657-3A53-4B62-8927-FE9A082B81DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E7E7657-3A53-4B62-8927-FE9A082B81DE}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E7E7657-3A53-4B62-8927-FE9A082B81DE}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -286,6 +302,26 @@ Global {28C16B43-E498-40DB-8ACF-D7F2A88A402F}.Debug|Any CPU.Build.0 = Debug|Any CPU {28C16B43-E498-40DB-8ACF-D7F2A88A402F}.Release|Any CPU.ActiveCfg = Release|Any CPU {28C16B43-E498-40DB-8ACF-D7F2A88A402F}.Release|Any CPU.Build.0 = Release|Any CPU + {E60412AA-F88C-4CB7-AEFC-78427B1ADA13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E60412AA-F88C-4CB7-AEFC-78427B1ADA13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E60412AA-F88C-4CB7-AEFC-78427B1ADA13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E60412AA-F88C-4CB7-AEFC-78427B1ADA13}.Release|Any CPU.Build.0 = Release|Any CPU + {0380E4B0-2A0C-4E3B-8536-499B72B23179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0380E4B0-2A0C-4E3B-8536-499B72B23179}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0380E4B0-2A0C-4E3B-8536-499B72B23179}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0380E4B0-2A0C-4E3B-8536-499B72B23179}.Release|Any CPU.Build.0 = Release|Any CPU + {D6D07FC5-2925-4B13-9F65-22123E07F8CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6D07FC5-2925-4B13-9F65-22123E07F8CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6D07FC5-2925-4B13-9F65-22123E07F8CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6D07FC5-2925-4B13-9F65-22123E07F8CC}.Release|Any CPU.Build.0 = Release|Any CPU + {5E7A867E-D026-43B4-BDB9-240E4331CA23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5E7A867E-D026-43B4-BDB9-240E4331CA23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5E7A867E-D026-43B4-BDB9-240E4331CA23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5E7A867E-D026-43B4-BDB9-240E4331CA23}.Release|Any CPU.Build.0 = Release|Any CPU + {C6E3B901-3730-4B04-B821-85A6673C3D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6E3B901-3730-4B04-B821-85A6673C3D25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6E3B901-3730-4B04-B821-85A6673C3D25}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6E3B901-3730-4B04-B821-85A6673C3D25}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {CF4834CB-91B7-4172-AC13-ECDA8613CD17} = {145597B4-3E30-45E6-9F72-4DD43194539A} @@ -325,6 +361,7 @@ Global {73B97F6E-2BDC-40DA-84A7-7FB0264387D6} = {AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854} {C2B14CD4-1BCA-4933-96D9-92F40EACD2B9} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} {09E280B0-43D3-47BD-AF15-CF4FCDD24FE6} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} + {2C7F3D89-402B-43CB-988E-8D2D853BEF44} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} {2E7E7657-3A53-4B62-8927-FE9A082B81DE} = {145597B4-3E30-45E6-9F72-4DD43194539A} {F2967439-A590-4D5E-9208-1B973C83AA1C} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} {1045AC74-D4D8-4581-AAE3-575DF26060E6} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} @@ -335,5 +372,10 @@ Global {6069D487-DBAB-4253-BFA1-CF994B84BE49} = {145597B4-3E30-45E6-9F72-4DD43194539A} {93084D79-2977-47A1-9CAC-3E2DC6423F5B} = {145597B4-3E30-45E6-9F72-4DD43194539A} {28C16B43-E498-40DB-8ACF-D7F2A88A402F} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} + {E60412AA-F88C-4CB7-AEFC-78427B1ADA13} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} + {0380E4B0-2A0C-4E3B-8536-499B72B23179} = {145597B4-3E30-45E6-9F72-4DD43194539A} + {D6D07FC5-2925-4B13-9F65-22123E07F8CC} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} + {5E7A867E-D026-43B4-BDB9-240E4331CA23} = {4931A385-24DC-4E78-BFF4-356F8D6D5183} + {C6E3B901-3730-4B04-B821-85A6673C3D25} = {145597B4-3E30-45E6-9F72-4DD43194539A} EndGlobalSection EndGlobal diff --git a/csharp/Lib/Devices/GPIORaspberryPI4/DigitalInput.cs b/csharp/Lib/Devices/GPIORaspberryPI4/DigitalInput.cs new file mode 100644 index 000000000..26301fadd --- /dev/null +++ b/csharp/Lib/Devices/GPIORaspberryPI4/DigitalInput.cs @@ -0,0 +1,57 @@ +using System; +using System.Device.Gpio; + +namespace GPIORaspberryPI4; + +public sealed class DigitalInput : IDigitalInput +{ + private readonly GpioController _gpio; + private readonly int _pin; + private readonly bool _activeLow; + private bool _disposed; + + public int Pin => _pin; + + public bool IsActive => Read(); + + public DigitalInput(int pin, bool pullUp = true, bool activeLow = true) + { + _pin = pin; + _activeLow = activeLow; + + _gpio = new GpioController(); + + var mode = pullUp ? PinMode.InputPullUp : PinMode.Input; + + _gpio.OpenPin(_pin, mode); + } + + public bool Read() + { + ThrowIfDisposed(); + + var value = _gpio.Read(_pin); + + return _activeLow + ? value == PinValue.Low + : value == PinValue.High; + } + + private void ThrowIfDisposed() + { + if (_disposed) + throw new ObjectDisposedException(nameof(DigitalInput)); + } + + public void Dispose() + { + if (_disposed) + return; + + if (_gpio.IsPinOpen(_pin)) + _gpio.ClosePin(_pin); + + _gpio.Dispose(); + _disposed = true; + } +} \ No newline at end of file diff --git a/csharp/Lib/Devices/GPIORaspberryPI4/GPIORaspberryPI4.csproj b/csharp/Lib/Devices/GPIORaspberryPI4/GPIORaspberryPI4.csproj new file mode 100644 index 000000000..9b12551de --- /dev/null +++ b/csharp/Lib/Devices/GPIORaspberryPI4/GPIORaspberryPI4.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/csharp/Lib/Devices/GPIORaspberryPI4/IDigitalInput.cs b/csharp/Lib/Devices/GPIORaspberryPI4/IDigitalInput.cs new file mode 100644 index 000000000..5102bfae2 --- /dev/null +++ b/csharp/Lib/Devices/GPIORaspberryPI4/IDigitalInput.cs @@ -0,0 +1,8 @@ +namespace GPIORaspberryPI4; + +public interface IDigitalInput : IDisposable +{ + int Pin { get; } + bool IsActive { get; } + bool Read(); +} \ No newline at end of file diff --git a/csharp/Lib/Devices/GPIORaspberryPI4/IRelayOutput.cs b/csharp/Lib/Devices/GPIORaspberryPI4/IRelayOutput.cs new file mode 100644 index 000000000..351919cda --- /dev/null +++ b/csharp/Lib/Devices/GPIORaspberryPI4/IRelayOutput.cs @@ -0,0 +1,9 @@ +namespace GPIORaspberryPI4; + +public interface IRelayOutput : IDisposable +{ + void On(); + void Off(); + void Set(bool on); + bool IsOn { get; } +} \ No newline at end of file diff --git a/csharp/Lib/Devices/GPIORaspberryPI4/RelayOutput.cs b/csharp/Lib/Devices/GPIORaspberryPI4/RelayOutput.cs new file mode 100644 index 000000000..e0c1e2b65 --- /dev/null +++ b/csharp/Lib/Devices/GPIORaspberryPI4/RelayOutput.cs @@ -0,0 +1,81 @@ +using System.Device.Gpio; + +namespace GPIORaspberryPI4; + +public sealed class RelayOutput : IRelayOutput +{ + private readonly GpioController _gpio; + private readonly int _pin; + private readonly bool _activeLow; + private bool _disposed; + + public bool IsOn { get; private set; } + + public RelayOutput(int pin, bool activeLow = false) + { + _pin = pin; + _activeLow = activeLow; + + _gpio = new GpioController(); + _gpio.OpenPin(_pin, PinMode.Output); + + // Safe default state + WriteInternal(false); + } + + public void On() + { + ThrowIfDisposed(); + WriteInternal(true); + } + + public void Off() + { + ThrowIfDisposed(); + WriteInternal(false); + } + + public void Set(bool on) + { + ThrowIfDisposed(); + WriteInternal(on); + } + + private void WriteInternal(bool on) + { + var pinValue = _activeLow + ? (on ? PinValue.Low : PinValue.High) + : (on ? PinValue.High : PinValue.Low); + + _gpio.Write(_pin, pinValue); + IsOn = on; + } + + private void ThrowIfDisposed() + { + if (_disposed) + throw new ObjectDisposedException(nameof(RelayOutput)); + } + + public void Dispose() + { + if (_disposed) + return; + + try + { + // Fail-safe: relay OFF on dispose + WriteInternal(false); + } + catch + { + // Ignore cleanup errors + } + + if (_gpio.IsPinOpen(_pin)) + _gpio.ClosePin(_pin); + + _gpio.Dispose(); + _disposed = true; + } +} \ No newline at end of file