first commit

This commit is contained in:
motahhari
2025-10-31 20:21:22 +03:30
commit 60d20a2734
186 changed files with 15497 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "9.0.10",
"commands": [
"dotnet-ef"
],
"rollForward": false
}
}
}

View File

@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Mvc;
using GreenHome.Application;
namespace GreenHome.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class DeviceSettingsController : ControllerBase
{
private readonly IDeviceSettingsService deviceSettingsService;
public DeviceSettingsController(IDeviceSettingsService deviceSettingsService)
{
this.deviceSettingsService = deviceSettingsService;
}
[HttpGet("{deviceId}")]
public async Task<ActionResult<DeviceSettingsDto>> GetByDeviceId(int deviceId, CancellationToken cancellationToken)
{
var result = await deviceSettingsService.GetByDeviceIdAsync(deviceId, cancellationToken);
if (result == null)
{
return NotFound();
}
return Ok(result);
}
[HttpPost]
public async Task<ActionResult<int>> Create(DeviceSettingsDto dto, CancellationToken cancellationToken)
{
var id = await deviceSettingsService.CreateAsync(dto, cancellationToken);
return Ok(id);
}
[HttpPut]
public async Task<ActionResult> Update(DeviceSettingsDto dto, CancellationToken cancellationToken)
{
await deviceSettingsService.UpdateAsync(dto, cancellationToken);
return Ok();
}
}

View File

@@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Mvc;
using GreenHome.Application;
namespace GreenHome.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class DevicesController : ControllerBase
{
private readonly IDeviceService deviceService;
public DevicesController(IDeviceService deviceService)
{
this.deviceService = deviceService;
}
[HttpGet]
public async Task<ActionResult<IReadOnlyList<DeviceDto>>> GetAll(CancellationToken cancellationToken)
{
var result = await deviceService.ListAsync(cancellationToken);
return Ok(result);
}
[HttpGet("CheckDevice")]
public async Task<ActionResult<IReadOnlyList<DeviceDto>>> CheckDevice(string deviceName,CancellationToken cancellationToken)
{
var result = await deviceService.GetDeviceId(deviceName,cancellationToken);
return Ok(result);
}
[HttpPost]
public async Task<ActionResult<int>> Create(DeviceDto dto, CancellationToken cancellationToken)
{
var id = await deviceService.AddDeviceAsync(dto, cancellationToken);
return Ok(id);
}
}

View File

@@ -0,0 +1,63 @@
using Microsoft.AspNetCore.Mvc;
using GreenHome.Application;
namespace GreenHome.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class TelemetryController : ControllerBase
{
private readonly ITelemetryService telemetryService;
public TelemetryController(ITelemetryService telemetryService)
{
this.telemetryService = telemetryService;
}
[HttpGet]
public async Task<ActionResult<PagedResult<TelemetryDto>>> List([FromQuery] int? deviceId, [FromQuery] DateTime? startUtc, [FromQuery] DateTime? endUtc, [FromQuery] int page = 1, [FromQuery] int pageSize = 20, CancellationToken cancellationToken = default)
{
var filter = new TelemetryFilter { DeviceId = deviceId, StartDateUtc = startUtc, EndDateUtc = endUtc, Page = page, PageSize = pageSize };
var result = await telemetryService.ListAsync(filter, cancellationToken);
return Ok(result);
}
[HttpGet("AddData")]
public async Task<ActionResult<int>> Create(string deviceName, decimal temperatureC, decimal humidityPercent,
decimal soilPercent, int gasPPM, decimal lux, CancellationToken cancellationToken)
{
TelemetryDto dto = new TelemetryDto
{
DeviceName = deviceName,
TemperatureC = temperatureC,
HumidityPercent = humidityPercent,
SoilPercent = soilPercent,
GasPPM = gasPPM,
Lux = lux,
TimestampUtc = DateTime.UtcNow
};
var id = await telemetryService.AddAsync(dto, cancellationToken);
return Ok(id);
}
[HttpGet("minmax")]
public async Task<ActionResult<TelemetryMinMax>> MinMax([FromQuery] int deviceId, [FromQuery] DateTime? startUtc, [FromQuery] DateTime? endUtc, CancellationToken cancellationToken)
{
var result = await telemetryService.GetMinMaxAsync(deviceId, startUtc, endUtc, cancellationToken);
return Ok(result);
}
[HttpGet("days")]
public async Task<ActionResult<IReadOnlyList<DayCount>>> Days([FromQuery] int deviceId, [FromQuery] int year, [FromQuery] int month, CancellationToken cancellationToken)
{
var result = await telemetryService.GetMonthDaysAsync(deviceId, year, month, cancellationToken);
return Ok(result);
}
[HttpGet("months")]
public async Task<ActionResult<IReadOnlyList<int>>> Months([FromQuery] int deviceId, [FromQuery] int year, CancellationToken cancellationToken)
{
var result = await telemetryService.GetActiveMonthsAsync(deviceId, year, cancellationToken);
return Ok(result);
}
}

View File

@@ -0,0 +1,13 @@
# مرحله build
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app
# مرحله runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app .
EXPOSE 8080
ENTRYPOINT ["dotnet", "GreenHome.Api.dll"]

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.9" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GreenHome.Application\GreenHome.Application.csproj" />
<ProjectReference Include="..\GreenHome.Infrastructure\GreenHome.Infrastructure.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>IIS Express</ActiveDebugProfile>
<NameOfLastUsedPublishProfile>D:\Data\Projects\php\greenhome\src\GreenHome.Api\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,6 @@
@GreenHome.Api_HostAddress = http://localhost:5064
GET {{GreenHome.Api_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@@ -0,0 +1,63 @@
using FluentValidation;
using GreenHome.Application;
using GreenHome.Infrastructure;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Application/Infrastructure DI
builder.Services.AddAutoMapper(typeof(GreenHome.Application.MappingProfile));
builder.Services.AddValidatorsFromAssemblyContaining<GreenHome.Application.DeviceDtoValidator>();
// CORS for Next.js dev (adjust origins as needed)
const string CorsPolicy = "DefaultCors";
builder.Services.AddCors(options =>
{
options.AddPolicy(CorsPolicy, policy =>
policy
.WithOrigins(
"http://green.nabaksoft.ir",
"https://green.nabaksoft.ir",
"http://gh1.nabaksoft.ir",
"https://gh1.nabaksoft.ir",
"http://localhost:3000",
"http://localhost:3000",
"http://127.0.0.1:3000",
"https://localhost:3000"
)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
});
builder.Services.AddDbContext<GreenHome.Infrastructure.GreenHomeDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("Default"));
});
builder.Services.AddScoped<GreenHome.Application.IDeviceService, GreenHome.Infrastructure.DeviceService>();
builder.Services.AddScoped<GreenHome.Application.ITelemetryService, GreenHome.Infrastructure.TelemetryService>();
builder.Services.AddScoped<GreenHome.Application.IDeviceSettingsService, GreenHome.Infrastructure.DeviceSettingsService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors(CorsPolicy);
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<DeleteExistingFiles>true</DeleteExistingFiles>
<ExcludeApp_Data>false</ExcludeApp_Data>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>D:\Data\Projects\php\greenhome\src\GreenHome.Api\bin\publish</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
<_TargetId>Folder</_TargetId>
<SiteUrlToLaunchAfterPublish />
<TargetFramework>net9.0</TargetFramework>
<ProjectGuid>75e498d4-5d04-4f63-a1a5-5d851fa40c74</ProjectGuid>
<SelfContained>false</SelfContained>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<TimeStampOfAssociatedLegacyPublishXmlFile />
<_PublishTargetUrl>D:\Data\Projects\php\greenhome\src\GreenHome.Api\bin\publish</_PublishTargetUrl>
<History>True|2025-10-27T10:50:38.6931407Z||;</History>
<LastFailureDetails />
</PropertyGroup>
<ItemGroup>
<DestinationConnectionStrings Include="Default">
<Value>Server=.%3bDatabase=GreenHomeDb%3bUser Id=sa%3bPassword=qwER12#%24110%3bTrusted_Connection=True%3bMultipleActiveResultSets=true%3bTrustServerCertificate=True</Value>
</DestinationConnectionStrings>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,36 @@
{
"profiles": {
"http": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5064"
},
"https": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7274;http://localhost:5064"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
},
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:62250/",
"sslPort": 44315
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"Default": "Server=.;Database=GreenHomeDb;User Id=sa;Password=qwER12#$110;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True"
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,39 @@
services:
build:
image: mcr.microsoft.com/dotnet/sdk:6.0
volumes:
- .:/app
working_dir: /app
command: "dotnet publish -c Release -o /app/publish"
networks:
- serviceNetwork
web:
image: mcr.microsoft.com/dotnet/aspnet:6.0
depends_on:
- build
# ports:
# - "5000:80"
environment:
- ASPNETCORE_ENVIRONMENT=Development
volumes:
- .:/app
working_dir: /app/publish
command: ["dotnet", "GreenHome.Api.dll"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`gh.nabaksoft.ir`)"
- "traefik.http.services.web.loadbalancer.server.port=80"
- "traefik.http.middlewares.cors-headers.headers.accesscontrolalloworiginlist=https://green.nabaksoft.ir"
- "traefik.http.middlewares.cors-headers.headers.accesscontrolalloworiginlist=http://green.nabaksoft.ir"
- "traefik.http.middlewares.cors-headers.headers.accesscontrolallowmethods=GET,POST,PUT,DELETE,OPTIONS"
- "traefik.http.middlewares.cors-headers.headers.accesscontrolallowheaders=Content-Type,Authorization"
- "traefik.http.middlewares.cors-headers.headers.accesscontrolallowcredentials=true"
- "traefik.http.routers.greenhome-api.middlewares=cors-headers@docker"
networks:
- greenNetwork
networks:
serviceNetwork:
name: greenNetwork
external: true

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")]

View File

@@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("GreenHome.Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("GreenHome.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("GreenHome.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.

View File

@@ -0,0 +1 @@
c307d33a16c6447b758cae28ca2fa40d39ada8eff9f6b0aa1055040d6099f1b2

View File

@@ -0,0 +1,21 @@
is_global = true
build_property.TargetFramework = net9.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb = true
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = GreenHome.Api
build_property.RootNamespace = GreenHome.Api
build_property.ProjectDir = D:\Data\Projects\php\greenhome\src\GreenHome.Api\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.RazorLangVersion = 9.0
build_property.SupportLocalizedComponentNames =
build_property.GenerateRazorMetadataSourceChecksumAttributes =
build_property.MSBuildProjectDirectory = D:\Data\Projects\php\greenhome\src\GreenHome.Api
build_property._RazorSourceGeneratorDebug =
build_property.EffectiveAnalysisLevelStyle = 9.0
build_property.EnableCodeStyleSeverity =

View File

@@ -0,0 +1,17 @@
// <auto-generated/>
global using global::Microsoft.AspNetCore.Builder;
global using global::Microsoft.AspNetCore.Hosting;
global using global::Microsoft.AspNetCore.Http;
global using global::Microsoft.AspNetCore.Routing;
global using global::Microsoft.Extensions.Configuration;
global using global::Microsoft.Extensions.DependencyInjection;
global using global::Microsoft.Extensions.Hosting;
global using global::Microsoft.Extensions.Logging;
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Net.Http.Json;
global using global::System.Threading;
global using global::System.Threading.Tasks;